sky2: sky2 FE+ receive status workaround

The Yukon FE+ chip appears to have a hardware glitch that causes bogus
receive status values to be posted. The data in the packet is good, but
the status value is random garbage. As a temporary workaround until the
problem is better understood, implement the workaround the vendor driver
used of ignoring the status value on this chip.

Since this means trusting dodgy hardware values; add additional checking
of the receive packet length.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Stephen Hemminger and committed by Jeff Garzik 3b12e014 ff0ce684

+17 -11
+17 -11
drivers/net/sky2.c
··· 2148 sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; 2149 prefetch(sky2->rx_ring + sky2->rx_next); 2150 2151 if (status & GMR_FS_ANY_ERR) 2152 goto error; 2153 ··· 2168 2169 /* if length reported by DMA does not match PHY, packet was truncated */ 2170 if (length != count) 2171 - goto len_mismatch; 2172 2173 if (length < copybreak) 2174 skb = receive_copy(sky2, re, length); 2175 else ··· 2180 2181 return skb; 2182 2183 - len_mismatch: 2184 /* Truncation of overlength packets 2185 causes PHY length to not match MAC length */ 2186 ++sky2->net_stats.rx_length_errors; 2187 if (netif_msg_rx_err(sky2) && net_ratelimit()) 2188 - pr_info(PFX "%s: rx length mismatch: length %d status %#x\n", 2189 - dev->name, length, status); 2190 goto resubmit; 2191 2192 error: ··· 3946 sky2->netdev = dev; 3947 sky2->hw = hw; 3948 sky2->msg_enable = netif_msg_init(debug, default_msg); 3949 - 3950 - /* This chip has hardware problems that generates 3951 - * bogus PHY receive status so by default shut up the message. 3952 - */ 3953 - if (hw->chip_id == CHIP_ID_YUKON_FE_P && 3954 - hw->chip_rev == CHIP_REV_YU_FE2_A0) 3955 - sky2->msg_enable &= ~NETIF_MSG_RX_ERR; 3956 3957 /* Auto speed and flow control */ 3958 sky2->autoneg = AUTONEG_ENABLE;
··· 2148 sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; 2149 prefetch(sky2->rx_ring + sky2->rx_next); 2150 2151 + if (length < ETH_ZLEN || length > sky2->rx_data_size) 2152 + goto len_error; 2153 + 2154 + /* This chip has hardware problems that generates bogus status. 2155 + * So do only marginal checking and expect higher level protocols 2156 + * to handle crap frames. 2157 + */ 2158 + if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && 2159 + sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 && 2160 + length != count) 2161 + goto okay; 2162 + 2163 if (status & GMR_FS_ANY_ERR) 2164 goto error; 2165 ··· 2156 2157 /* if length reported by DMA does not match PHY, packet was truncated */ 2158 if (length != count) 2159 + goto len_error; 2160 2161 + okay: 2162 if (length < copybreak) 2163 skb = receive_copy(sky2, re, length); 2164 else ··· 2167 2168 return skb; 2169 2170 + len_error: 2171 /* Truncation of overlength packets 2172 causes PHY length to not match MAC length */ 2173 ++sky2->net_stats.rx_length_errors; 2174 if (netif_msg_rx_err(sky2) && net_ratelimit()) 2175 + pr_info(PFX "%s: rx length error: status %#x length %d\n", 2176 + dev->name, status, length); 2177 goto resubmit; 2178 2179 error: ··· 3933 sky2->netdev = dev; 3934 sky2->hw = hw; 3935 sky2->msg_enable = netif_msg_init(debug, default_msg); 3936 3937 /* Auto speed and flow control */ 3938 sky2->autoneg = AUTONEG_ENABLE;