diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2011-05-03 10:38:29 -0400 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2011-09-22 05:35:26 -0400 |
commit | d58d46b5d85139d18eb939aa7279c160bab70484 (patch) | |
tree | ff46d953d2434335f807ab1bccf63f259d8a9ff4 /drivers/net/ethernet | |
parent | deb9d93c89d311714a60809b28160e538e1cbb43 (diff) |
r8169: jumbo fixes.
- fix features : jumbo frames and checksumming can not be used at the
same time.
- introduce hw_jumbo_{enable / disable} helpers. Their content has been
creatively extracted from Realtek's own drivers. As an illustration,
it would be nice to know how/if the MaxTxPacketSize register operates
when the device can work with a 9k jumbo frame as its documentation
(8168c) can not be applied beyond ~7k.
- rtl_tx_performance_tweak is moved forward. No change.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 308 |
1 files changed, 252 insertions, 56 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 30bba23ce86..2ce60709a45 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -145,88 +145,110 @@ enum rtl_tx_desc_version { | |||
145 | RTL_TD_1 = 1, | 145 | RTL_TD_1 = 1, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | #define _R(NAME,TD,FW) \ | 148 | #define JUMBO_1K ETH_DATA_LEN |
149 | { .name = NAME, .txd_version = TD, .fw_name = FW } | 149 | #define JUMBO_4K (4*1024 - ETH_HLEN - 2) |
150 | #define JUMBO_6K (6*1024 - ETH_HLEN - 2) | ||
151 | #define JUMBO_7K (7*1024 - ETH_HLEN - 2) | ||
152 | #define JUMBO_9K (9*1024 - ETH_HLEN - 2) | ||
153 | |||
154 | #define _R(NAME,TD,FW,SZ,B) { \ | ||
155 | .name = NAME, \ | ||
156 | .txd_version = TD, \ | ||
157 | .fw_name = FW, \ | ||
158 | .jumbo_max = SZ, \ | ||
159 | .jumbo_tx_csum = B \ | ||
160 | } | ||
150 | 161 | ||
151 | static const struct { | 162 | static const struct { |
152 | const char *name; | 163 | const char *name; |
153 | enum rtl_tx_desc_version txd_version; | 164 | enum rtl_tx_desc_version txd_version; |
154 | const char *fw_name; | 165 | const char *fw_name; |
166 | u16 jumbo_max; | ||
167 | bool jumbo_tx_csum; | ||
155 | } rtl_chip_infos[] = { | 168 | } rtl_chip_infos[] = { |
156 | /* PCI devices. */ | 169 | /* PCI devices. */ |
157 | [RTL_GIGA_MAC_VER_01] = | 170 | [RTL_GIGA_MAC_VER_01] = |
158 | _R("RTL8169", RTL_TD_0, NULL), | 171 | _R("RTL8169", RTL_TD_0, NULL, JUMBO_7K, true), |
159 | [RTL_GIGA_MAC_VER_02] = | 172 | [RTL_GIGA_MAC_VER_02] = |
160 | _R("RTL8169s", RTL_TD_0, NULL), | 173 | _R("RTL8169s", RTL_TD_0, NULL, JUMBO_7K, true), |
161 | [RTL_GIGA_MAC_VER_03] = | 174 | [RTL_GIGA_MAC_VER_03] = |
162 | _R("RTL8110s", RTL_TD_0, NULL), | 175 | _R("RTL8110s", RTL_TD_0, NULL, JUMBO_7K, true), |
163 | [RTL_GIGA_MAC_VER_04] = | 176 | [RTL_GIGA_MAC_VER_04] = |
164 | _R("RTL8169sb/8110sb", RTL_TD_0, NULL), | 177 | _R("RTL8169sb/8110sb", RTL_TD_0, NULL, JUMBO_7K, true), |
165 | [RTL_GIGA_MAC_VER_05] = | 178 | [RTL_GIGA_MAC_VER_05] = |
166 | _R("RTL8169sc/8110sc", RTL_TD_0, NULL), | 179 | _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), |
167 | [RTL_GIGA_MAC_VER_06] = | 180 | [RTL_GIGA_MAC_VER_06] = |
168 | _R("RTL8169sc/8110sc", RTL_TD_0, NULL), | 181 | _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), |
169 | /* PCI-E devices. */ | 182 | /* PCI-E devices. */ |
170 | [RTL_GIGA_MAC_VER_07] = | 183 | [RTL_GIGA_MAC_VER_07] = |
171 | _R("RTL8102e", RTL_TD_1, NULL), | 184 | _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), |
172 | [RTL_GIGA_MAC_VER_08] = | 185 | [RTL_GIGA_MAC_VER_08] = |
173 | _R("RTL8102e", RTL_TD_1, NULL), | 186 | _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), |
174 | [RTL_GIGA_MAC_VER_09] = | 187 | [RTL_GIGA_MAC_VER_09] = |
175 | _R("RTL8102e", RTL_TD_1, NULL), | 188 | _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), |
176 | [RTL_GIGA_MAC_VER_10] = | 189 | [RTL_GIGA_MAC_VER_10] = |
177 | _R("RTL8101e", RTL_TD_0, NULL), | 190 | _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), |
178 | [RTL_GIGA_MAC_VER_11] = | 191 | [RTL_GIGA_MAC_VER_11] = |
179 | _R("RTL8168b/8111b", RTL_TD_0, NULL), | 192 | _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), |
180 | [RTL_GIGA_MAC_VER_12] = | 193 | [RTL_GIGA_MAC_VER_12] = |
181 | _R("RTL8168b/8111b", RTL_TD_0, NULL), | 194 | _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), |
182 | [RTL_GIGA_MAC_VER_13] = | 195 | [RTL_GIGA_MAC_VER_13] = |
183 | _R("RTL8101e", RTL_TD_0, NULL), | 196 | _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), |
184 | [RTL_GIGA_MAC_VER_14] = | 197 | [RTL_GIGA_MAC_VER_14] = |
185 | _R("RTL8100e", RTL_TD_0, NULL), | 198 | _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), |
186 | [RTL_GIGA_MAC_VER_15] = | 199 | [RTL_GIGA_MAC_VER_15] = |
187 | _R("RTL8100e", RTL_TD_0, NULL), | 200 | _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), |
188 | [RTL_GIGA_MAC_VER_16] = | 201 | [RTL_GIGA_MAC_VER_16] = |
189 | _R("RTL8101e", RTL_TD_0, NULL), | 202 | _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), |
190 | [RTL_GIGA_MAC_VER_17] = | 203 | [RTL_GIGA_MAC_VER_17] = |
191 | _R("RTL8168b/8111b", RTL_TD_0, NULL), | 204 | _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false), |
192 | [RTL_GIGA_MAC_VER_18] = | 205 | [RTL_GIGA_MAC_VER_18] = |
193 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL), | 206 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), |
194 | [RTL_GIGA_MAC_VER_19] = | 207 | [RTL_GIGA_MAC_VER_19] = |
195 | _R("RTL8168c/8111c", RTL_TD_1, NULL), | 208 | _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), |
196 | [RTL_GIGA_MAC_VER_20] = | 209 | [RTL_GIGA_MAC_VER_20] = |
197 | _R("RTL8168c/8111c", RTL_TD_1, NULL), | 210 | _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), |
198 | [RTL_GIGA_MAC_VER_21] = | 211 | [RTL_GIGA_MAC_VER_21] = |
199 | _R("RTL8168c/8111c", RTL_TD_1, NULL), | 212 | _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), |
200 | [RTL_GIGA_MAC_VER_22] = | 213 | [RTL_GIGA_MAC_VER_22] = |
201 | _R("RTL8168c/8111c", RTL_TD_1, NULL), | 214 | _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), |
202 | [RTL_GIGA_MAC_VER_23] = | 215 | [RTL_GIGA_MAC_VER_23] = |
203 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL), | 216 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), |
204 | [RTL_GIGA_MAC_VER_24] = | 217 | [RTL_GIGA_MAC_VER_24] = |
205 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL), | 218 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), |
206 | [RTL_GIGA_MAC_VER_25] = | 219 | [RTL_GIGA_MAC_VER_25] = |
207 | _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1), | 220 | _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1, |
221 | JUMBO_9K, false), | ||
208 | [RTL_GIGA_MAC_VER_26] = | 222 | [RTL_GIGA_MAC_VER_26] = |
209 | _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2), | 223 | _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2, |
224 | JUMBO_9K, false), | ||
210 | [RTL_GIGA_MAC_VER_27] = | 225 | [RTL_GIGA_MAC_VER_27] = |
211 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL), | 226 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), |
212 | [RTL_GIGA_MAC_VER_28] = | 227 | [RTL_GIGA_MAC_VER_28] = |
213 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL), | 228 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), |
214 | [RTL_GIGA_MAC_VER_29] = | 229 | [RTL_GIGA_MAC_VER_29] = |
215 | _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), | 230 | _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, |
231 | JUMBO_1K, true), | ||
216 | [RTL_GIGA_MAC_VER_30] = | 232 | [RTL_GIGA_MAC_VER_30] = |
217 | _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), | 233 | _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, |
234 | JUMBO_1K, true), | ||
218 | [RTL_GIGA_MAC_VER_31] = | 235 | [RTL_GIGA_MAC_VER_31] = |
219 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL), | 236 | _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), |
220 | [RTL_GIGA_MAC_VER_32] = | 237 | [RTL_GIGA_MAC_VER_32] = |
221 | _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1), | 238 | _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1, |
239 | JUMBO_9K, false), | ||
222 | [RTL_GIGA_MAC_VER_33] = | 240 | [RTL_GIGA_MAC_VER_33] = |
223 | _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2), | 241 | _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2, |
242 | JUMBO_9K, false), | ||
224 | [RTL_GIGA_MAC_VER_34] = | 243 | [RTL_GIGA_MAC_VER_34] = |
225 | _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3), | 244 | _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3, |
245 | JUMBO_9K, false), | ||
226 | [RTL_GIGA_MAC_VER_35] = | 246 | [RTL_GIGA_MAC_VER_35] = |
227 | _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_1), | 247 | _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_1, |
248 | JUMBO_9K, false), | ||
228 | [RTL_GIGA_MAC_VER_36] = | 249 | [RTL_GIGA_MAC_VER_36] = |
229 | _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_2) | 250 | _R("RTL8168f/8111f", RTL_TD_1, FIRMWARE_8168F_2, |
251 | JUMBO_9K, false), | ||
230 | }; | 252 | }; |
231 | #undef _R | 253 | #undef _R |
232 | 254 | ||
@@ -469,8 +491,12 @@ enum rtl_register_content { | |||
469 | /* Config3 register p.25 */ | 491 | /* Config3 register p.25 */ |
470 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ | 492 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ |
471 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ | 493 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ |
494 | Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ | ||
472 | Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ | 495 | Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ |
473 | 496 | ||
497 | /* Config4 register */ | ||
498 | Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */ | ||
499 | |||
474 | /* Config5 register p.27 */ | 500 | /* Config5 register p.27 */ |
475 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ | 501 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ |
476 | MWF = (1 << 5), /* Accept Multicast wakeup frame */ | 502 | MWF = (1 << 5), /* Accept Multicast wakeup frame */ |
@@ -679,6 +705,11 @@ struct rtl8169_private { | |||
679 | void (*up)(struct rtl8169_private *); | 705 | void (*up)(struct rtl8169_private *); |
680 | } pll_power_ops; | 706 | } pll_power_ops; |
681 | 707 | ||
708 | struct jumbo_ops { | ||
709 | void (*enable)(struct rtl8169_private *); | ||
710 | void (*disable)(struct rtl8169_private *); | ||
711 | } jumbo_ops; | ||
712 | |||
682 | int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); | 713 | int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); |
683 | int (*get_settings)(struct net_device *, struct ethtool_cmd *); | 714 | int (*get_settings)(struct net_device *, struct ethtool_cmd *); |
684 | void (*phy_reset_enable)(struct rtl8169_private *tp); | 715 | void (*phy_reset_enable)(struct rtl8169_private *tp); |
@@ -743,6 +774,19 @@ static void rtl8169_down(struct net_device *dev); | |||
743 | static void rtl8169_rx_clear(struct rtl8169_private *tp); | 774 | static void rtl8169_rx_clear(struct rtl8169_private *tp); |
744 | static int rtl8169_poll(struct napi_struct *napi, int budget); | 775 | static int rtl8169_poll(struct napi_struct *napi, int budget); |
745 | 776 | ||
777 | static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) | ||
778 | { | ||
779 | int cap = pci_pcie_cap(pdev); | ||
780 | |||
781 | if (cap) { | ||
782 | u16 ctl; | ||
783 | |||
784 | pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); | ||
785 | ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; | ||
786 | pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); | ||
787 | } | ||
788 | } | ||
789 | |||
746 | static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) | 790 | static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) |
747 | { | 791 | { |
748 | void __iomem *ioaddr = tp->mmio_addr; | 792 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -1511,9 +1555,15 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1511 | 1555 | ||
1512 | static u32 rtl8169_fix_features(struct net_device *dev, u32 features) | 1556 | static u32 rtl8169_fix_features(struct net_device *dev, u32 features) |
1513 | { | 1557 | { |
1558 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1559 | |||
1514 | if (dev->mtu > TD_MSS_MAX) | 1560 | if (dev->mtu > TD_MSS_MAX) |
1515 | features &= ~NETIF_F_ALL_TSO; | 1561 | features &= ~NETIF_F_ALL_TSO; |
1516 | 1562 | ||
1563 | if (dev->mtu > JUMBO_1K && | ||
1564 | !rtl_chip_infos[tp->mac_version].jumbo_tx_csum) | ||
1565 | features &= ~NETIF_F_IP_CSUM; | ||
1566 | |||
1517 | return features; | 1567 | return features; |
1518 | } | 1568 | } |
1519 | 1569 | ||
@@ -3608,8 +3658,8 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) | |||
3608 | r8168_phy_power_up(tp); | 3658 | r8168_phy_power_up(tp); |
3609 | } | 3659 | } |
3610 | 3660 | ||
3611 | static void rtl_pll_power_op(struct rtl8169_private *tp, | 3661 | static void rtl_generic_op(struct rtl8169_private *tp, |
3612 | void (*op)(struct rtl8169_private *)) | 3662 | void (*op)(struct rtl8169_private *)) |
3613 | { | 3663 | { |
3614 | if (op) | 3664 | if (op) |
3615 | op(tp); | 3665 | op(tp); |
@@ -3617,12 +3667,12 @@ static void rtl_pll_power_op(struct rtl8169_private *tp, | |||
3617 | 3667 | ||
3618 | static void rtl_pll_power_down(struct rtl8169_private *tp) | 3668 | static void rtl_pll_power_down(struct rtl8169_private *tp) |
3619 | { | 3669 | { |
3620 | rtl_pll_power_op(tp, tp->pll_power_ops.down); | 3670 | rtl_generic_op(tp, tp->pll_power_ops.down); |
3621 | } | 3671 | } |
3622 | 3672 | ||
3623 | static void rtl_pll_power_up(struct rtl8169_private *tp) | 3673 | static void rtl_pll_power_up(struct rtl8169_private *tp) |
3624 | { | 3674 | { |
3625 | rtl_pll_power_op(tp, tp->pll_power_ops.up); | 3675 | rtl_generic_op(tp, tp->pll_power_ops.up); |
3626 | } | 3676 | } |
3627 | 3677 | ||
3628 | static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) | 3678 | static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) |
@@ -3713,6 +3763,150 @@ static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) | |||
3713 | tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; | 3763 | tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; |
3714 | } | 3764 | } |
3715 | 3765 | ||
3766 | static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3767 | { | ||
3768 | rtl_generic_op(tp, tp->jumbo_ops.enable); | ||
3769 | } | ||
3770 | |||
3771 | static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3772 | { | ||
3773 | rtl_generic_op(tp, tp->jumbo_ops.disable); | ||
3774 | } | ||
3775 | |||
3776 | static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3777 | { | ||
3778 | void __iomem *ioaddr = tp->mmio_addr; | ||
3779 | |||
3780 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); | ||
3781 | RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); | ||
3782 | rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); | ||
3783 | } | ||
3784 | |||
3785 | static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3786 | { | ||
3787 | void __iomem *ioaddr = tp->mmio_addr; | ||
3788 | |||
3789 | RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); | ||
3790 | RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); | ||
3791 | rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
3792 | } | ||
3793 | |||
3794 | static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3795 | { | ||
3796 | void __iomem *ioaddr = tp->mmio_addr; | ||
3797 | |||
3798 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); | ||
3799 | } | ||
3800 | |||
3801 | static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3802 | { | ||
3803 | void __iomem *ioaddr = tp->mmio_addr; | ||
3804 | |||
3805 | RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); | ||
3806 | } | ||
3807 | |||
3808 | static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3809 | { | ||
3810 | void __iomem *ioaddr = tp->mmio_addr; | ||
3811 | struct pci_dev *pdev = tp->pci_dev; | ||
3812 | |||
3813 | RTL_W8(MaxTxPacketSize, 0x3f); | ||
3814 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); | ||
3815 | RTL_W8(Config4, RTL_R8(Config4) | 0x01); | ||
3816 | pci_write_config_byte(pdev, 0x79, 0x20); | ||
3817 | } | ||
3818 | |||
3819 | static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3820 | { | ||
3821 | void __iomem *ioaddr = tp->mmio_addr; | ||
3822 | struct pci_dev *pdev = tp->pci_dev; | ||
3823 | |||
3824 | RTL_W8(MaxTxPacketSize, 0x0c); | ||
3825 | RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); | ||
3826 | RTL_W8(Config4, RTL_R8(Config4) & ~0x01); | ||
3827 | pci_write_config_byte(pdev, 0x79, 0x50); | ||
3828 | } | ||
3829 | |||
3830 | static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3831 | { | ||
3832 | rtl_tx_performance_tweak(tp->pci_dev, | ||
3833 | (0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
3834 | } | ||
3835 | |||
3836 | static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3837 | { | ||
3838 | rtl_tx_performance_tweak(tp->pci_dev, | ||
3839 | (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
3840 | } | ||
3841 | |||
3842 | static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) | ||
3843 | { | ||
3844 | void __iomem *ioaddr = tp->mmio_addr; | ||
3845 | |||
3846 | r8168b_0_hw_jumbo_enable(tp); | ||
3847 | |||
3848 | RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); | ||
3849 | } | ||
3850 | |||
3851 | static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) | ||
3852 | { | ||
3853 | void __iomem *ioaddr = tp->mmio_addr; | ||
3854 | |||
3855 | r8168b_0_hw_jumbo_disable(tp); | ||
3856 | |||
3857 | RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); | ||
3858 | } | ||
3859 | |||
3860 | static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) | ||
3861 | { | ||
3862 | struct jumbo_ops *ops = &tp->jumbo_ops; | ||
3863 | |||
3864 | switch (tp->mac_version) { | ||
3865 | case RTL_GIGA_MAC_VER_11: | ||
3866 | ops->disable = r8168b_0_hw_jumbo_disable; | ||
3867 | ops->enable = r8168b_0_hw_jumbo_enable; | ||
3868 | break; | ||
3869 | case RTL_GIGA_MAC_VER_12: | ||
3870 | case RTL_GIGA_MAC_VER_17: | ||
3871 | ops->disable = r8168b_1_hw_jumbo_disable; | ||
3872 | ops->enable = r8168b_1_hw_jumbo_enable; | ||
3873 | break; | ||
3874 | case RTL_GIGA_MAC_VER_18: /* Wild guess. Needs info from Realtek. */ | ||
3875 | case RTL_GIGA_MAC_VER_19: | ||
3876 | case RTL_GIGA_MAC_VER_20: | ||
3877 | case RTL_GIGA_MAC_VER_21: /* Wild guess. Needs info from Realtek. */ | ||
3878 | case RTL_GIGA_MAC_VER_22: | ||
3879 | case RTL_GIGA_MAC_VER_23: | ||
3880 | case RTL_GIGA_MAC_VER_24: | ||
3881 | case RTL_GIGA_MAC_VER_25: | ||
3882 | case RTL_GIGA_MAC_VER_26: | ||
3883 | ops->disable = r8168c_hw_jumbo_disable; | ||
3884 | ops->enable = r8168c_hw_jumbo_enable; | ||
3885 | break; | ||
3886 | case RTL_GIGA_MAC_VER_27: | ||
3887 | case RTL_GIGA_MAC_VER_28: | ||
3888 | ops->disable = r8168dp_hw_jumbo_disable; | ||
3889 | ops->enable = r8168dp_hw_jumbo_enable; | ||
3890 | break; | ||
3891 | case RTL_GIGA_MAC_VER_31: /* Wild guess. Needs info from Realtek. */ | ||
3892 | case RTL_GIGA_MAC_VER_32: | ||
3893 | case RTL_GIGA_MAC_VER_33: | ||
3894 | case RTL_GIGA_MAC_VER_34: | ||
3895 | ops->disable = r8168e_hw_jumbo_disable; | ||
3896 | ops->enable = r8168e_hw_jumbo_enable; | ||
3897 | break; | ||
3898 | |||
3899 | /* | ||
3900 | * No action needed for jumbo frames with 8169. | ||
3901 | * No jumbo for 810x at all. | ||
3902 | */ | ||
3903 | default: | ||
3904 | ops->disable = NULL; | ||
3905 | ops->enable = NULL; | ||
3906 | break; | ||
3907 | } | ||
3908 | } | ||
3909 | |||
3716 | static void rtl_hw_reset(struct rtl8169_private *tp) | 3910 | static void rtl_hw_reset(struct rtl8169_private *tp) |
3717 | { | 3911 | { |
3718 | void __iomem *ioaddr = tp->mmio_addr; | 3912 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -3857,6 +4051,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3857 | 4051 | ||
3858 | rtl_init_mdio_ops(tp); | 4052 | rtl_init_mdio_ops(tp); |
3859 | rtl_init_pll_power_ops(tp); | 4053 | rtl_init_pll_power_ops(tp); |
4054 | rtl_init_jumbo_ops(tp); | ||
3860 | 4055 | ||
3861 | rtl8169_print_mac_version(tp); | 4056 | rtl8169_print_mac_version(tp); |
3862 | 4057 | ||
@@ -3940,6 +4135,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3940 | netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", | 4135 | netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", |
3941 | rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr, | 4136 | rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr, |
3942 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); | 4137 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); |
4138 | if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) { | ||
4139 | netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, " | ||
4140 | "tx checksumming: %s]\n", | ||
4141 | rtl_chip_infos[chipset].jumbo_max, | ||
4142 | rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko"); | ||
4143 | } | ||
3943 | 4144 | ||
3944 | if (tp->mac_version == RTL_GIGA_MAC_VER_27 || | 4145 | if (tp->mac_version == RTL_GIGA_MAC_VER_27 || |
3945 | tp->mac_version == RTL_GIGA_MAC_VER_28 || | 4146 | tp->mac_version == RTL_GIGA_MAC_VER_28 || |
@@ -4296,19 +4497,6 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
4296 | RTL_W16(IntrMask, tp->intr_event); | 4497 | RTL_W16(IntrMask, tp->intr_event); |
4297 | } | 4498 | } |
4298 | 4499 | ||
4299 | static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) | ||
4300 | { | ||
4301 | int cap = pci_pcie_cap(pdev); | ||
4302 | |||
4303 | if (cap) { | ||
4304 | u16 ctl; | ||
4305 | |||
4306 | pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); | ||
4307 | ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; | ||
4308 | pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); | ||
4309 | } | ||
4310 | } | ||
4311 | |||
4312 | static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) | 4500 | static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) |
4313 | { | 4501 | { |
4314 | u32 csi; | 4502 | u32 csi; |
@@ -4936,9 +5124,17 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
4936 | 5124 | ||
4937 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) | 5125 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) |
4938 | { | 5126 | { |
4939 | if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) | 5127 | struct rtl8169_private *tp = netdev_priv(dev); |
5128 | |||
5129 | if (new_mtu < ETH_ZLEN || | ||
5130 | new_mtu > rtl_chip_infos[tp->mac_version].jumbo_max) | ||
4940 | return -EINVAL; | 5131 | return -EINVAL; |
4941 | 5132 | ||
5133 | if (new_mtu > ETH_DATA_LEN) | ||
5134 | rtl_hw_jumbo_enable(tp); | ||
5135 | else | ||
5136 | rtl_hw_jumbo_disable(tp); | ||
5137 | |||
4942 | dev->mtu = new_mtu; | 5138 | dev->mtu = new_mtu; |
4943 | netdev_update_features(dev); | 5139 | netdev_update_features(dev); |
4944 | 5140 | ||