diff options
Diffstat (limited to 'drivers/net/cxgb4/cxgb4_main.c')
-rw-r--r-- | drivers/net/cxgb4/cxgb4_main.c | 102 |
1 files changed, 63 insertions, 39 deletions
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index a7e30a23d32..58045b00cf4 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c | |||
@@ -240,9 +240,9 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
240 | u16 filt_idx[7]; | 240 | u16 filt_idx[7]; |
241 | const u8 *addr[7]; | 241 | const u8 *addr[7]; |
242 | int ret, naddr = 0; | 242 | int ret, naddr = 0; |
243 | const struct dev_addr_list *d; | ||
244 | const struct netdev_hw_addr *ha; | 243 | const struct netdev_hw_addr *ha; |
245 | int uc_cnt = netdev_uc_count(dev); | 244 | int uc_cnt = netdev_uc_count(dev); |
245 | int mc_cnt = netdev_mc_count(dev); | ||
246 | const struct port_info *pi = netdev_priv(dev); | 246 | const struct port_info *pi = netdev_priv(dev); |
247 | 247 | ||
248 | /* first do the secondary unicast addresses */ | 248 | /* first do the secondary unicast addresses */ |
@@ -260,9 +260,9 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | /* next set up the multicast addresses */ | 262 | /* next set up the multicast addresses */ |
263 | netdev_for_each_mc_addr(d, dev) { | 263 | netdev_for_each_mc_addr(ha, dev) { |
264 | addr[naddr++] = d->dmi_addr; | 264 | addr[naddr++] = ha->addr; |
265 | if (naddr >= ARRAY_SIZE(addr) || d->next == NULL) { | 265 | if (--mc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { |
266 | ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, | 266 | ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, |
267 | naddr, addr, filt_idx, &mhash, sleep); | 267 | naddr, addr, filt_idx, &mhash, sleep); |
268 | if (ret < 0) | 268 | if (ret < 0) |
@@ -290,7 +290,7 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) | |||
290 | if (ret == 0) | 290 | if (ret == 0) |
291 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu, | 291 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu, |
292 | (dev->flags & IFF_PROMISC) ? 1 : 0, | 292 | (dev->flags & IFF_PROMISC) ? 1 : 0, |
293 | (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, | 293 | (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, -1, |
294 | sleep_ok); | 294 | sleep_ok); |
295 | return ret; | 295 | return ret; |
296 | } | 296 | } |
@@ -311,11 +311,11 @@ static int link_start(struct net_device *dev) | |||
311 | * that step explicitly. | 311 | * that step explicitly. |
312 | */ | 312 | */ |
313 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1, | 313 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1, |
314 | true); | 314 | pi->vlan_grp != NULL, true); |
315 | if (ret == 0) { | 315 | if (ret == 0) { |
316 | ret = t4_change_mac(pi->adapter, 0, pi->viid, | 316 | ret = t4_change_mac(pi->adapter, 0, pi->viid, |
317 | pi->xact_addr_filt, dev->dev_addr, true, | 317 | pi->xact_addr_filt, dev->dev_addr, true, |
318 | false); | 318 | true); |
319 | if (ret >= 0) { | 319 | if (ret >= 0) { |
320 | pi->xact_addr_filt = ret; | 320 | pi->xact_addr_filt = ret; |
321 | ret = 0; | 321 | ret = 0; |
@@ -859,6 +859,8 @@ static char stats_strings[][ETH_GSTRING_LEN] = { | |||
859 | "RxCsumGood ", | 859 | "RxCsumGood ", |
860 | "VLANextractions ", | 860 | "VLANextractions ", |
861 | "VLANinsertions ", | 861 | "VLANinsertions ", |
862 | "GROpackets ", | ||
863 | "GROmerged ", | ||
862 | }; | 864 | }; |
863 | 865 | ||
864 | static int get_sset_count(struct net_device *dev, int sset) | 866 | static int get_sset_count(struct net_device *dev, int sset) |
@@ -922,6 +924,8 @@ struct queue_port_stats { | |||
922 | u64 rx_csum; | 924 | u64 rx_csum; |
923 | u64 vlan_ex; | 925 | u64 vlan_ex; |
924 | u64 vlan_ins; | 926 | u64 vlan_ins; |
927 | u64 gro_pkts; | ||
928 | u64 gro_merged; | ||
925 | }; | 929 | }; |
926 | 930 | ||
927 | static void collect_sge_port_stats(const struct adapter *adap, | 931 | static void collect_sge_port_stats(const struct adapter *adap, |
@@ -938,6 +942,8 @@ static void collect_sge_port_stats(const struct adapter *adap, | |||
938 | s->rx_csum += rx->stats.rx_cso; | 942 | s->rx_csum += rx->stats.rx_cso; |
939 | s->vlan_ex += rx->stats.vlan_ex; | 943 | s->vlan_ex += rx->stats.vlan_ex; |
940 | s->vlan_ins += tx->vlan_ins; | 944 | s->vlan_ins += tx->vlan_ins; |
945 | s->gro_pkts += rx->stats.lro_pkts; | ||
946 | s->gro_merged += rx->stats.lro_merged; | ||
941 | } | 947 | } |
942 | } | 948 | } |
943 | 949 | ||
@@ -1711,6 +1717,18 @@ static int set_tso(struct net_device *dev, u32 value) | |||
1711 | return 0; | 1717 | return 0; |
1712 | } | 1718 | } |
1713 | 1719 | ||
1720 | static int set_flags(struct net_device *dev, u32 flags) | ||
1721 | { | ||
1722 | if (flags & ~ETH_FLAG_RXHASH) | ||
1723 | return -EOPNOTSUPP; | ||
1724 | |||
1725 | if (flags & ETH_FLAG_RXHASH) | ||
1726 | dev->features |= NETIF_F_RXHASH; | ||
1727 | else | ||
1728 | dev->features &= ~NETIF_F_RXHASH; | ||
1729 | return 0; | ||
1730 | } | ||
1731 | |||
1714 | static struct ethtool_ops cxgb_ethtool_ops = { | 1732 | static struct ethtool_ops cxgb_ethtool_ops = { |
1715 | .get_settings = get_settings, | 1733 | .get_settings = get_settings, |
1716 | .set_settings = set_settings, | 1734 | .set_settings = set_settings, |
@@ -1741,6 +1759,7 @@ static struct ethtool_ops cxgb_ethtool_ops = { | |||
1741 | .get_wol = get_wol, | 1759 | .get_wol = get_wol, |
1742 | .set_wol = set_wol, | 1760 | .set_wol = set_wol, |
1743 | .set_tso = set_tso, | 1761 | .set_tso = set_tso, |
1762 | .set_flags = set_flags, | ||
1744 | .flash_device = set_flash, | 1763 | .flash_device = set_flash, |
1745 | }; | 1764 | }; |
1746 | 1765 | ||
@@ -2308,6 +2327,9 @@ static void uld_attach(struct adapter *adap, unsigned int uld) | |||
2308 | register_netevent_notifier(&cxgb4_netevent_nb); | 2327 | register_netevent_notifier(&cxgb4_netevent_nb); |
2309 | netevent_registered = true; | 2328 | netevent_registered = true; |
2310 | } | 2329 | } |
2330 | |||
2331 | if (adap->flags & FULL_INIT_DONE) | ||
2332 | ulds[uld].state_change(handle, CXGB4_STATE_UP); | ||
2311 | } | 2333 | } |
2312 | 2334 | ||
2313 | static void attach_ulds(struct adapter *adap) | 2335 | static void attach_ulds(struct adapter *adap) |
@@ -2414,23 +2436,17 @@ EXPORT_SYMBOL(cxgb4_unregister_uld); | |||
2414 | */ | 2436 | */ |
2415 | static int cxgb_up(struct adapter *adap) | 2437 | static int cxgb_up(struct adapter *adap) |
2416 | { | 2438 | { |
2417 | int err = 0; | 2439 | int err; |
2418 | 2440 | ||
2419 | if (!(adap->flags & FULL_INIT_DONE)) { | 2441 | err = setup_sge_queues(adap); |
2420 | err = setup_sge_queues(adap); | 2442 | if (err) |
2421 | if (err) | 2443 | goto out; |
2422 | goto out; | 2444 | err = setup_rss(adap); |
2423 | err = setup_rss(adap); | 2445 | if (err) |
2424 | if (err) { | 2446 | goto freeq; |
2425 | t4_free_sge_resources(adap); | ||
2426 | goto out; | ||
2427 | } | ||
2428 | if (adap->flags & USING_MSIX) | ||
2429 | name_msix_vecs(adap); | ||
2430 | adap->flags |= FULL_INIT_DONE; | ||
2431 | } | ||
2432 | 2447 | ||
2433 | if (adap->flags & USING_MSIX) { | 2448 | if (adap->flags & USING_MSIX) { |
2449 | name_msix_vecs(adap); | ||
2434 | err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0, | 2450 | err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0, |
2435 | adap->msix_info[0].desc, adap); | 2451 | adap->msix_info[0].desc, adap); |
2436 | if (err) | 2452 | if (err) |
@@ -2451,11 +2467,14 @@ static int cxgb_up(struct adapter *adap) | |||
2451 | enable_rx(adap); | 2467 | enable_rx(adap); |
2452 | t4_sge_start(adap); | 2468 | t4_sge_start(adap); |
2453 | t4_intr_enable(adap); | 2469 | t4_intr_enable(adap); |
2470 | adap->flags |= FULL_INIT_DONE; | ||
2454 | notify_ulds(adap, CXGB4_STATE_UP); | 2471 | notify_ulds(adap, CXGB4_STATE_UP); |
2455 | out: | 2472 | out: |
2456 | return err; | 2473 | return err; |
2457 | irq_err: | 2474 | irq_err: |
2458 | dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); | 2475 | dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); |
2476 | freeq: | ||
2477 | t4_free_sge_resources(adap); | ||
2459 | goto out; | 2478 | goto out; |
2460 | } | 2479 | } |
2461 | 2480 | ||
@@ -2471,6 +2490,9 @@ static void cxgb_down(struct adapter *adapter) | |||
2471 | } else | 2490 | } else |
2472 | free_irq(adapter->pdev->irq, adapter); | 2491 | free_irq(adapter->pdev->irq, adapter); |
2473 | quiesce_rx(adapter); | 2492 | quiesce_rx(adapter); |
2493 | t4_sge_stop(adapter); | ||
2494 | t4_free_sge_resources(adapter); | ||
2495 | adapter->flags &= ~FULL_INIT_DONE; | ||
2474 | } | 2496 | } |
2475 | 2497 | ||
2476 | /* | 2498 | /* |
@@ -2482,11 +2504,13 @@ static int cxgb_open(struct net_device *dev) | |||
2482 | struct port_info *pi = netdev_priv(dev); | 2504 | struct port_info *pi = netdev_priv(dev); |
2483 | struct adapter *adapter = pi->adapter; | 2505 | struct adapter *adapter = pi->adapter; |
2484 | 2506 | ||
2485 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) | 2507 | if (!(adapter->flags & FULL_INIT_DONE)) { |
2486 | return err; | 2508 | err = cxgb_up(adapter); |
2509 | if (err < 0) | ||
2510 | return err; | ||
2511 | } | ||
2487 | 2512 | ||
2488 | dev->real_num_tx_queues = pi->nqsets; | 2513 | dev->real_num_tx_queues = pi->nqsets; |
2489 | set_bit(pi->tx_chan, &adapter->open_device_map); | ||
2490 | link_start(dev); | 2514 | link_start(dev); |
2491 | netif_tx_start_all_queues(dev); | 2515 | netif_tx_start_all_queues(dev); |
2492 | return 0; | 2516 | return 0; |
@@ -2494,19 +2518,12 @@ static int cxgb_open(struct net_device *dev) | |||
2494 | 2518 | ||
2495 | static int cxgb_close(struct net_device *dev) | 2519 | static int cxgb_close(struct net_device *dev) |
2496 | { | 2520 | { |
2497 | int ret; | ||
2498 | struct port_info *pi = netdev_priv(dev); | 2521 | struct port_info *pi = netdev_priv(dev); |
2499 | struct adapter *adapter = pi->adapter; | 2522 | struct adapter *adapter = pi->adapter; |
2500 | 2523 | ||
2501 | netif_tx_stop_all_queues(dev); | 2524 | netif_tx_stop_all_queues(dev); |
2502 | netif_carrier_off(dev); | 2525 | netif_carrier_off(dev); |
2503 | ret = t4_enable_vi(adapter, 0, pi->viid, false, false); | 2526 | return t4_enable_vi(adapter, 0, pi->viid, false, false); |
2504 | |||
2505 | clear_bit(pi->tx_chan, &adapter->open_device_map); | ||
2506 | |||
2507 | if (!adapter->open_device_map) | ||
2508 | cxgb_down(adapter); | ||
2509 | return 0; | ||
2510 | } | 2527 | } |
2511 | 2528 | ||
2512 | static struct net_device_stats *cxgb_get_stats(struct net_device *dev) | 2529 | static struct net_device_stats *cxgb_get_stats(struct net_device *dev) |
@@ -2601,7 +2618,7 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) | |||
2601 | 2618 | ||
2602 | if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ | 2619 | if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ |
2603 | return -EINVAL; | 2620 | return -EINVAL; |
2604 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, | 2621 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, -1, |
2605 | true); | 2622 | true); |
2606 | if (!ret) | 2623 | if (!ret) |
2607 | dev->mtu = new_mtu; | 2624 | dev->mtu = new_mtu; |
@@ -2632,7 +2649,8 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | |||
2632 | struct port_info *pi = netdev_priv(dev); | 2649 | struct port_info *pi = netdev_priv(dev); |
2633 | 2650 | ||
2634 | pi->vlan_grp = grp; | 2651 | pi->vlan_grp = grp; |
2635 | t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL); | 2652 | t4_set_rxmode(pi->adapter, 0, pi->viid, -1, -1, -1, -1, grp != NULL, |
2653 | true); | ||
2636 | } | 2654 | } |
2637 | 2655 | ||
2638 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2656 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -3066,6 +3084,12 @@ static void __devinit print_port_info(struct adapter *adap) | |||
3066 | 3084 | ||
3067 | int i; | 3085 | int i; |
3068 | char buf[80]; | 3086 | char buf[80]; |
3087 | const char *spd = ""; | ||
3088 | |||
3089 | if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_2_5GB) | ||
3090 | spd = " 2.5 GT/s"; | ||
3091 | else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) | ||
3092 | spd = " 5 GT/s"; | ||
3069 | 3093 | ||
3070 | for_each_port(adap, i) { | 3094 | for_each_port(adap, i) { |
3071 | struct net_device *dev = adap->port[i]; | 3095 | struct net_device *dev = adap->port[i]; |
@@ -3085,10 +3109,10 @@ static void __devinit print_port_info(struct adapter *adap) | |||
3085 | --bufp; | 3109 | --bufp; |
3086 | sprintf(bufp, "BASE-%s", base[pi->port_type]); | 3110 | sprintf(bufp, "BASE-%s", base[pi->port_type]); |
3087 | 3111 | ||
3088 | netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n", | 3112 | netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", |
3089 | adap->params.vpd.id, adap->params.rev, | 3113 | adap->params.vpd.id, adap->params.rev, |
3090 | buf, is_offload(adap) ? "R" : "", | 3114 | buf, is_offload(adap) ? "R" : "", |
3091 | adap->params.pci.width, | 3115 | adap->params.pci.width, spd, |
3092 | (adap->flags & USING_MSIX) ? " MSI-X" : | 3116 | (adap->flags & USING_MSIX) ? " MSI-X" : |
3093 | (adap->flags & USING_MSI) ? " MSI" : ""); | 3117 | (adap->flags & USING_MSI) ? " MSI" : ""); |
3094 | if (adap->name == dev->name) | 3118 | if (adap->name == dev->name) |
@@ -3203,7 +3227,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3203 | 3227 | ||
3204 | netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; | 3228 | netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; |
3205 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 3229 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
3206 | netdev->features |= NETIF_F_GRO | highdma; | 3230 | netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma; |
3207 | netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 3231 | netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
3208 | netdev->vlan_features = netdev->features & VLAN_FEAT; | 3232 | netdev->vlan_features = netdev->features & VLAN_FEAT; |
3209 | 3233 | ||
@@ -3334,8 +3358,8 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
3334 | if (adapter->debugfs_root) | 3358 | if (adapter->debugfs_root) |
3335 | debugfs_remove_recursive(adapter->debugfs_root); | 3359 | debugfs_remove_recursive(adapter->debugfs_root); |
3336 | 3360 | ||
3337 | t4_sge_stop(adapter); | 3361 | if (adapter->flags & FULL_INIT_DONE) |
3338 | t4_free_sge_resources(adapter); | 3362 | cxgb_down(adapter); |
3339 | t4_free_mem(adapter->l2t); | 3363 | t4_free_mem(adapter->l2t); |
3340 | t4_free_mem(adapter->tids.tid_tab); | 3364 | t4_free_mem(adapter->tids.tid_tab); |
3341 | disable_msi(adapter); | 3365 | disable_msi(adapter); |