aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-08 02:35:56 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-10 21:55:18 -0400
commit350fb32ae45ec74ea9cc117c728c48b8e840f0f9 (patch)
treeaf5b53bf85da0a00b20ef239166be8dc9c017667 /drivers/net
parent8b8ddc68df13032a5666438b48dfb7a86de3a610 (diff)
net: r8169: convert to hw_features
Simple conversion with a bit of needed cleanup. This also fixes: - confusion around vlan_features in rtl8169_vlan_mode(), - problem with broken TSO for too big MTU (the limit is set at 0xFFF --- max MSS field value). SG+IP_CSUM+TSO is left disabled by default, based on suggestion by David Dillow. 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/r8169.c95
1 files changed, 33 insertions, 62 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index caa99cdb5818..058524f3eb49 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1286,14 +1286,15 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1286 return ret; 1286 return ret;
1287} 1287}
1288 1288
1289static u32 rtl8169_get_rx_csum(struct net_device *dev) 1289static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
1290{ 1290{
1291 struct rtl8169_private *tp = netdev_priv(dev); 1291 if (dev->mtu > MSSMask)
1292 features &= ~NETIF_F_ALL_TSO;
1292 1293
1293 return tp->cp_cmd & RxChkSum; 1294 return features;
1294} 1295}
1295 1296
1296static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) 1297static int rtl8169_set_features(struct net_device *dev, u32 features)
1297{ 1298{
1298 struct rtl8169_private *tp = netdev_priv(dev); 1299 struct rtl8169_private *tp = netdev_priv(dev);
1299 void __iomem *ioaddr = tp->mmio_addr; 1300 void __iomem *ioaddr = tp->mmio_addr;
@@ -1301,11 +1302,16 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
1301 1302
1302 spin_lock_irqsave(&tp->lock, flags); 1303 spin_lock_irqsave(&tp->lock, flags);
1303 1304
1304 if (data) 1305 if (features & NETIF_F_RXCSUM)
1305 tp->cp_cmd |= RxChkSum; 1306 tp->cp_cmd |= RxChkSum;
1306 else 1307 else
1307 tp->cp_cmd &= ~RxChkSum; 1308 tp->cp_cmd &= ~RxChkSum;
1308 1309
1310 if (dev->features & NETIF_F_HW_VLAN_RX)
1311 tp->cp_cmd |= RxVlan;
1312 else
1313 tp->cp_cmd &= ~RxVlan;
1314
1309 RTL_W16(CPlusCmd, tp->cp_cmd); 1315 RTL_W16(CPlusCmd, tp->cp_cmd);
1310 RTL_R16(CPlusCmd); 1316 RTL_R16(CPlusCmd);
1311 1317
@@ -1321,27 +1327,6 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
1321 TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; 1327 TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
1322} 1328}
1323 1329
1324#define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)
1325
1326static void rtl8169_vlan_mode(struct net_device *dev)
1327{
1328 struct rtl8169_private *tp = netdev_priv(dev);
1329 void __iomem *ioaddr = tp->mmio_addr;
1330 unsigned long flags;
1331
1332 spin_lock_irqsave(&tp->lock, flags);
1333 if (dev->features & NETIF_F_HW_VLAN_RX)
1334 tp->cp_cmd |= RxVlan;
1335 else
1336 tp->cp_cmd &= ~RxVlan;
1337 RTL_W16(CPlusCmd, tp->cp_cmd);
1338 /* PCI commit */
1339 RTL_R16(CPlusCmd);
1340 spin_unlock_irqrestore(&tp->lock, flags);
1341
1342 dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX;
1343}
1344
1345static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) 1330static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
1346{ 1331{
1347 u32 opts2 = le32_to_cpu(desc->opts2); 1332 u32 opts2 = le32_to_cpu(desc->opts2);
@@ -1522,28 +1507,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1522 } 1507 }
1523} 1508}
1524 1509
1525static int rtl8169_set_flags(struct net_device *dev, u32 data)
1526{
1527 struct rtl8169_private *tp = netdev_priv(dev);
1528 unsigned long old_feat = dev->features;
1529 int rc;
1530
1531 if ((tp->mac_version == RTL_GIGA_MAC_VER_05) &&
1532 !(data & ETH_FLAG_RXVLAN)) {
1533 netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n");
1534 return -EINVAL;
1535 }
1536
1537 rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN);
1538 if (rc)
1539 return rc;
1540
1541 if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX)
1542 rtl8169_vlan_mode(dev);
1543
1544 return 0;
1545}
1546
1547static const struct ethtool_ops rtl8169_ethtool_ops = { 1510static const struct ethtool_ops rtl8169_ethtool_ops = {
1548 .get_drvinfo = rtl8169_get_drvinfo, 1511 .get_drvinfo = rtl8169_get_drvinfo,
1549 .get_regs_len = rtl8169_get_regs_len, 1512 .get_regs_len = rtl8169_get_regs_len,
@@ -1552,19 +1515,12 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
1552 .set_settings = rtl8169_set_settings, 1515 .set_settings = rtl8169_set_settings,
1553 .get_msglevel = rtl8169_get_msglevel, 1516 .get_msglevel = rtl8169_get_msglevel,
1554 .set_msglevel = rtl8169_set_msglevel, 1517 .set_msglevel = rtl8169_set_msglevel,
1555 .get_rx_csum = rtl8169_get_rx_csum,
1556 .set_rx_csum = rtl8169_set_rx_csum,
1557 .set_tx_csum = ethtool_op_set_tx_csum,
1558 .set_sg = ethtool_op_set_sg,
1559 .set_tso = ethtool_op_set_tso,
1560 .get_regs = rtl8169_get_regs, 1518 .get_regs = rtl8169_get_regs,
1561 .get_wol = rtl8169_get_wol, 1519 .get_wol = rtl8169_get_wol,
1562 .set_wol = rtl8169_set_wol, 1520 .set_wol = rtl8169_set_wol,
1563 .get_strings = rtl8169_get_strings, 1521 .get_strings = rtl8169_get_strings,
1564 .get_sset_count = rtl8169_get_sset_count, 1522 .get_sset_count = rtl8169_get_sset_count,
1565 .get_ethtool_stats = rtl8169_get_ethtool_stats, 1523 .get_ethtool_stats = rtl8169_get_ethtool_stats,
1566 .set_flags = rtl8169_set_flags,
1567 .get_flags = ethtool_op_get_flags,
1568}; 1524};
1569 1525
1570static void rtl8169_get_mac_version(struct rtl8169_private *tp, 1526static void rtl8169_get_mac_version(struct rtl8169_private *tp,
@@ -2979,6 +2935,8 @@ static const struct net_device_ops rtl8169_netdev_ops = {
2979 .ndo_tx_timeout = rtl8169_tx_timeout, 2935 .ndo_tx_timeout = rtl8169_tx_timeout,
2980 .ndo_validate_addr = eth_validate_addr, 2936 .ndo_validate_addr = eth_validate_addr,
2981 .ndo_change_mtu = rtl8169_change_mtu, 2937 .ndo_change_mtu = rtl8169_change_mtu,
2938 .ndo_fix_features = rtl8169_fix_features,
2939 .ndo_set_features = rtl8169_set_features,
2982 .ndo_set_mac_address = rtl_set_mac_address, 2940 .ndo_set_mac_address = rtl_set_mac_address,
2983 .ndo_do_ioctl = rtl8169_ioctl, 2941 .ndo_do_ioctl = rtl8169_ioctl,
2984 .ndo_set_multicast_list = rtl_set_rx_mode, 2942 .ndo_set_multicast_list = rtl_set_rx_mode,
@@ -3425,7 +3383,19 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3425 3383
3426 netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); 3384 netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
3427 3385
3428 dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO; 3386 /* don't enable SG, IP_CSUM and TSO by default - it might not work
3387 * properly for all devices */
3388 dev->features |= NETIF_F_RXCSUM |
3389 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
3390
3391 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
3392 NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
3393 dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
3394 NETIF_F_HIGHDMA;
3395
3396 if (tp->mac_version == RTL_GIGA_MAC_VER_05)
3397 /* 8110SCd requires hardware Rx VLAN - disallow toggling */
3398 dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
3429 3399
3430 tp->intr_mask = 0xffff; 3400 tp->intr_mask = 0xffff;
3431 tp->hw_start = cfg->hw_start; 3401 tp->hw_start = cfg->hw_start;
@@ -3545,7 +3515,7 @@ static int rtl8169_open(struct net_device *dev)
3545 3515
3546 rtl8169_init_phy(dev, tp); 3516 rtl8169_init_phy(dev, tp);
3547 3517
3548 rtl8169_vlan_mode(dev); 3518 rtl8169_set_features(dev, dev->features);
3549 3519
3550 rtl_pll_power_up(tp); 3520 rtl_pll_power_up(tp);
3551 3521
@@ -4318,6 +4288,8 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
4318 return -EINVAL; 4288 return -EINVAL;
4319 4289
4320 dev->mtu = new_mtu; 4290 dev->mtu = new_mtu;
4291 netdev_update_features(dev);
4292
4321 return 0; 4293 return 0;
4322} 4294}
4323 4295
@@ -4642,12 +4614,11 @@ err_out:
4642 4614
4643static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) 4615static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
4644{ 4616{
4645 if (dev->features & NETIF_F_TSO) { 4617 u32 mss = skb_shinfo(skb)->gso_size;
4646 u32 mss = skb_shinfo(skb)->gso_size; 4618
4619 if (mss)
4620 return LargeSend | ((mss & MSSMask) << MSSShift);
4647 4621
4648 if (mss)
4649 return LargeSend | ((mss & MSSMask) << MSSShift);
4650 }
4651 if (skb->ip_summed == CHECKSUM_PARTIAL) { 4622 if (skb->ip_summed == CHECKSUM_PARTIAL) {
4652 const struct iphdr *ip = ip_hdr(skb); 4623 const struct iphdr *ip = ip_hdr(skb);
4653 4624