diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2011-04-19 01:53:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-19 01:53:24 -0400 |
commit | 2b7b431858c284b62c18baaf2cea571be2797d5a (patch) | |
tree | 8aec96a197b6e9bf501752884c1f55c97e0c385b /drivers/net/r8169.c | |
parent | 47c2cdf5513e86e43c799da8d5406cc9a2bf3626 (diff) |
r8169: TSO fixes.
- the MSS value is actually contained in a 11 bits wide (0x7ff) field.
The extra bit in the former MSSMask did encompass the TSO command
bit ("LargeSend") as well (0xfff). Oops.
- the Tx descriptor layout is not the same through the whole chipset
family. The 8169 documentation, the 8168c documentation and Realtek's
drivers (8.020.00, 1.019.00, 6.014.00) highlight two layouts:
1. 8169, 8168 up to 8168b (included) and 8101
2. {8102e, 8168c} and beyond
- notwithstanding the "first descriptor" and "last descriptor" bits, the
same Tx descriptor content is enforced when a packet consists of several
descriptors. The chipsets are documented to require it.
Credits go to David Dillow <dave@thedillows.org> for the original patch.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Realtek <nic_swsd@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 209 |
1 files changed, 137 insertions, 72 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 058524f3eb49..fb03e6ff3716 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -134,47 +134,52 @@ enum mac_version { | |||
134 | RTL_GIGA_MAC_VER_33 = 0x21, // 8168E | 134 | RTL_GIGA_MAC_VER_33 = 0x21, // 8168E |
135 | }; | 135 | }; |
136 | 136 | ||
137 | #define _R(NAME,MAC,MASK) \ | 137 | enum rtl_tx_desc_version { |
138 | { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } | 138 | RTL_TD_0 = 0, |
139 | RTL_TD_1 = 1, | ||
140 | }; | ||
141 | |||
142 | #define _R(NAME,MAC,TD) \ | ||
143 | { .name = NAME, .mac_version = MAC, .txd_version = TD } | ||
139 | 144 | ||
140 | static const struct { | 145 | static const struct { |
141 | const char *name; | 146 | const char *name; |
142 | u8 mac_version; | 147 | u8 mac_version; |
143 | u32 RxConfigMask; /* Clears the bits supported by this chip */ | 148 | enum rtl_tx_desc_version txd_version; |
144 | } rtl_chip_info[] = { | 149 | } rtl_chip_info[] = { |
145 | _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 | 150 | _R("RTL8169", RTL_GIGA_MAC_VER_01, RTL_TD_0), // 8169 |
146 | _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S | 151 | _R("RTL8169s", RTL_GIGA_MAC_VER_02, RTL_TD_0), // 8169S |
147 | _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S | 152 | _R("RTL8110s", RTL_GIGA_MAC_VER_03, RTL_TD_0), // 8110S |
148 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB | 153 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, RTL_TD_0), // 8169SB |
149 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd | 154 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, RTL_TD_0), // 8110SCd |
150 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe | 155 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, RTL_TD_0), // 8110SCe |
151 | _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E | 156 | _R("RTL8102e", RTL_GIGA_MAC_VER_07, RTL_TD_1), // PCI-E |
152 | _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E | 157 | _R("RTL8102e", RTL_GIGA_MAC_VER_08, RTL_TD_1), // PCI-E |
153 | _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E | 158 | _R("RTL8102e", RTL_GIGA_MAC_VER_09, RTL_TD_1), // PCI-E |
154 | _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E | 159 | _R("RTL8101e", RTL_GIGA_MAC_VER_10, RTL_TD_0), // PCI-E |
155 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E | 160 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, RTL_TD_0), // PCI-E |
156 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E | 161 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, RTL_TD_0), // PCI-E |
157 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 | 162 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, RTL_TD_0), // PCI-E 8139 |
158 | _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 | 163 | _R("RTL8100e", RTL_GIGA_MAC_VER_14, RTL_TD_0), // PCI-E 8139 |
159 | _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 | 164 | _R("RTL8100e", RTL_GIGA_MAC_VER_15, RTL_TD_0), // PCI-E 8139 |
160 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E | 165 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, RTL_TD_0), // PCI-E |
161 | _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E | 166 | _R("RTL8101e", RTL_GIGA_MAC_VER_16, RTL_TD_0), // PCI-E |
162 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E | 167 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, RTL_TD_1), // PCI-E |
163 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E | 168 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, RTL_TD_1), // PCI-E |
164 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E | 169 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, RTL_TD_1), // PCI-E |
165 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E | 170 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, RTL_TD_1), // PCI-E |
166 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E | 171 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, RTL_TD_1), // PCI-E |
167 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E | 172 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, RTL_TD_1), // PCI-E |
168 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E | 173 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, RTL_TD_1), // PCI-E |
169 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E | 174 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, RTL_TD_1), // PCI-E |
170 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E | 175 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, RTL_TD_1), // PCI-E |
171 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E | 176 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, RTL_TD_1), // PCI-E |
172 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E | 177 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, RTL_TD_1), // PCI-E |
173 | _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E | 178 | _R("RTL8105e", RTL_GIGA_MAC_VER_29, RTL_TD_1), // PCI-E |
174 | _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880), // PCI-E | 179 | _R("RTL8105e", RTL_GIGA_MAC_VER_30, RTL_TD_1), // PCI-E |
175 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, 0xff7e1880), // PCI-E | 180 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, RTL_TD_1), // PCI-E |
176 | _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_32, 0xff7e1880), // PCI-E | 181 | _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_32, RTL_TD_1), // PCI-E |
177 | _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_33, 0xff7e1880) // PCI-E | 182 | _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_33, RTL_TD_1) // PCI-E |
178 | }; | 183 | }; |
179 | #undef _R | 184 | #undef _R |
180 | 185 | ||
@@ -230,6 +235,9 @@ enum rtl_registers { | |||
230 | IntrStatus = 0x3e, | 235 | IntrStatus = 0x3e, |
231 | TxConfig = 0x40, | 236 | TxConfig = 0x40, |
232 | RxConfig = 0x44, | 237 | RxConfig = 0x44, |
238 | |||
239 | #define RTL_RX_CONFIG_MASK 0xff7e1880u | ||
240 | |||
233 | RxMissed = 0x4c, | 241 | RxMissed = 0x4c, |
234 | Cfg9346 = 0x50, | 242 | Cfg9346 = 0x50, |
235 | Config0 = 0x51, | 243 | Config0 = 0x51, |
@@ -452,21 +460,69 @@ enum rtl_register_content { | |||
452 | CounterDump = 0x8, | 460 | CounterDump = 0x8, |
453 | }; | 461 | }; |
454 | 462 | ||
455 | enum desc_status_bit { | 463 | enum rtl_desc_bit { |
464 | /* First doubleword. */ | ||
456 | DescOwn = (1 << 31), /* Descriptor is owned by NIC */ | 465 | DescOwn = (1 << 31), /* Descriptor is owned by NIC */ |
457 | RingEnd = (1 << 30), /* End of descriptor ring */ | 466 | RingEnd = (1 << 30), /* End of descriptor ring */ |
458 | FirstFrag = (1 << 29), /* First segment of a packet */ | 467 | FirstFrag = (1 << 29), /* First segment of a packet */ |
459 | LastFrag = (1 << 28), /* Final segment of a packet */ | 468 | LastFrag = (1 << 28), /* Final segment of a packet */ |
469 | }; | ||
470 | |||
471 | /* Generic case. */ | ||
472 | enum rtl_tx_desc_bit { | ||
473 | /* First doubleword. */ | ||
474 | TD_LSO = (1 << 27), /* Large Send Offload */ | ||
475 | #define TD_MSS_MAX 0x07ffu /* MSS value */ | ||
460 | 476 | ||
461 | /* Tx private */ | 477 | /* Second doubleword. */ |
462 | LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ | 478 | TxVlanTag = (1 << 17), /* Add VLAN tag */ |
463 | MSSShift = 16, /* MSS value position */ | 479 | }; |
464 | MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ | 480 | |
465 | IPCS = (1 << 18), /* Calculate IP checksum */ | 481 | /* 8169, 8168b and 810x except 8102e. */ |
466 | UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ | 482 | enum rtl_tx_desc_bit_0 { |
467 | TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ | 483 | /* First doubleword. */ |
468 | TxVlanTag = (1 << 17), /* Add VLAN tag */ | 484 | #define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */ |
485 | TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */ | ||
486 | TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */ | ||
487 | TD0_IP_CS = (1 << 18), /* Calculate IP checksum */ | ||
488 | }; | ||
489 | |||
490 | /* 8102e, 8168c and beyond. */ | ||
491 | enum rtl_tx_desc_bit_1 { | ||
492 | /* Second doubleword. */ | ||
493 | #define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */ | ||
494 | TD1_IP_CS = (1 << 29), /* Calculate IP checksum */ | ||
495 | TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */ | ||
496 | TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ | ||
497 | }; | ||
469 | 498 | ||
499 | static const struct rtl_tx_desc_info { | ||
500 | struct { | ||
501 | u32 udp; | ||
502 | u32 tcp; | ||
503 | } checksum; | ||
504 | u16 mss_shift; | ||
505 | u16 opts_offset; | ||
506 | } tx_desc_info [] = { | ||
507 | [RTL_TD_0] = { | ||
508 | .checksum = { | ||
509 | .udp = TD0_IP_CS | TD0_UDP_CS, | ||
510 | .tcp = TD0_IP_CS | TD0_TCP_CS | ||
511 | }, | ||
512 | .mss_shift = TD0_MSS_SHIFT, | ||
513 | .opts_offset = 0 | ||
514 | }, | ||
515 | [RTL_TD_1] = { | ||
516 | .checksum = { | ||
517 | .udp = TD1_IP_CS | TD1_UDP_CS, | ||
518 | .tcp = TD1_IP_CS | TD1_TCP_CS | ||
519 | }, | ||
520 | .mss_shift = TD1_MSS_SHIFT, | ||
521 | .opts_offset = 1 | ||
522 | } | ||
523 | }; | ||
524 | |||
525 | enum rtl_rx_desc_bit { | ||
470 | /* Rx private */ | 526 | /* Rx private */ |
471 | PID1 = (1 << 18), /* Protocol ID bit 1/2 */ | 527 | PID1 = (1 << 18), /* Protocol ID bit 1/2 */ |
472 | PID0 = (1 << 17), /* Protocol ID bit 2/2 */ | 528 | PID0 = (1 << 17), /* Protocol ID bit 2/2 */ |
@@ -531,8 +587,8 @@ struct rtl8169_private { | |||
531 | struct napi_struct napi; | 587 | struct napi_struct napi; |
532 | spinlock_t lock; /* spin lock flag */ | 588 | spinlock_t lock; /* spin lock flag */ |
533 | u32 msg_enable; | 589 | u32 msg_enable; |
534 | int chipset; | 590 | u16 txd_version; |
535 | int mac_version; | 591 | u16 mac_version; |
536 | u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ | 592 | u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ |
537 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ | 593 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ |
538 | u32 dirty_rx; | 594 | u32 dirty_rx; |
@@ -1288,7 +1344,7 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1288 | 1344 | ||
1289 | static u32 rtl8169_fix_features(struct net_device *dev, u32 features) | 1345 | static u32 rtl8169_fix_features(struct net_device *dev, u32 features) |
1290 | { | 1346 | { |
1291 | if (dev->mtu > MSSMask) | 1347 | if (dev->mtu > TD_MSS_MAX) |
1292 | features &= ~NETIF_F_ALL_TSO; | 1348 | features &= ~NETIF_F_ALL_TSO; |
1293 | 1349 | ||
1294 | return features; | 1350 | return features; |
@@ -3194,7 +3250,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3194 | struct mii_if_info *mii; | 3250 | struct mii_if_info *mii; |
3195 | struct net_device *dev; | 3251 | struct net_device *dev; |
3196 | void __iomem *ioaddr; | 3252 | void __iomem *ioaddr; |
3197 | unsigned int i; | 3253 | int chipset, i; |
3198 | int rc; | 3254 | int rc; |
3199 | 3255 | ||
3200 | if (netif_msg_drv(&debug)) { | 3256 | if (netif_msg_drv(&debug)) { |
@@ -3336,7 +3392,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3336 | "driver bug, MAC version not found in rtl_chip_info\n"); | 3392 | "driver bug, MAC version not found in rtl_chip_info\n"); |
3337 | goto err_out_msi_4; | 3393 | goto err_out_msi_4; |
3338 | } | 3394 | } |
3339 | tp->chipset = i; | 3395 | chipset = i; |
3396 | tp->txd_version = rtl_chip_info[chipset].txd_version; | ||
3340 | 3397 | ||
3341 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 3398 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
3342 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | 3399 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); |
@@ -3413,8 +3470,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3413 | pci_set_drvdata(pdev, dev); | 3470 | pci_set_drvdata(pdev, dev); |
3414 | 3471 | ||
3415 | netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", | 3472 | netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", |
3416 | rtl_chip_info[tp->chipset].name, | 3473 | rtl_chip_info[chipset].name, dev->base_addr, dev->dev_addr, |
3417 | dev->base_addr, dev->dev_addr, | ||
3418 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); | 3474 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); |
3419 | 3475 | ||
3420 | if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || | 3476 | if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || |
@@ -3572,7 +3628,7 @@ static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) | |||
3572 | void __iomem *ioaddr = tp->mmio_addr; | 3628 | void __iomem *ioaddr = tp->mmio_addr; |
3573 | u32 cfg = rtl8169_rx_config; | 3629 | u32 cfg = rtl8169_rx_config; |
3574 | 3630 | ||
3575 | cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); | 3631 | cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); |
3576 | RTL_W32(RxConfig, cfg); | 3632 | RTL_W32(RxConfig, cfg); |
3577 | 3633 | ||
3578 | /* Set DMA burst size and Interframe Gap Time */ | 3634 | /* Set DMA burst size and Interframe Gap Time */ |
@@ -4564,7 +4620,7 @@ static void rtl8169_tx_timeout(struct net_device *dev) | |||
4564 | } | 4620 | } |
4565 | 4621 | ||
4566 | static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, | 4622 | static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, |
4567 | u32 opts1) | 4623 | u32 *opts) |
4568 | { | 4624 | { |
4569 | struct skb_shared_info *info = skb_shinfo(skb); | 4625 | struct skb_shared_info *info = skb_shinfo(skb); |
4570 | unsigned int cur_frag, entry; | 4626 | unsigned int cur_frag, entry; |
@@ -4592,9 +4648,11 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, | |||
4592 | } | 4648 | } |
4593 | 4649 | ||
4594 | /* anti gcc 2.95.3 bugware (sic) */ | 4650 | /* anti gcc 2.95.3 bugware (sic) */ |
4595 | status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); | 4651 | status = opts[0] | len | |
4652 | (RingEnd * !((entry + 1) % NUM_TX_DESC)); | ||
4596 | 4653 | ||
4597 | txd->opts1 = cpu_to_le32(status); | 4654 | txd->opts1 = cpu_to_le32(status); |
4655 | txd->opts2 = cpu_to_le32(opts[1]); | ||
4598 | txd->addr = cpu_to_le64(mapping); | 4656 | txd->addr = cpu_to_le64(mapping); |
4599 | 4657 | ||
4600 | tp->tx_skb[entry].len = len; | 4658 | tp->tx_skb[entry].len = len; |
@@ -4612,23 +4670,26 @@ err_out: | |||
4612 | return -EIO; | 4670 | return -EIO; |
4613 | } | 4671 | } |
4614 | 4672 | ||
4615 | static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) | 4673 | static inline void rtl8169_tso_csum(struct rtl8169_private *tp, |
4674 | struct sk_buff *skb, u32 *opts) | ||
4616 | { | 4675 | { |
4676 | const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; | ||
4617 | u32 mss = skb_shinfo(skb)->gso_size; | 4677 | u32 mss = skb_shinfo(skb)->gso_size; |
4678 | int offset = info->opts_offset; | ||
4618 | 4679 | ||
4619 | if (mss) | 4680 | if (mss) { |
4620 | return LargeSend | ((mss & MSSMask) << MSSShift); | 4681 | opts[0] |= TD_LSO; |
4621 | 4682 | opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift; | |
4622 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 4683 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
4623 | const struct iphdr *ip = ip_hdr(skb); | 4684 | const struct iphdr *ip = ip_hdr(skb); |
4624 | 4685 | ||
4625 | if (ip->protocol == IPPROTO_TCP) | 4686 | if (ip->protocol == IPPROTO_TCP) |
4626 | return IPCS | TCPCS; | 4687 | opts[offset] |= info->checksum.tcp; |
4627 | else if (ip->protocol == IPPROTO_UDP) | 4688 | else if (ip->protocol == IPPROTO_UDP) |
4628 | return IPCS | UDPCS; | 4689 | opts[offset] |= info->checksum.udp; |
4629 | WARN_ON(1); /* we need a WARN() */ | 4690 | else |
4691 | WARN_ON_ONCE(1); | ||
4630 | } | 4692 | } |
4631 | return 0; | ||
4632 | } | 4693 | } |
4633 | 4694 | ||
4634 | static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | 4695 | static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
@@ -4641,7 +4702,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
4641 | struct device *d = &tp->pci_dev->dev; | 4702 | struct device *d = &tp->pci_dev->dev; |
4642 | dma_addr_t mapping; | 4703 | dma_addr_t mapping; |
4643 | u32 status, len; | 4704 | u32 status, len; |
4644 | u32 opts1; | 4705 | u32 opts[2]; |
4645 | int frags; | 4706 | int frags; |
4646 | 4707 | ||
4647 | if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { | 4708 | if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { |
@@ -4662,24 +4723,28 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
4662 | 4723 | ||
4663 | tp->tx_skb[entry].len = len; | 4724 | tp->tx_skb[entry].len = len; |
4664 | txd->addr = cpu_to_le64(mapping); | 4725 | txd->addr = cpu_to_le64(mapping); |
4665 | txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); | ||
4666 | 4726 | ||
4667 | opts1 = DescOwn | rtl8169_tso_csum(skb, dev); | 4727 | opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); |
4728 | opts[0] = DescOwn; | ||
4668 | 4729 | ||
4669 | frags = rtl8169_xmit_frags(tp, skb, opts1); | 4730 | rtl8169_tso_csum(tp, skb, opts); |
4731 | |||
4732 | frags = rtl8169_xmit_frags(tp, skb, opts); | ||
4670 | if (frags < 0) | 4733 | if (frags < 0) |
4671 | goto err_dma_1; | 4734 | goto err_dma_1; |
4672 | else if (frags) | 4735 | else if (frags) |
4673 | opts1 |= FirstFrag; | 4736 | opts[0] |= FirstFrag; |
4674 | else { | 4737 | else { |
4675 | opts1 |= FirstFrag | LastFrag; | 4738 | opts[0] |= FirstFrag | LastFrag; |
4676 | tp->tx_skb[entry].skb = skb; | 4739 | tp->tx_skb[entry].skb = skb; |
4677 | } | 4740 | } |
4678 | 4741 | ||
4742 | txd->opts2 = cpu_to_le32(opts[1]); | ||
4743 | |||
4679 | wmb(); | 4744 | wmb(); |
4680 | 4745 | ||
4681 | /* anti gcc 2.95.3 bugware (sic) */ | 4746 | /* anti gcc 2.95.3 bugware (sic) */ |
4682 | status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); | 4747 | status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); |
4683 | txd->opts1 = cpu_to_le32(status); | 4748 | txd->opts1 = cpu_to_le32(status); |
4684 | 4749 | ||
4685 | tp->cur_tx += frags + 1; | 4750 | tp->cur_tx += frags + 1; |
@@ -5167,7 +5232,7 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
5167 | spin_lock_irqsave(&tp->lock, flags); | 5232 | spin_lock_irqsave(&tp->lock, flags); |
5168 | 5233 | ||
5169 | tmp = rtl8169_rx_config | rx_mode | | 5234 | tmp = rtl8169_rx_config | rx_mode | |
5170 | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); | 5235 | (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); |
5171 | 5236 | ||
5172 | if (tp->mac_version > RTL_GIGA_MAC_VER_06) { | 5237 | if (tp->mac_version > RTL_GIGA_MAC_VER_06) { |
5173 | u32 data = mc_filter[0]; | 5238 | u32 data = mc_filter[0]; |