diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2009-06-17 03:30:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-17 21:46:52 -0400 |
commit | bf15fe996e050332c018cf63dd51288b081cc556 (patch) | |
tree | 60aa23279726e73f4649a0039e9f536f1ef72e1b | |
parent | 6c83504ff24f4a6bf28ad865e7c0619b17349e08 (diff) |
sky2: receive counter update
Since it is likely that there are multiple packets received per
interrupt, only update the receive counters once after all
packets are processed.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sky2.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fd7accf8f305..1b8de4518adc 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -2357,11 +2357,25 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
2357 | } | 2357 | } |
2358 | } | 2358 | } |
2359 | 2359 | ||
2360 | static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port, | ||
2361 | unsigned packets, unsigned bytes) | ||
2362 | { | ||
2363 | if (packets) { | ||
2364 | struct net_device *dev = hw->dev[port]; | ||
2365 | |||
2366 | dev->stats.rx_packets += packets; | ||
2367 | dev->stats.rx_bytes += bytes; | ||
2368 | dev->last_rx = jiffies; | ||
2369 | sky2_rx_update(netdev_priv(dev), rxqaddr[port]); | ||
2370 | } | ||
2371 | } | ||
2372 | |||
2360 | /* Process status response ring */ | 2373 | /* Process status response ring */ |
2361 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | 2374 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) |
2362 | { | 2375 | { |
2363 | int work_done = 0; | 2376 | int work_done = 0; |
2364 | unsigned rx[2] = { 0, 0 }; | 2377 | unsigned int total_bytes[2] = { 0 }; |
2378 | unsigned int total_packets[2] = { 0 }; | ||
2365 | 2379 | ||
2366 | rmb(); | 2380 | rmb(); |
2367 | do { | 2381 | do { |
@@ -2388,7 +2402,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2388 | le->opcode = 0; | 2402 | le->opcode = 0; |
2389 | switch (opcode & ~HW_OWNER) { | 2403 | switch (opcode & ~HW_OWNER) { |
2390 | case OP_RXSTAT: | 2404 | case OP_RXSTAT: |
2391 | ++rx[port]; | 2405 | total_packets[port]++; |
2406 | total_bytes[port] += length; | ||
2392 | skb = sky2_receive(dev, length, status); | 2407 | skb = sky2_receive(dev, length, status); |
2393 | if (unlikely(!skb)) { | 2408 | if (unlikely(!skb)) { |
2394 | dev->stats.rx_dropped++; | 2409 | dev->stats.rx_dropped++; |
@@ -2406,9 +2421,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2406 | } | 2421 | } |
2407 | 2422 | ||
2408 | skb->protocol = eth_type_trans(skb, dev); | 2423 | skb->protocol = eth_type_trans(skb, dev); |
2409 | dev->stats.rx_packets++; | ||
2410 | dev->stats.rx_bytes += skb->len; | ||
2411 | dev->last_rx = jiffies; | ||
2412 | 2424 | ||
2413 | #ifdef SKY2_VLAN_TAG_USED | 2425 | #ifdef SKY2_VLAN_TAG_USED |
2414 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | 2426 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { |
@@ -2487,11 +2499,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2487 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2499 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2488 | 2500 | ||
2489 | exit_loop: | 2501 | exit_loop: |
2490 | if (rx[0]) | 2502 | sky2_rx_done(hw, 0, total_packets[0], total_bytes[0]); |
2491 | sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1); | 2503 | sky2_rx_done(hw, 1, total_packets[1], total_bytes[1]); |
2492 | |||
2493 | if (rx[1]) | ||
2494 | sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2); | ||
2495 | 2504 | ||
2496 | return work_done; | 2505 | return work_done; |
2497 | } | 2506 | } |