Commit 0fde6e3b authored by David S. Miller's avatar David S. Miller

Merge branch 'r8169-series-with-improvements'

Heiner Kallweit says:

====================
r8169: series with improvements

Again a series with few improvements.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7070eea5 773235f4
...@@ -75,6 +75,8 @@ ...@@ -75,6 +75,8 @@
#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
#define OCP_STD_PHY_BASE 0xa400
#define RTL_CFG_NO_GBIT 1 #define RTL_CFG_NO_GBIT 1
/* write/read MMIO register */ /* write/read MMIO register */
...@@ -847,8 +849,6 @@ static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask, ...@@ -847,8 +849,6 @@ static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask,
r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); r8168_mac_ocp_write(tp, reg, (data & ~mask) | set);
} }
#define OCP_STD_PHY_BASE 0xa400
static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value)
{ {
if (reg == 0x1f) { if (reg == 0x1f) {
...@@ -2397,6 +2397,8 @@ static void rtl_pll_power_up(struct rtl8169_private *tp) ...@@ -2397,6 +2397,8 @@ static void rtl_pll_power_up(struct rtl8169_private *tp)
static void rtl_init_rxcfg(struct rtl8169_private *tp) static void rtl_init_rxcfg(struct rtl8169_private *tp)
{ {
u32 vlan;
switch (tp->mac_version) { switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17:
...@@ -2411,8 +2413,9 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) ...@@ -2411,8 +2413,9 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
break; break;
case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61:
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_VLAN_8125 | /* VLAN flags are controlled by NETIF_F_HW_VLAN_CTAG_RX */
RX_DMA_BURST); vlan = RTL_R32(tp, RxConfig) & RX_VLAN_8125;
RTL_W32(tp, RxConfig, vlan | RX_FETCH_DFLT_8125 | RX_DMA_BURST);
break; break;
default: default:
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
...@@ -4124,25 +4127,20 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, ...@@ -4124,25 +4127,20 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
struct sk_buff *skb, u32 *opts) struct sk_buff *skb, u32 *opts)
{ {
u32 transport_offset = (u32)skb_transport_offset(skb); u32 transport_offset = (u32)skb_transport_offset(skb);
u32 mss = skb_shinfo(skb)->gso_size; struct skb_shared_info *shinfo = skb_shinfo(skb);
u32 mss = shinfo->gso_size;
if (mss) { if (mss) {
switch (vlan_get_protocol(skb)) { if (shinfo->gso_type & SKB_GSO_TCPV4) {
case htons(ETH_P_IP):
opts[0] |= TD1_GTSENV4; opts[0] |= TD1_GTSENV4;
break; } else if (shinfo->gso_type & SKB_GSO_TCPV6) {
case htons(ETH_P_IPV6):
if (skb_cow_head(skb, 0)) if (skb_cow_head(skb, 0))
return false; return false;
tcp_v6_gso_csum_prep(skb); tcp_v6_gso_csum_prep(skb);
opts[0] |= TD1_GTSENV6; opts[0] |= TD1_GTSENV6;
break; } else {
default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
break;
} }
opts[0] |= transport_offset << GTTCPHO_SHIFT; opts[0] |= transport_offset << GTTCPHO_SHIFT;
...@@ -4308,6 +4306,37 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, ...@@ -4308,6 +4306,37 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
static unsigned int rtl_last_frag_len(struct sk_buff *skb)
{
struct skb_shared_info *info = skb_shinfo(skb);
unsigned int nr_frags = info->nr_frags;
if (!nr_frags)
return UINT_MAX;
return skb_frag_size(info->frags + nr_frags - 1);
}
/* Workaround for hw issues with TSO on RTL8168evl */
static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb,
netdev_features_t features)
{
/* IPv4 header has options field */
if (vlan_get_protocol(skb) == htons(ETH_P_IP) &&
ip_hdrlen(skb) > sizeof(struct iphdr))
features &= ~NETIF_F_ALL_TSO;
/* IPv4 TCP header has options field */
else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 &&
tcp_hdrlen(skb) > sizeof(struct tcphdr))
features &= ~NETIF_F_ALL_TSO;
else if (rtl_last_frag_len(skb) <= 6)
features &= ~NETIF_F_ALL_TSO;
return features;
}
static netdev_features_t rtl8169_features_check(struct sk_buff *skb, static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
netdev_features_t features) netdev_features_t features)
...@@ -4316,6 +4345,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, ...@@ -4316,6 +4345,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
if (skb_is_gso(skb)) { if (skb_is_gso(skb)) {
if (tp->mac_version == RTL_GIGA_MAC_VER_34)
features = rtl8168evl_fix_tso(skb, features);
if (transport_offset > GTTCPHO_MAX && if (transport_offset > GTTCPHO_MAX &&
rtl_chip_supports_csum_v2(tp)) rtl_chip_supports_csum_v2(tp))
features &= ~NETIF_F_ALL_TSO; features &= ~NETIF_F_ALL_TSO;
...@@ -5189,8 +5221,6 @@ static int r8169_mdio_register(struct rtl8169_private *tp) ...@@ -5189,8 +5221,6 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
static void rtl_hw_init_8168g(struct rtl8169_private *tp) static void rtl_hw_init_8168g(struct rtl8169_private *tp)
{ {
tp->ocp_base = OCP_STD_PHY_BASE;
RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN);
if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42)) if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42))
...@@ -5215,8 +5245,6 @@ static void rtl_hw_init_8168g(struct rtl8169_private *tp) ...@@ -5215,8 +5245,6 @@ static void rtl_hw_init_8168g(struct rtl8169_private *tp)
static void rtl_hw_init_8125(struct rtl8169_private *tp) static void rtl_hw_init_8125(struct rtl8169_private *tp)
{ {
tp->ocp_base = OCP_STD_PHY_BASE;
RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN);
if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42))
...@@ -5353,6 +5381,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -5353,6 +5381,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
tp->eee_adv = -1; tp->eee_adv = -1;
tp->ocp_base = OCP_STD_PHY_BASE;
/* Get the *optional* external "ether_clk" used on some boards */ /* Get the *optional* external "ether_clk" used on some boards */
rc = rtl_get_ether_clk(tp); rc = rtl_get_ether_clk(tp);
...@@ -5443,14 +5472,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -5443,14 +5472,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
NETIF_F_HIGHDMA;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
tp->cp_cmd |= RxChkSum;
/* RTL8125 uses register RxConfig for VLAN offloading config */
if (!rtl_is_8125(tp))
tp->cp_cmd |= RxVlan;
/* /*
* Pretend we are using VLANs; This bypasses a nasty bug where * Pretend we are using VLANs; This bypasses a nasty bug where
* Interrupts stop flowing on high load on 8110SCd controllers. * Interrupts stop flowing on high load on 8110SCd controllers.
...@@ -5482,6 +5506,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -5482,6 +5506,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->hw_features |= NETIF_F_RXALL; dev->hw_features |= NETIF_F_RXALL;
dev->hw_features |= NETIF_F_RXFCS; dev->hw_features |= NETIF_F_RXFCS;
/* configure chip for default features */
rtl8169_set_features(dev, dev->features);
jumbo_max = rtl_jumbo_max(tp); jumbo_max = rtl_jumbo_max(tp);
if (jumbo_max) if (jumbo_max)
dev->max_mtu = jumbo_max; dev->max_mtu = jumbo_max;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment