aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-08 22:46:55 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-10 21:55:19 -0400
commit5e982f3bfdd5d063f8806a26c87843496a35d26b (patch)
tree6526772af4bbe2222aaa0625c9f53006de1c7464 /drivers/net
parent044a890c5a0fb7ac60c70bbb4e1b79e59272e504 (diff)
net: stmmac: convert to hw_features
This also removes TSO as it's made fully in software --- better to leave this to networking core. If the MAC features can be detected at probe time and not at open, then stmmac_fix_features could be simplified by limiting hw_features. That's also better for users as they don't see offloads being togglable but never turned on. Redundant fallbacks for TX csum are removed as it's already handled by network core. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c14
-rw-r--r--drivers/net/stmmac/stmmac_main.c83
2 files changed, 23 insertions, 74 deletions
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index fd719edc7f7c..156a805c6c23 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -197,13 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
197 } 197 }
198} 198}
199 199
200static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
201{
202 struct stmmac_priv *priv = netdev_priv(dev);
203
204 return priv->rx_coe;
205}
206
207static void 200static void
208stmmac_get_pauseparam(struct net_device *netdev, 201stmmac_get_pauseparam(struct net_device *netdev,
209 struct ethtool_pauseparam *pause) 202 struct ethtool_pauseparam *pause)
@@ -358,11 +351,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
358 .get_regs = stmmac_ethtool_gregs, 351 .get_regs = stmmac_ethtool_gregs,
359 .get_regs_len = stmmac_ethtool_get_regs_len, 352 .get_regs_len = stmmac_ethtool_get_regs_len,
360 .get_link = ethtool_op_get_link, 353 .get_link = ethtool_op_get_link,
361 .get_rx_csum = stmmac_ethtool_get_rx_csum,
362 .get_tx_csum = ethtool_op_get_tx_csum,
363 .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
364 .get_sg = ethtool_op_get_sg,
365 .set_sg = ethtool_op_set_sg,
366 .get_pauseparam = stmmac_get_pauseparam, 354 .get_pauseparam = stmmac_get_pauseparam,
367 .set_pauseparam = stmmac_set_pauseparam, 355 .set_pauseparam = stmmac_set_pauseparam,
368 .get_ethtool_stats = stmmac_get_ethtool_stats, 356 .get_ethtool_stats = stmmac_get_ethtool_stats,
@@ -370,8 +358,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
370 .get_wol = stmmac_get_wol, 358 .get_wol = stmmac_get_wol,
371 .set_wol = stmmac_set_wol, 359 .set_wol = stmmac_set_wol,
372 .get_sset_count = stmmac_get_sset_count, 360 .get_sset_count = stmmac_get_sset_count,
373 .get_tso = ethtool_op_get_tso,
374 .set_tso = ethtool_op_set_tso,
375}; 361};
376 362
377void stmmac_set_ethtool_ops(struct net_device *netdev) 363void stmmac_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 0e5f03135b50..62fa51ed93ff 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -139,7 +139,6 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
139 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 139 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
140 140
141static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 141static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
142static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
143 142
144/** 143/**
145 * stmmac_verify_args - verify the driver parameters. 144 * stmmac_verify_args - verify the driver parameters.
@@ -843,6 +842,7 @@ static int stmmac_open(struct net_device *dev)
843 pr_info("stmmac: Rx Checksum Offload Engine supported\n"); 842 pr_info("stmmac: Rx Checksum Offload Engine supported\n");
844 if (priv->plat->tx_coe) 843 if (priv->plat->tx_coe)
845 pr_info("\tTX Checksum insertion supported\n"); 844 pr_info("\tTX Checksum insertion supported\n");
845 netdev_update_features(dev);
846 846
847 /* Initialise the MMC (if present) to disable all interrupts. */ 847 /* Initialise the MMC (if present) to disable all interrupts. */
848 writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); 848 writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
@@ -927,46 +927,6 @@ static int stmmac_release(struct net_device *dev)
927 return 0; 927 return 0;
928} 928}
929 929
930/*
931 * To perform emulated hardware segmentation on skb.
932 */
933static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
934{
935 struct sk_buff *segs, *curr_skb;
936 int gso_segs = skb_shinfo(skb)->gso_segs;
937
938 /* Estimate the number of fragments in the worst case */
939 if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
940 netif_stop_queue(priv->dev);
941 TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
942 __func__);
943 if (stmmac_tx_avail(priv) < gso_segs)
944 return NETDEV_TX_BUSY;
945
946 netif_wake_queue(priv->dev);
947 }
948 TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
949 skb, skb->len);
950
951 segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
952 if (IS_ERR(segs))
953 goto sw_tso_end;
954
955 do {
956 curr_skb = segs;
957 segs = segs->next;
958 TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
959 "*next %p\n", curr_skb->len, curr_skb, segs);
960 curr_skb->next = NULL;
961 stmmac_xmit(curr_skb, priv->dev);
962 } while (segs);
963
964sw_tso_end:
965 dev_kfree_skb(skb);
966
967 return NETDEV_TX_OK;
968}
969
970static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb, 930static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
971 struct net_device *dev, 931 struct net_device *dev,
972 int csum_insertion) 932 int csum_insertion)
@@ -1044,16 +1004,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
1044 !skb_is_gso(skb) ? "isn't" : "is"); 1004 !skb_is_gso(skb) ? "isn't" : "is");
1045#endif 1005#endif
1046 1006
1047 if (unlikely(skb_is_gso(skb))) 1007 csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
1048 return stmmac_sw_tso(priv, skb);
1049
1050 if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
1051 if (unlikely((!priv->plat->tx_coe) ||
1052 (priv->no_csum_insertion)))
1053 skb_checksum_help(skb);
1054 else
1055 csum_insertion = 1;
1056 }
1057 1008
1058 desc = priv->dma_tx + entry; 1009 desc = priv->dma_tx + entry;
1059 first = desc; 1010 first = desc;
@@ -1373,18 +1324,29 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
1373 return -EINVAL; 1324 return -EINVAL;
1374 } 1325 }
1375 1326
1327 dev->mtu = new_mtu;
1328 netdev_update_features(dev);
1329
1330 return 0;
1331}
1332
1333static u32 stmmac_fix_features(struct net_device *dev, u32 features)
1334{
1335 struct stmmac_priv *priv = netdev_priv(dev);
1336
1337 if (!priv->rx_coe)
1338 features &= ~NETIF_F_RXCSUM;
1339 if (!priv->plat->tx_coe)
1340 features &= ~NETIF_F_ALL_CSUM;
1341
1376 /* Some GMAC devices have a bugged Jumbo frame support that 1342 /* Some GMAC devices have a bugged Jumbo frame support that
1377 * needs to have the Tx COE disabled for oversized frames 1343 * needs to have the Tx COE disabled for oversized frames
1378 * (due to limited buffer sizes). In this case we disable 1344 * (due to limited buffer sizes). In this case we disable
1379 * the TX csum insertionin the TDES and not use SF. */ 1345 * the TX csum insertionin the TDES and not use SF. */
1380 if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) 1346 if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
1381 priv->no_csum_insertion = 1; 1347 features &= ~NETIF_F_ALL_CSUM;
1382 else
1383 priv->no_csum_insertion = 0;
1384 1348
1385 dev->mtu = new_mtu; 1349 return features;
1386
1387 return 0;
1388} 1350}
1389 1351
1390static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 1352static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
@@ -1464,6 +1426,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
1464 .ndo_start_xmit = stmmac_xmit, 1426 .ndo_start_xmit = stmmac_xmit,
1465 .ndo_stop = stmmac_release, 1427 .ndo_stop = stmmac_release,
1466 .ndo_change_mtu = stmmac_change_mtu, 1428 .ndo_change_mtu = stmmac_change_mtu,
1429 .ndo_fix_features = stmmac_fix_features,
1467 .ndo_set_multicast_list = stmmac_multicast_list, 1430 .ndo_set_multicast_list = stmmac_multicast_list,
1468 .ndo_tx_timeout = stmmac_tx_timeout, 1431 .ndo_tx_timeout = stmmac_tx_timeout,
1469 .ndo_do_ioctl = stmmac_ioctl, 1432 .ndo_do_ioctl = stmmac_ioctl,
@@ -1494,8 +1457,8 @@ static int stmmac_probe(struct net_device *dev)
1494 dev->netdev_ops = &stmmac_netdev_ops; 1457 dev->netdev_ops = &stmmac_netdev_ops;
1495 stmmac_set_ethtool_ops(dev); 1458 stmmac_set_ethtool_ops(dev);
1496 1459
1497 dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA | 1460 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
1498 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 1461 dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
1499 dev->watchdog_timeo = msecs_to_jiffies(watchdog); 1462 dev->watchdog_timeo = msecs_to_jiffies(watchdog);
1500#ifdef STMMAC_VLAN_TAG_USED 1463#ifdef STMMAC_VLAN_TAG_USED
1501 /* Both mac100 and gmac support receive VLAN tag detection */ 1464 /* Both mac100 and gmac support receive VLAN tag detection */