From 87b6cf51acb4999fff7e6841986874b108679cb4 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 27 Apr 2010 16:22:42 -0700 Subject: cxgb4: set skb->rxhash Implement the ->set_flags ethtool method to control NETIF_F_RXHASH and set skb->rxhash to the HW calculated hash accordingly. Follow Eric Dumazet's suggestion and use the hash value raw. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 5f582db..1bad500 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1711,6 +1711,18 @@ static int set_tso(struct net_device *dev, u32 value) return 0; } +static int set_flags(struct net_device *dev, u32 flags) +{ + if (flags & ~ETH_FLAG_RXHASH) + return -EOPNOTSUPP; + + if (flags & ETH_FLAG_RXHASH) + dev->features |= NETIF_F_RXHASH; + else + dev->features &= ~NETIF_F_RXHASH; + return 0; +} + static struct ethtool_ops cxgb_ethtool_ops = { .get_settings = get_settings, .set_settings = set_settings, @@ -1741,6 +1753,7 @@ static struct ethtool_ops cxgb_ethtool_ops = { .get_wol = get_wol, .set_wol = set_wol, .set_tso = set_tso, + .set_flags = set_flags, .flash_device = set_flash, }; @@ -3203,7 +3216,7 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_GRO | highdma; + netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma; netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; netdev->vlan_features = netdev->features & VLAN_FEAT; -- cgit v1.1 From f8f5aafa960883bc3f1b8f85f1cf8199d0c85879 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 10 May 2010 15:58:07 +0000 Subject: cxgb4: configure HW VLAN extraction through FW HW VLAN extraction needs to be configured through FW to work correctly in virtualization environments. Remove the direct register manipulation and rely on FW. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 1bad500..a73cda9 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -290,7 +290,7 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) if (ret == 0) ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu, (dev->flags & IFF_PROMISC) ? 1 : 0, - (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, + (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, -1, sleep_ok); return ret; } @@ -311,7 +311,7 @@ static int link_start(struct net_device *dev) * that step explicitly. */ ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1, - true); + pi->vlan_grp != NULL, true); if (ret == 0) { ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt, dev->dev_addr, true, @@ -2614,7 +2614,7 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ return -EINVAL; - ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, + ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, -1, true); if (!ret) dev->mtu = new_mtu; @@ -2645,7 +2645,8 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) struct port_info *pi = netdev_priv(dev); pi->vlan_grp = grp; - t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL); + t4_set_rxmode(pi->adapter, 0, pi->viid, -1, -1, -1, -1, grp != NULL, + true); } #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit v1.1 From f1a051b93090ad920e88748023ab0dea3a6e2ad7 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 10 May 2010 15:58:08 +0000 Subject: cxgb4: report the PCIe link speed Report the PCIe link speed (2.5 or 5 Gbps). Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index a73cda9..80c3fc5 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3080,6 +3080,12 @@ static void __devinit print_port_info(struct adapter *adap) int i; char buf[80]; + const char *spd = ""; + + if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_2_5GB) + spd = " 2.5 GT/s"; + else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) + spd = " 5 GT/s"; for_each_port(adap, i) { struct net_device *dev = adap->port[i]; @@ -3099,10 +3105,10 @@ static void __devinit print_port_info(struct adapter *adap) --bufp; sprintf(bufp, "BASE-%s", base[pi->port_type]); - netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n", + netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", adap->params.vpd.id, adap->params.rev, buf, is_offload(adap) ? "R" : "", - adap->params.pci.width, + adap->params.pci.width, spd, (adap->flags & USING_MSIX) ? " MSI-X" : (adap->flags & USING_MSI) ? " MSI" : ""); if (adap->name == dev->name) -- cgit v1.1 From 4a6346d4ea63b5e1390babf22f1cc0f113d8082b Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 10 May 2010 15:58:09 +0000 Subject: cxgb4: report GRO stats with ethtool -S Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 80c3fc5..90d375b 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -859,6 +859,8 @@ static char stats_strings[][ETH_GSTRING_LEN] = { "RxCsumGood ", "VLANextractions ", "VLANinsertions ", + "GROpackets ", + "GROmerged ", }; static int get_sset_count(struct net_device *dev, int sset) @@ -922,6 +924,8 @@ struct queue_port_stats { u64 rx_csum; u64 vlan_ex; u64 vlan_ins; + u64 gro_pkts; + u64 gro_merged; }; static void collect_sge_port_stats(const struct adapter *adap, @@ -938,6 +942,8 @@ static void collect_sge_port_stats(const struct adapter *adap, s->rx_csum += rx->stats.rx_cso; s->vlan_ex += rx->stats.vlan_ex; s->vlan_ins += tx->vlan_ins; + s->gro_pkts += rx->stats.lro_pkts; + s->gro_merged += rx->stats.lro_merged; } } -- cgit v1.1 From b6bd29e793c1747e0b4be8791d5738acea3a86df Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 18 May 2010 10:07:11 +0000 Subject: cxgb4: fix initial addition of MAC address The call to add the MAC address during link initialization wasn't adding the address to one of the HW tables. Fix. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 90d375b..1f59971 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -315,7 +315,7 @@ static int link_start(struct net_device *dev) if (ret == 0) { ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt, dev->dev_addr, true, - false); + true); if (ret >= 0) { pi->xact_addr_filt = ret; ret = 0; -- cgit v1.1 From aaefae9b32b2cba7350a4d524357168119372e51 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 18 May 2010 10:07:12 +0000 Subject: cxgb4: keep interrupts available when the ports are brought down The PF driver needs to remain alert while its ports are down to service requests or errors from virtual functions or FW so keep interrupts and queues available when the ports are brought down. The change makes open_device_map unnecessary so remove it. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 49 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 27 deletions(-) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 1f59971..87161ce 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2433,23 +2433,17 @@ EXPORT_SYMBOL(cxgb4_unregister_uld); */ static int cxgb_up(struct adapter *adap) { - int err = 0; + int err; - if (!(adap->flags & FULL_INIT_DONE)) { - err = setup_sge_queues(adap); - if (err) - goto out; - err = setup_rss(adap); - if (err) { - t4_free_sge_resources(adap); - goto out; - } - if (adap->flags & USING_MSIX) - name_msix_vecs(adap); - adap->flags |= FULL_INIT_DONE; - } + err = setup_sge_queues(adap); + if (err) + goto out; + err = setup_rss(adap); + if (err) + goto freeq; if (adap->flags & USING_MSIX) { + name_msix_vecs(adap); err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0, adap->msix_info[0].desc, adap); if (err) @@ -2470,11 +2464,14 @@ static int cxgb_up(struct adapter *adap) enable_rx(adap); t4_sge_start(adap); t4_intr_enable(adap); + adap->flags |= FULL_INIT_DONE; notify_ulds(adap, CXGB4_STATE_UP); out: return err; irq_err: dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); + freeq: + t4_free_sge_resources(adap); goto out; } @@ -2490,6 +2487,9 @@ static void cxgb_down(struct adapter *adapter) } else free_irq(adapter->pdev->irq, adapter); quiesce_rx(adapter); + t4_sge_stop(adapter); + t4_free_sge_resources(adapter); + adapter->flags &= ~FULL_INIT_DONE; } /* @@ -2501,11 +2501,13 @@ static int cxgb_open(struct net_device *dev) struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) - return err; + if (!(adapter->flags & FULL_INIT_DONE)) { + err = cxgb_up(adapter); + if (err < 0) + return err; + } dev->real_num_tx_queues = pi->nqsets; - set_bit(pi->tx_chan, &adapter->open_device_map); link_start(dev); netif_tx_start_all_queues(dev); return 0; @@ -2513,19 +2515,12 @@ static int cxgb_open(struct net_device *dev) static int cxgb_close(struct net_device *dev) { - int ret; struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; netif_tx_stop_all_queues(dev); netif_carrier_off(dev); - ret = t4_enable_vi(adapter, 0, pi->viid, false, false); - - clear_bit(pi->tx_chan, &adapter->open_device_map); - - if (!adapter->open_device_map) - cxgb_down(adapter); - return 0; + return t4_enable_vi(adapter, 0, pi->viid, false, false); } static struct net_device_stats *cxgb_get_stats(struct net_device *dev) @@ -3360,8 +3355,8 @@ static void __devexit remove_one(struct pci_dev *pdev) if (adapter->debugfs_root) debugfs_remove_recursive(adapter->debugfs_root); - t4_sge_stop(adapter); - t4_free_sge_resources(adapter); + if (adapter->flags & FULL_INIT_DONE) + cxgb_down(adapter); t4_free_mem(adapter->l2t); t4_free_mem(adapter->tids.tid_tab); disable_msi(adapter); -- cgit v1.1 From e29f5dbc9e9719af158a960e5c1d16f32740ebc3 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Tue, 18 May 2010 10:07:13 +0000 Subject: cxgb4: notify upper drivers if the device is already up when they load Upper layer drivers aren't notified that a device is ready if their modules load after the device becomes ready. Add the missing notification. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/cxgb4/cxgb4_main.c') diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 87161ce..58045b0 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2327,6 +2327,9 @@ static void uld_attach(struct adapter *adap, unsigned int uld) register_netevent_notifier(&cxgb4_netevent_nb); netevent_registered = true; } + + if (adap->flags & FULL_INIT_DONE) + ulds[uld].state_change(handle, CXGB4_STATE_UP); } static void attach_ulds(struct adapter *adap) -- cgit v1.1