diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/r8169.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index c59507f8a76b..b3768d844747 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev) | |||
1585 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 1585 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
1586 | RTL_W8(EarlyTxThres, EarlyTxThld); | 1586 | RTL_W8(EarlyTxThres, EarlyTxThld); |
1587 | 1587 | ||
1588 | /* For gigabit rtl8169, MTU + header + CRC + VLAN */ | 1588 | /* Low hurts. Let's disable the filtering. */ |
1589 | RTL_W16(RxMaxSize, tp->rx_buf_sz); | 1589 | RTL_W16(RxMaxSize, 16383); |
1590 | 1590 | ||
1591 | /* Set Rx Config register */ | 1591 | /* Set Rx Config register */ |
1592 | i = rtl8169_rx_config | | 1592 | i = rtl8169_rx_config | |
@@ -2127,6 +2127,11 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, | |||
2127 | } | 2127 | } |
2128 | } | 2128 | } |
2129 | 2129 | ||
2130 | static inline int rtl8169_fragmented_frame(u32 status) | ||
2131 | { | ||
2132 | return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); | ||
2133 | } | ||
2134 | |||
2130 | static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) | 2135 | static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) |
2131 | { | 2136 | { |
2132 | u32 opts1 = le32_to_cpu(desc->opts1); | 2137 | u32 opts1 = le32_to_cpu(desc->opts1); |
@@ -2177,27 +2182,41 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, | |||
2177 | 2182 | ||
2178 | while (rx_left > 0) { | 2183 | while (rx_left > 0) { |
2179 | unsigned int entry = cur_rx % NUM_RX_DESC; | 2184 | unsigned int entry = cur_rx % NUM_RX_DESC; |
2185 | struct RxDesc *desc = tp->RxDescArray + entry; | ||
2180 | u32 status; | 2186 | u32 status; |
2181 | 2187 | ||
2182 | rmb(); | 2188 | rmb(); |
2183 | status = le32_to_cpu(tp->RxDescArray[entry].opts1); | 2189 | status = le32_to_cpu(desc->opts1); |
2184 | 2190 | ||
2185 | if (status & DescOwn) | 2191 | if (status & DescOwn) |
2186 | break; | 2192 | break; |
2187 | if (status & RxRES) { | 2193 | if (status & RxRES) { |
2188 | printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); | 2194 | printk(KERN_INFO "%s: Rx ERROR. status = %08x\n", |
2195 | dev->name, status); | ||
2189 | tp->stats.rx_errors++; | 2196 | tp->stats.rx_errors++; |
2190 | if (status & (RxRWT | RxRUNT)) | 2197 | if (status & (RxRWT | RxRUNT)) |
2191 | tp->stats.rx_length_errors++; | 2198 | tp->stats.rx_length_errors++; |
2192 | if (status & RxCRC) | 2199 | if (status & RxCRC) |
2193 | tp->stats.rx_crc_errors++; | 2200 | tp->stats.rx_crc_errors++; |
2201 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | ||
2194 | } else { | 2202 | } else { |
2195 | struct RxDesc *desc = tp->RxDescArray + entry; | ||
2196 | struct sk_buff *skb = tp->Rx_skbuff[entry]; | 2203 | struct sk_buff *skb = tp->Rx_skbuff[entry]; |
2197 | int pkt_size = (status & 0x00001FFF) - 4; | 2204 | int pkt_size = (status & 0x00001FFF) - 4; |
2198 | void (*pci_action)(struct pci_dev *, dma_addr_t, | 2205 | void (*pci_action)(struct pci_dev *, dma_addr_t, |
2199 | size_t, int) = pci_dma_sync_single_for_device; | 2206 | size_t, int) = pci_dma_sync_single_for_device; |
2200 | 2207 | ||
2208 | /* | ||
2209 | * The driver does not support incoming fragmented | ||
2210 | * frames. They are seen as a symptom of over-mtu | ||
2211 | * sized frames. | ||
2212 | */ | ||
2213 | if (unlikely(rtl8169_fragmented_frame(status))) { | ||
2214 | tp->stats.rx_dropped++; | ||
2215 | tp->stats.rx_length_errors++; | ||
2216 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | ||
2217 | goto move_on; | ||
2218 | } | ||
2219 | |||
2201 | rtl8169_rx_csum(skb, desc); | 2220 | rtl8169_rx_csum(skb, desc); |
2202 | 2221 | ||
2203 | pci_dma_sync_single_for_cpu(tp->pci_dev, | 2222 | pci_dma_sync_single_for_cpu(tp->pci_dev, |
@@ -2224,7 +2243,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, | |||
2224 | tp->stats.rx_bytes += pkt_size; | 2243 | tp->stats.rx_bytes += pkt_size; |
2225 | tp->stats.rx_packets++; | 2244 | tp->stats.rx_packets++; |
2226 | } | 2245 | } |
2227 | 2246 | move_on: | |
2228 | cur_rx++; | 2247 | cur_rx++; |
2229 | rx_left--; | 2248 | rx_left--; |
2230 | } | 2249 | } |