diff options
Diffstat (limited to 'drivers/net/ethernet/sun/niu.c')
| -rw-r--r-- | drivers/net/ethernet/sun/niu.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 72177fea1cfb..88df15e6dd74 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -2225,7 +2225,7 @@ static int niu_link_status(struct niu *np, int *link_up_p) static void niu_timer(struct timer_list *t) { - struct niu *np = from_timer(np, t, timer); + struct niu *np = timer_container_of(np, t, timer); unsigned long off; int err, link_up; @@ -3336,7 +3336,7 @@ static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp, addr = np->ops->map_page(np->device, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); - if (!addr) { + if (np->ops->mapping_error(np->device, addr)) { __free_page(page); return -ENOMEM; } @@ -4341,8 +4341,7 @@ static int niu_alloc_rx_ring_info(struct niu *np, { BUILD_BUG_ON(sizeof(struct rxdma_mailbox) != 64); - rp->rxhash = kcalloc(MAX_RBR_RING_SIZE, sizeof(struct page *), - GFP_KERNEL); + rp->rxhash = kzalloc_objs(struct page *, MAX_RBR_RING_SIZE); if (!rp->rxhash) return -ENOMEM; @@ -4485,8 +4484,7 @@ static int niu_alloc_channels(struct niu *np) num_rx_rings = parent->rxchan_per_port[port]; num_tx_rings = parent->txchan_per_port[port]; - rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), - GFP_KERNEL); + rx_rings = kzalloc_objs(struct rx_ring_info, num_rx_rings); err = -ENOMEM; if (!rx_rings) goto out_err; @@ -4525,8 +4523,7 @@ static int niu_alloc_channels(struct niu *np) goto out_err; } - tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), - GFP_KERNEL); + tx_rings = kzalloc_objs(struct tx_ring_info, num_tx_rings); err = -ENOMEM; if (!tx_rings) goto out_err; @@ -5825,7 +5822,7 @@ static int niu_init_mac(struct niu *np) /* This looks hookey but the RX MAC reset we just did will * undo some of the state we setup in niu_init_tx_mac() so we * have to call it again. In particular, the RX MAC reset will - * set the XMAC_MAX register back to it's default value. + * set the XMAC_MAX register back to its default value. */ niu_init_tx_mac(np); niu_enable_tx_mac(np, 1); @@ -6165,7 +6162,7 @@ static void niu_full_shutdown(struct niu *np, struct net_device *dev) niu_disable_napi(np); netif_tx_stop_all_queues(dev); - del_timer_sync(&np->timer); + timer_delete_sync(&np->timer); spin_lock_irq(&np->lock); @@ -6511,7 +6508,7 @@ static void niu_reset_task(struct work_struct *work) spin_unlock_irqrestore(&np->lock, flags); - del_timer_sync(&np->timer); + timer_delete_sync(&np->timer); niu_netif_stop(np); @@ -6676,6 +6673,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, len = skb_headlen(skb); mapping = np->ops->map_single(np->device, skb->data, len, DMA_TO_DEVICE); + if (np->ops->mapping_error(np->device, mapping)) + goto out_drop; prod = rp->prod; @@ -6717,6 +6716,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, mapping = np->ops->map_page(np->device, skb_frag_page(frag), skb_frag_off(frag), len, DMA_TO_DEVICE); + if (np->ops->mapping_error(np->device, mapping)) + goto out_unmap; rp->tx_buffs[prod].skb = NULL; rp->tx_buffs[prod].mapping = mapping; @@ -6741,6 +6742,19 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, out: return NETDEV_TX_OK; +out_unmap: + while (i--) { + const skb_frag_t *frag; + + prod = PREVIOUS_TX(rp, prod); + frag = &skb_shinfo(skb)->frags[i]; + np->ops->unmap_page(np->device, rp->tx_buffs[prod].mapping, + skb_frag_size(frag), DMA_TO_DEVICE); + } + + np->ops->unmap_single(np->device, rp->tx_buffs[rp->prod].mapping, + skb_headlen(skb), DMA_TO_DEVICE); + out_drop: rp->tx_errors++; kfree_skb(skb); @@ -7077,8 +7091,10 @@ static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key) } -static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc) +static int niu_get_rxfh_fields(struct net_device *dev, + struct ethtool_rxfh_fields *nfc) { + struct niu *np = netdev_priv(dev); u64 class; nfc->data = 0; @@ -7283,6 +7299,13 @@ static int niu_get_ethtool_tcam_all(struct niu *np, return ret; } +static u32 niu_get_rx_ring_count(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + return np->num_rx_rings; +} + static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, u32 *rule_locs) { @@ -7290,12 +7313,6 @@ static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, int ret = 0; switch (cmd->cmd) { - case ETHTOOL_GRXFH: - ret = niu_get_hash_opts(np, cmd); - break; - case ETHTOOL_GRXRINGS: - cmd->data = np->num_rx_rings; - break; case ETHTOOL_GRXCLSRLCNT: cmd->rule_cnt = tcam_get_valid_entry_cnt(np); break; @@ -7313,8 +7330,11 @@ static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, return ret; } -static int niu_set_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc) +static int niu_set_rxfh_fields(struct net_device *dev, + const struct ethtool_rxfh_fields *nfc, + struct netlink_ext_ack *extack) { + struct niu *np = netdev_priv(dev); u64 class; u64 flow_key = 0; unsigned long flags; @@ -7656,9 +7676,6 @@ static int niu_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) int ret = 0; switch (cmd->cmd) { - case ETHTOOL_SRXFH: - ret = niu_set_hash_opts(np, cmd); - break; case ETHTOOL_SRXCLSRLINS: ret = niu_add_ethtool_tcam_entry(np, cmd); break; @@ -7912,6 +7929,9 @@ static const struct ethtool_ops niu_ethtool_ops = { .set_phys_id = niu_set_phys_id, .get_rxnfc = niu_get_nfc, .set_rxnfc = niu_set_nfc, + .get_rx_ring_count = niu_get_rx_ring_count, + .get_rxfh_fields = niu_get_rxfh_fields, + .set_rxfh_fields = niu_set_rxfh_fields, .get_link_ksettings = niu_get_link_ksettings, .set_link_ksettings = niu_set_link_ksettings, }; @@ -9064,6 +9084,8 @@ static void niu_try_msix(struct niu *np, u8 *ldg_num_map) msi_vec[i].entry = i; } + pdev->dev_flags |= PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST; + num_irqs = pci_enable_msix_range(pdev, msi_vec, 1, num_irqs); if (num_irqs < 0) { np->flags &= ~NIU_FLAGS_MSIX; @@ -9489,7 +9511,7 @@ static struct niu_parent *niu_new_parent(struct niu *np, goto fail_unregister; } - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) goto fail_unregister; @@ -9642,6 +9664,11 @@ static void niu_pci_unmap_single(struct device *dev, u64 dma_address, dma_unmap_single(dev, dma_address, size, direction); } +static int niu_pci_mapping_error(struct device *dev, u64 addr) +{ + return dma_mapping_error(dev, addr); +} + static const struct niu_ops niu_pci_ops = { .alloc_coherent = niu_pci_alloc_coherent, .free_coherent = niu_pci_free_coherent, @@ -9649,6 +9676,7 @@ static const struct niu_ops niu_pci_ops = { .unmap_page = niu_pci_unmap_page, .map_single = niu_pci_map_single, .unmap_single = niu_pci_unmap_single, + .mapping_error = niu_pci_mapping_error, }; static void niu_driver_version(void) @@ -9914,7 +9942,7 @@ static int __maybe_unused niu_suspend(struct device *dev_d) flush_work(&np->reset_task); niu_netif_stop(np); - del_timer_sync(&np->timer); + timer_delete_sync(&np->timer); spin_lock_irqsave(&np->lock, flags); niu_enable_interrupts(np, 0); @@ -10017,6 +10045,11 @@ static void niu_phys_unmap_single(struct device *dev, u64 dma_address, /* Nothing to do. */ } +static int niu_phys_mapping_error(struct device *dev, u64 dma_address) +{ + return false; +} + static const struct niu_ops niu_phys_ops = { .alloc_coherent = niu_phys_alloc_coherent, .free_coherent = niu_phys_free_coherent, @@ -10024,6 +10057,7 @@ static const struct niu_ops niu_phys_ops = { .unmap_page = niu_phys_unmap_page, .map_single = niu_phys_map_single, .unmap_single = niu_phys_unmap_single, + .mapping_error = niu_phys_mapping_error, }; static int niu_of_probe(struct platform_device *op) |
