diff options
| -rw-r--r-- | drivers/net/sky2.c | 65 |
1 files changed, 28 insertions, 37 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 0cc57293faf9..8527a49e3ff7 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -1040,13 +1040,14 @@ out_unlock: | |||
| 1040 | * NB: the hardware will tell us about partial completion of multi-part | 1040 | * NB: the hardware will tell us about partial completion of multi-part |
| 1041 | * buffers; these are defered until completion. | 1041 | * buffers; these are defered until completion. |
| 1042 | */ | 1042 | */ |
| 1043 | static void sky2_tx_complete(struct net_device *dev, u16 done) | 1043 | static void sky2_tx_complete(struct sky2_port *sky2, u16 done) |
| 1044 | { | 1044 | { |
| 1045 | struct sky2_port *sky2 = netdev_priv(dev); | 1045 | struct net_device *dev = sky2->netdev; |
| 1046 | unsigned i; | 1046 | unsigned i; |
| 1047 | 1047 | ||
| 1048 | if (netif_msg_tx_done(sky2)) | 1048 | if (unlikely(netif_msg_tx_done(sky2))) |
| 1049 | printk(KERN_DEBUG "%s: tx done, upto %u\n", dev->name, done); | 1049 | printk(KERN_DEBUG "%s: tx done, upto %u\n", |
| 1050 | dev->name, done); | ||
| 1050 | 1051 | ||
| 1051 | spin_lock(&sky2->tx_lock); | 1052 | spin_lock(&sky2->tx_lock); |
| 1052 | 1053 | ||
| @@ -1086,7 +1087,7 @@ out: | |||
| 1086 | /* Cleanup all untransmitted buffers, assume transmitter not running */ | 1087 | /* Cleanup all untransmitted buffers, assume transmitter not running */ |
| 1087 | static inline void sky2_tx_clean(struct sky2_port *sky2) | 1088 | static inline void sky2_tx_clean(struct sky2_port *sky2) |
| 1088 | { | 1089 | { |
| 1089 | sky2_tx_complete(sky2->netdev, sky2->tx_prod); | 1090 | sky2_tx_complete(sky2, sky2->tx_prod); |
| 1090 | } | 1091 | } |
| 1091 | 1092 | ||
| 1092 | /* Network shutdown */ | 1093 | /* Network shutdown */ |
| @@ -1421,18 +1422,17 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1421 | * For small packets or errors, just reuse existing skb. | 1422 | * For small packets or errors, just reuse existing skb. |
| 1422 | * For larger pakects, get new buffer. | 1423 | * For larger pakects, get new buffer. |
| 1423 | */ | 1424 | */ |
| 1424 | static struct sk_buff *sky2_receive(struct sky2_hw *hw, unsigned port, | 1425 | static struct sk_buff *sky2_receive(struct sky2_port *sky2, |
| 1425 | u16 length, u32 status) | 1426 | u16 length, u32 status) |
| 1426 | { | 1427 | { |
| 1427 | struct net_device *dev = hw->dev[port]; | ||
| 1428 | struct sky2_port *sky2 = netdev_priv(dev); | ||
| 1429 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; | 1428 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; |
| 1430 | struct sk_buff *skb = NULL; | 1429 | struct sk_buff *skb = NULL; |
| 1430 | struct net_device *dev; | ||
| 1431 | const unsigned int bufsize = rx_size(sky2); | 1431 | const unsigned int bufsize = rx_size(sky2); |
| 1432 | 1432 | ||
| 1433 | if (unlikely(netif_msg_rx_status(sky2))) | 1433 | if (unlikely(netif_msg_rx_status(sky2))) |
| 1434 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", | 1434 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", |
| 1435 | dev->name, sky2->rx_next, status, length); | 1435 | sky2->netdev->name, sky2->rx_next, status, length); |
| 1436 | 1436 | ||
| 1437 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; | 1437 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; |
| 1438 | 1438 | ||
| @@ -1451,6 +1451,8 @@ static struct sk_buff *sky2_receive(struct sky2_hw *hw, unsigned port, | |||
| 1451 | pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr, | 1451 | pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr, |
| 1452 | length, PCI_DMA_FROMDEVICE); | 1452 | length, PCI_DMA_FROMDEVICE); |
| 1453 | memcpy(skb->data, re->skb->data, length); | 1453 | memcpy(skb->data, re->skb->data, length); |
| 1454 | skb->ip_summed = re->skb->ip_summed; | ||
| 1455 | skb->csum = re->skb->csum; | ||
| 1454 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr, | 1456 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr, |
| 1455 | length, PCI_DMA_FROMDEVICE); | 1457 | length, PCI_DMA_FROMDEVICE); |
| 1456 | } else { | 1458 | } else { |
| @@ -1471,12 +1473,14 @@ static struct sk_buff *sky2_receive(struct sky2_hw *hw, unsigned port, | |||
| 1471 | re->maplen = bufsize; | 1473 | re->maplen = bufsize; |
| 1472 | } | 1474 | } |
| 1473 | 1475 | ||
| 1474 | skb->dev = dev; | ||
| 1475 | skb_put(skb, length); | 1476 | skb_put(skb, length); |
| 1477 | dev = sky2->netdev; | ||
| 1478 | skb->dev = dev; | ||
| 1476 | skb->protocol = eth_type_trans(skb, dev); | 1479 | skb->protocol = eth_type_trans(skb, dev); |
| 1477 | dev->last_rx = jiffies; | 1480 | dev->last_rx = jiffies; |
| 1478 | 1481 | ||
| 1479 | resubmit: | 1482 | resubmit: |
| 1483 | re->skb->ip_summed = CHECKSUM_NONE; | ||
| 1480 | sky2_rx_add(sky2, re); | 1484 | sky2_rx_add(sky2, re); |
| 1481 | 1485 | ||
| 1482 | return skb; | 1486 | return skb; |
| @@ -1517,59 +1521,46 @@ static inline u16 tx_index(u8 port, u32 status, u16 len) | |||
| 1517 | * Both ports share the same status interrupt, therefore there is only | 1521 | * Both ports share the same status interrupt, therefore there is only |
| 1518 | * one poll routine. | 1522 | * one poll routine. |
| 1519 | */ | 1523 | */ |
| 1520 | static int sky2_poll(struct net_device *dev, int *budget) | 1524 | static int sky2_poll(struct net_device *dev0, int *budget) |
| 1521 | { | 1525 | { |
| 1522 | struct sky2_port *sky2 = netdev_priv(dev); | 1526 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; |
| 1523 | struct sky2_hw *hw = sky2->hw; | 1527 | unsigned int to_do = min(dev0->quota, *budget); |
| 1524 | unsigned int to_do = min(dev->quota, *budget); | ||
| 1525 | unsigned int work_done = 0; | 1528 | unsigned int work_done = 0; |
| 1526 | u16 hwidx; | 1529 | u16 hwidx; |
| 1527 | unsigned char summed[2] = { CHECKSUM_NONE, CHECKSUM_NONE }; | ||
| 1528 | unsigned int csum[2]; | ||
| 1529 | 1530 | ||
| 1530 | hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1531 | hwidx = sky2_read16(hw, STAT_PUT_IDX); |
| 1531 | BUG_ON(hwidx >= STATUS_RING_SIZE); | 1532 | BUG_ON(hwidx >= STATUS_RING_SIZE); |
| 1532 | rmb(); | 1533 | rmb(); |
| 1533 | while (hw->st_idx != hwidx && work_done < to_do) { | 1534 | while (hw->st_idx != hwidx && work_done < to_do) { |
| 1534 | struct sky2_status_le *le = hw->st_le + hw->st_idx; | 1535 | struct sky2_status_le *le = hw->st_le + hw->st_idx; |
| 1536 | struct sky2_port *sky2; | ||
| 1535 | struct sk_buff *skb; | 1537 | struct sk_buff *skb; |
| 1536 | u8 port; | ||
| 1537 | u32 status; | 1538 | u32 status; |
| 1538 | u16 length; | 1539 | u16 length; |
| 1539 | 1540 | ||
| 1541 | BUG_ON(le->link >= hw->ports); | ||
| 1542 | sky2 = netdev_priv(hw->dev[le->link]); | ||
| 1540 | status = le32_to_cpu(le->status); | 1543 | status = le32_to_cpu(le->status); |
| 1541 | length = le16_to_cpu(le->length); | 1544 | length = le16_to_cpu(le->length); |
| 1542 | port = le->link; | ||
| 1543 | |||
| 1544 | BUG_ON(port >= hw->ports || hw->dev[port] == NULL); | ||
| 1545 | 1545 | ||
| 1546 | switch (le->opcode & ~HW_OWNER) { | 1546 | switch (le->opcode & ~HW_OWNER) { |
| 1547 | case OP_RXSTAT: | 1547 | case OP_RXSTAT: |
| 1548 | skb = sky2_receive(hw, port, length, status); | 1548 | skb = sky2_receive(sky2, length, status); |
| 1549 | if (likely(skb)) { | 1549 | if (likely(skb)) { |
| 1550 | /* Add hw checksum if available */ | ||
| 1551 | skb->ip_summed = summed[port]; | ||
| 1552 | skb->csum = csum[port]; | ||
| 1553 | |||
| 1554 | netif_receive_skb(skb); | 1550 | netif_receive_skb(skb); |
| 1555 | ++work_done; | 1551 | ++work_done; |
| 1556 | } | 1552 | } |
| 1557 | |||
| 1558 | /* Clear for next packet */ | ||
| 1559 | csum[port] = 0; | ||
| 1560 | summed[port] = CHECKSUM_NONE; | ||
| 1561 | |||
| 1562 | break; | 1553 | break; |
| 1563 | 1554 | ||
| 1564 | case OP_RXCHKS: | 1555 | case OP_RXCHKS: |
| 1565 | /* Save computed checksum for next rx */ | 1556 | skb = sky2->rx_ring[sky2->rx_next].skb; |
| 1566 | csum[port] = le16_to_cpu(status & 0xffff); | 1557 | skb->ip_summed = CHECKSUM_HW; |
| 1567 | summed[port] = CHECKSUM_HW; | 1558 | skb->csum = le16_to_cpu(status); |
| 1568 | break; | 1559 | break; |
| 1569 | 1560 | ||
| 1570 | case OP_TXINDEXLE: | 1561 | case OP_TXINDEXLE: |
| 1571 | sky2_tx_complete(hw->dev[port], | 1562 | sky2_tx_complete(sky2, |
| 1572 | tx_index(port, status, length)); | 1563 | tx_index(sky2->port, status, length)); |
| 1573 | break; | 1564 | break; |
| 1574 | 1565 | ||
| 1575 | case OP_RXTIMESTAMP: | 1566 | case OP_RXTIMESTAMP: |
| @@ -1599,7 +1590,7 @@ static int sky2_poll(struct net_device *dev, int *budget) | |||
| 1599 | rx_set_put(hw->dev[1]); | 1590 | rx_set_put(hw->dev[1]); |
| 1600 | 1591 | ||
| 1601 | *budget -= work_done; | 1592 | *budget -= work_done; |
| 1602 | dev->quota -= work_done; | 1593 | dev0->quota -= work_done; |
| 1603 | if (work_done < to_do) { | 1594 | if (work_done < to_do) { |
| 1604 | /* | 1595 | /* |
| 1605 | * Another chip workaround, need to restart TX timer if status | 1596 | * Another chip workaround, need to restart TX timer if status |
| @@ -1613,7 +1604,7 @@ static int sky2_poll(struct net_device *dev, int *budget) | |||
| 1613 | hw->intr_mask |= Y2_IS_STAT_BMU; | 1604 | hw->intr_mask |= Y2_IS_STAT_BMU; |
| 1614 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1605 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
| 1615 | sky2_read32(hw, B0_IMSK); | 1606 | sky2_read32(hw, B0_IMSK); |
| 1616 | netif_rx_complete(dev); | 1607 | netif_rx_complete(dev0); |
| 1617 | } | 1608 | } |
| 1618 | 1609 | ||
| 1619 | return work_done >= to_do; | 1610 | return work_done >= to_do; |
