diff options
-rw-r--r-- | drivers/net/r8169.c | 95 |
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 | ||
1289 | static u32 rtl8169_get_rx_csum(struct net_device *dev) | 1289 | static 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 | ||
1296 | static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) | 1297 | static 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 | |||
1326 | static 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 | |||
1345 | static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) | 1330 | static 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 | ||
1525 | static 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 | |||
1547 | static const struct ethtool_ops rtl8169_ethtool_ops = { | 1510 | static 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 | ||
1570 | static void rtl8169_get_mac_version(struct rtl8169_private *tp, | 1526 | static 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 | ||
4643 | static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) | 4615 | static 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 | ||