diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-04-08 22:46:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-10 21:55:19 -0400 |
commit | 5e982f3bfdd5d063f8806a26c87843496a35d26b (patch) | |
tree | 6526772af4bbe2222aaa0625c9f53006de1c7464 /drivers/net/stmmac/stmmac_main.c | |
parent | 044a890c5a0fb7ac60c70bbb4e1b79e59272e504 (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/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 83 |
1 files changed, 23 insertions, 60 deletions
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 | ||
141 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id); | 141 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id); |
142 | static 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 | */ | ||
933 | static 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 | |||
964 | sw_tso_end: | ||
965 | dev_kfree_skb(skb); | ||
966 | |||
967 | return NETDEV_TX_OK; | ||
968 | } | ||
969 | |||
970 | static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb, | 930 | static 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 | |||
1333 | static 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 | ||
1390 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id) | 1352 | static 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 */ |