aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2010-02-07 01:28:36 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-10 20:56:28 -0500
commit375c568844e49d292885c7485d4a255f71680e56 (patch)
treeb34b93a191692d7cf0d28b6d3a1d3e8957dbcfa2
parentacd12dde26eef5186a9d2ead9399d136932d2398 (diff)
sky2: receive checksum refactoring
Break the largish case for handling receive checksum into a separate function, and if there is a problem use dev_XXX routines to show which hardware is the problem. Turn one corner case into a BUG(). This only happens if the driver is expecting one behavior but the chip does the old behavior; only ever saw this when bringing up a new chip type and driver was buggy. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sky2.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 1aa1f3316702..478288b8bc21 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2484,6 +2484,32 @@ static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
2484 } 2484 }
2485} 2485}
2486 2486
2487static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
2488{
2489 /* If this happens then driver assuming wrong format for chip type */
2490 BUG_ON(sky2->hw->flags & SKY2_HW_NEW_LE);
2491
2492 /* Both checksum counters are programmed to start at
2493 * the same offset, so unless there is a problem they
2494 * should match. This failure is an early indication that
2495 * hardware receive checksumming won't work.
2496 */
2497 if (likely((u16)(status >> 16) == (u16)status)) {
2498 struct sk_buff *skb = sky2->rx_ring[sky2->rx_next].skb;
2499 skb->ip_summed = CHECKSUM_COMPLETE;
2500 skb->csum = le16_to_cpu(status);
2501 } else {
2502 dev_notice(&sky2->hw->pdev->dev,
2503 "%s: receive checksum problem (status = %#x)\n",
2504 sky2->netdev->name, status);
2505
2506 /* Disable checksum offload */
2507 sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
2508 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
2509 BMU_DIS_RX_CHKSUM);
2510 }
2511}
2512
2487/* Process status response ring */ 2513/* Process status response ring */
2488static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) 2514static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2489{ 2515{
@@ -2552,37 +2578,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2552 /* fall through */ 2578 /* fall through */
2553#endif 2579#endif
2554 case OP_RXCHKS: 2580 case OP_RXCHKS:
2555 if (!(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) 2581 if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
2556 break; 2582 sky2_rx_checksum(sky2, status);
2557
2558 /* If this happens then driver assuming wrong format */
2559 if (unlikely(hw->flags & SKY2_HW_NEW_LE)) {
2560 if (net_ratelimit())
2561 printk(KERN_NOTICE "%s: unexpected"
2562 " checksum status\n",
2563 dev->name);
2564 break;
2565 }
2566
2567 /* Both checksum counters are programmed to start at
2568 * the same offset, so unless there is a problem they
2569 * should match. This failure is an early indication that
2570 * hardware receive checksumming won't work.
2571 */
2572 if (likely(status >> 16 == (status & 0xffff))) {
2573 skb = sky2->rx_ring[sky2->rx_next].skb;
2574 skb->ip_summed = CHECKSUM_COMPLETE;
2575 skb->csum = le16_to_cpu(status);
2576 } else {
2577 printk(KERN_NOTICE PFX "%s: hardware receive "
2578 "checksum problem (status = %#x)\n",
2579 dev->name, status);
2580 sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
2581
2582 sky2_write32(sky2->hw,
2583 Q_ADDR(rxqaddr[port], Q_CSR),
2584 BMU_DIS_RX_CHKSUM);
2585 }
2586 break; 2583 break;
2587 2584
2588 case OP_TXINDEXLE: 2585 case OP_TXINDEXLE: