aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-12 05:38:23 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-12 17:50:44 -0400
commit66371c44136b566f39f70c72cb4d117558bee3fa (patch)
tree0976d78d048da3c8bddba3a177b42e35c78d070b /drivers/net/bnx2x
parente5ee20e70f078d584572709962f5d90f876912c3 (diff)
net: bnx2x: convert to hw_features
Since ndo_fix_features callback is postponing features change when bp->recovery_state != BNX2X_RECOVERY_DONE, netdev_update_features() has to be called again when this condition changes. Previously, ethtool_ops->set_flags callback returned -EBUSY in that case (it's not possible in the new model). Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> v5: - don't delay set_features, as it's rtnl_locked - same as recovery process v4: - complete bp->rx_csum -> NETIF_F_RXCSUM conversion - add check for failed ndo_set_features in ndo_open callback v3: - include NETIF_F_LRO in hw_features - don't call netdev_update_features() if bnx2x_nic_load() failed v2: - comment in ndo_fix_features callback Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r--drivers/net/bnx2x/bnx2x.h1
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c49
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h3
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c95
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c27
5 files changed, 57 insertions, 118 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index e0fca701d2f..9e87417f6ec 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -918,7 +918,6 @@ struct bnx2x {
918 918
919 int tx_ring_size; 919 int tx_ring_size;
920 920
921 u32 rx_csum;
922/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ 921/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
923#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) 922#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
924#define ETH_MIN_PACKET_SIZE 60 923#define ETH_MIN_PACKET_SIZE 60
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index e83ac6dd6fc..bec33a87bcd 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -640,7 +640,7 @@ reuse_rx:
640 640
641 skb_checksum_none_assert(skb); 641 skb_checksum_none_assert(skb);
642 642
643 if (bp->rx_csum) { 643 if (bp->dev->features & NETIF_F_RXCSUM) {
644 if (likely(BNX2X_RX_CSUM_OK(cqe))) 644 if (likely(BNX2X_RX_CSUM_OK(cqe)))
645 skb->ip_summed = CHECKSUM_UNNECESSARY; 645 skb->ip_summed = CHECKSUM_UNNECESSARY;
646 else 646 else
@@ -2443,11 +2443,21 @@ alloc_err:
2443 2443
2444} 2444}
2445 2445
2446static int bnx2x_reload_if_running(struct net_device *dev)
2447{
2448 struct bnx2x *bp = netdev_priv(dev);
2449
2450 if (unlikely(!netif_running(dev)))
2451 return 0;
2452
2453 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
2454 return bnx2x_nic_load(bp, LOAD_NORMAL);
2455}
2456
2446/* called with rtnl_lock */ 2457/* called with rtnl_lock */
2447int bnx2x_change_mtu(struct net_device *dev, int new_mtu) 2458int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
2448{ 2459{
2449 struct bnx2x *bp = netdev_priv(dev); 2460 struct bnx2x *bp = netdev_priv(dev);
2450 int rc = 0;
2451 2461
2452 if (bp->recovery_state != BNX2X_RECOVERY_DONE) { 2462 if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
2453 printk(KERN_ERR "Handling parity error recovery. Try again later\n"); 2463 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
@@ -2464,12 +2474,39 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
2464 */ 2474 */
2465 dev->mtu = new_mtu; 2475 dev->mtu = new_mtu;
2466 2476
2467 if (netif_running(dev)) { 2477 return bnx2x_reload_if_running(dev);
2468 bnx2x_nic_unload(bp, UNLOAD_NORMAL); 2478}
2469 rc = bnx2x_nic_load(bp, LOAD_NORMAL); 2479
2480u32 bnx2x_fix_features(struct net_device *dev, u32 features)
2481{
2482 struct bnx2x *bp = netdev_priv(dev);
2483
2484 /* TPA requires Rx CSUM offloading */
2485 if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa)
2486 features &= ~NETIF_F_LRO;
2487
2488 return features;
2489}
2490
2491int bnx2x_set_features(struct net_device *dev, u32 features)
2492{
2493 struct bnx2x *bp = netdev_priv(dev);
2494 u32 flags = bp->flags;
2495
2496 if (features & NETIF_F_LRO)
2497 flags |= TPA_ENABLE_FLAG;
2498 else
2499 flags &= ~TPA_ENABLE_FLAG;
2500
2501 if (flags ^ bp->flags) {
2502 bp->flags = flags;
2503
2504 if (bp->recovery_state == BNX2X_RECOVERY_DONE)
2505 return bnx2x_reload_if_running(dev);
2506 /* else: bnx2x_nic_load() will be called at end of recovery */
2470 } 2507 }
2471 2508
2472 return rc; 2509 return 0;
2473} 2510}
2474 2511
2475void bnx2x_tx_timeout(struct net_device *dev) 2512void bnx2x_tx_timeout(struct net_device *dev)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 775fef031ad..1cdab69b2a5 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -431,6 +431,9 @@ void bnx2x_free_mem_bp(struct bnx2x *bp);
431 */ 431 */
432int bnx2x_change_mtu(struct net_device *dev, int new_mtu); 432int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
433 433
434u32 bnx2x_fix_features(struct net_device *dev, u32 features);
435int bnx2x_set_features(struct net_device *dev, u32 features);
436
434/** 437/**
435 * tx timeout netdev callback 438 * tx timeout netdev callback
436 * 439 *
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 147999459df..ad7d91e499f 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1299,91 +1299,6 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
1299 return 0; 1299 return 0;
1300} 1300}
1301 1301
1302static int bnx2x_set_flags(struct net_device *dev, u32 data)
1303{
1304 struct bnx2x *bp = netdev_priv(dev);
1305 int changed = 0;
1306 int rc = 0;
1307
1308 if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1309 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1310 return -EAGAIN;
1311 }
1312
1313 if (!(data & ETH_FLAG_RXVLAN))
1314 return -EINVAL;
1315
1316 if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
1317 return -EINVAL;
1318
1319 rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN |
1320 ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
1321 if (rc)
1322 return rc;
1323
1324 /* TPA requires Rx CSUM offloading */
1325 if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
1326 if (!(bp->flags & TPA_ENABLE_FLAG)) {
1327 bp->flags |= TPA_ENABLE_FLAG;
1328 changed = 1;
1329 }
1330 } else if (bp->flags & TPA_ENABLE_FLAG) {
1331 dev->features &= ~NETIF_F_LRO;
1332 bp->flags &= ~TPA_ENABLE_FLAG;
1333 changed = 1;
1334 }
1335
1336 if (changed && netif_running(dev)) {
1337 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1338 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
1339 }
1340
1341 return rc;
1342}
1343
1344static u32 bnx2x_get_rx_csum(struct net_device *dev)
1345{
1346 struct bnx2x *bp = netdev_priv(dev);
1347
1348 return bp->rx_csum;
1349}
1350
1351static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
1352{
1353 struct bnx2x *bp = netdev_priv(dev);
1354 int rc = 0;
1355
1356 if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1357 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1358 return -EAGAIN;
1359 }
1360
1361 bp->rx_csum = data;
1362
1363 /* Disable TPA, when Rx CSUM is disabled. Otherwise all
1364 TPA'ed packets will be discarded due to wrong TCP CSUM */
1365 if (!data) {
1366 u32 flags = ethtool_op_get_flags(dev);
1367
1368 rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
1369 }
1370
1371 return rc;
1372}
1373
1374static int bnx2x_set_tso(struct net_device *dev, u32 data)
1375{
1376 if (data) {
1377 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
1378 dev->features |= NETIF_F_TSO6;
1379 } else {
1380 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
1381 dev->features &= ~NETIF_F_TSO6;
1382 }
1383
1384 return 0;
1385}
1386
1387static const struct { 1302static const struct {
1388 char string[ETH_GSTRING_LEN]; 1303 char string[ETH_GSTRING_LEN];
1389} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { 1304} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
@@ -2207,16 +2122,6 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
2207 .set_ringparam = bnx2x_set_ringparam, 2122 .set_ringparam = bnx2x_set_ringparam,
2208 .get_pauseparam = bnx2x_get_pauseparam, 2123 .get_pauseparam = bnx2x_get_pauseparam,
2209 .set_pauseparam = bnx2x_set_pauseparam, 2124 .set_pauseparam = bnx2x_set_pauseparam,
2210 .get_rx_csum = bnx2x_get_rx_csum,
2211 .set_rx_csum = bnx2x_set_rx_csum,
2212 .get_tx_csum = ethtool_op_get_tx_csum,
2213 .set_tx_csum = ethtool_op_set_tx_hw_csum,
2214 .set_flags = bnx2x_set_flags,
2215 .get_flags = ethtool_op_get_flags,
2216 .get_sg = ethtool_op_get_sg,
2217 .set_sg = ethtool_op_set_sg,
2218 .get_tso = ethtool_op_get_tso,
2219 .set_tso = bnx2x_set_tso,
2220 .self_test = bnx2x_self_test, 2125 .self_test = bnx2x_self_test,
2221 .get_sset_count = bnx2x_get_sset_count, 2126 .get_sset_count = bnx2x_get_sset_count,
2222 .get_strings = bnx2x_get_strings, 2127 .get_strings = bnx2x_get_strings,
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index a6915aafa69..696e84afdc5 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -8904,8 +8904,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
8904 bp->multi_mode = multi_mode; 8904 bp->multi_mode = multi_mode;
8905 bp->int_mode = int_mode; 8905 bp->int_mode = int_mode;
8906 8906
8907 bp->dev->features |= NETIF_F_GRO;
8908
8909 /* Set TPA flags */ 8907 /* Set TPA flags */
8910 if (disable_tpa) { 8908 if (disable_tpa) {
8911 bp->flags &= ~TPA_ENABLE_FLAG; 8909 bp->flags &= ~TPA_ENABLE_FLAG;
@@ -8925,8 +8923,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
8925 8923
8926 bp->tx_ring_size = MAX_TX_AVAIL; 8924 bp->tx_ring_size = MAX_TX_AVAIL;
8927 8925
8928 bp->rx_csum = 1;
8929
8930 /* make sure that the numbers are in the right granularity */ 8926 /* make sure that the numbers are in the right granularity */
8931 bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; 8927 bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
8932 bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; 8928 bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
@@ -9304,6 +9300,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
9304 .ndo_validate_addr = eth_validate_addr, 9300 .ndo_validate_addr = eth_validate_addr,
9305 .ndo_do_ioctl = bnx2x_ioctl, 9301 .ndo_do_ioctl = bnx2x_ioctl,
9306 .ndo_change_mtu = bnx2x_change_mtu, 9302 .ndo_change_mtu = bnx2x_change_mtu,
9303 .ndo_fix_features = bnx2x_fix_features,
9304 .ndo_set_features = bnx2x_set_features,
9307 .ndo_tx_timeout = bnx2x_tx_timeout, 9305 .ndo_tx_timeout = bnx2x_tx_timeout,
9308#ifdef CONFIG_NET_POLL_CONTROLLER 9306#ifdef CONFIG_NET_POLL_CONTROLLER
9309 .ndo_poll_controller = poll_bnx2x, 9307 .ndo_poll_controller = poll_bnx2x,
@@ -9430,20 +9428,17 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
9430 9428
9431 dev->netdev_ops = &bnx2x_netdev_ops; 9429 dev->netdev_ops = &bnx2x_netdev_ops;
9432 bnx2x_set_ethtool_ops(dev); 9430 bnx2x_set_ethtool_ops(dev);
9433 dev->features |= NETIF_F_SG;
9434 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
9435 if (bp->flags & USING_DAC_FLAG)
9436 dev->features |= NETIF_F_HIGHDMA;
9437 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
9438 dev->features |= NETIF_F_TSO6;
9439 dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
9440 9431
9441 dev->vlan_features |= NETIF_F_SG; 9432 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
9442 dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 9433 NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
9434 NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
9435
9436 dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
9437 NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
9438
9439 dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
9443 if (bp->flags & USING_DAC_FLAG) 9440 if (bp->flags & USING_DAC_FLAG)
9444 dev->vlan_features |= NETIF_F_HIGHDMA; 9441 dev->features |= NETIF_F_HIGHDMA;
9445 dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
9446 dev->vlan_features |= NETIF_F_TSO6;
9447 9442
9448#ifdef BCM_DCBNL 9443#ifdef BCM_DCBNL
9449 dev->dcbnl_ops = &bnx2x_dcbnl_ops; 9444 dev->dcbnl_ops = &bnx2x_dcbnl_ops;