diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 161 |
1 files changed, 107 insertions, 54 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 6b5946fe8ae2..7681d28c53d7 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sky2.h" | 50 | #include "sky2.h" |
51 | 51 | ||
52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.22" | 53 | #define DRV_VERSION "1.23" |
54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -65,9 +65,9 @@ | |||
65 | #define RX_DEF_PENDING RX_MAX_PENDING | 65 | #define RX_DEF_PENDING RX_MAX_PENDING |
66 | 66 | ||
67 | #define TX_RING_SIZE 512 | 67 | #define TX_RING_SIZE 512 |
68 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 68 | #define TX_DEF_PENDING 128 |
69 | #define TX_MIN_PENDING 64 | ||
70 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) | 69 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
70 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) | ||
71 | 71 | ||
72 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 72 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
73 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 73 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
@@ -1151,7 +1151,14 @@ stopped: | |||
1151 | 1151 | ||
1152 | /* reset the Rx prefetch unit */ | 1152 | /* reset the Rx prefetch unit */ |
1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); | 1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1154 | mmiowb(); | 1154 | |
1155 | /* Reset the RAM Buffer receive queue */ | ||
1156 | sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_RST_SET); | ||
1157 | |||
1158 | /* Reset Rx MAC FIFO */ | ||
1159 | sky2_write8(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), GMF_RST_SET); | ||
1160 | |||
1161 | sky2_read8(hw, B0_CTST); | ||
1155 | } | 1162 | } |
1156 | 1163 | ||
1157 | /* Clean out receive buffer area, assumes receiver hardware stopped */ | 1164 | /* Clean out receive buffer area, assumes receiver hardware stopped */ |
@@ -1169,6 +1176,7 @@ static void sky2_rx_clean(struct sky2_port *sky2) | |||
1169 | re->skb = NULL; | 1176 | re->skb = NULL; |
1170 | } | 1177 | } |
1171 | } | 1178 | } |
1179 | skb_queue_purge(&sky2->rx_recycle); | ||
1172 | } | 1180 | } |
1173 | 1181 | ||
1174 | /* Basic MII support */ | 1182 | /* Basic MII support */ |
@@ -1245,6 +1253,12 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1245 | } | 1253 | } |
1246 | #endif | 1254 | #endif |
1247 | 1255 | ||
1256 | /* Amount of required worst case padding in rx buffer */ | ||
1257 | static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) | ||
1258 | { | ||
1259 | return (hw->flags & SKY2_HW_RAM_BUFFER) ? 8 : 2; | ||
1260 | } | ||
1261 | |||
1248 | /* | 1262 | /* |
1249 | * Allocate an skb for receiving. If the MTU is large enough | 1263 | * Allocate an skb for receiving. If the MTU is large enough |
1250 | * make the skb non-linear with a fragment list of pages. | 1264 | * make the skb non-linear with a fragment list of pages. |
@@ -1254,6 +1268,13 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) | |||
1254 | struct sk_buff *skb; | 1268 | struct sk_buff *skb; |
1255 | int i; | 1269 | int i; |
1256 | 1270 | ||
1271 | skb = __skb_dequeue(&sky2->rx_recycle); | ||
1272 | if (!skb) | ||
1273 | skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size | ||
1274 | + sky2_rx_pad(sky2->hw)); | ||
1275 | if (!skb) | ||
1276 | goto nomem; | ||
1277 | |||
1257 | if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) { | 1278 | if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) { |
1258 | unsigned char *start; | 1279 | unsigned char *start; |
1259 | /* | 1280 | /* |
@@ -1262,18 +1283,10 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) | |||
1262 | * The buffer returned from netdev_alloc_skb is | 1283 | * The buffer returned from netdev_alloc_skb is |
1263 | * aligned except if slab debugging is enabled. | 1284 | * aligned except if slab debugging is enabled. |
1264 | */ | 1285 | */ |
1265 | skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8); | ||
1266 | if (!skb) | ||
1267 | goto nomem; | ||
1268 | start = PTR_ALIGN(skb->data, 8); | 1286 | start = PTR_ALIGN(skb->data, 8); |
1269 | skb_reserve(skb, start - skb->data); | 1287 | skb_reserve(skb, start - skb->data); |
1270 | } else { | 1288 | } else |
1271 | skb = netdev_alloc_skb(sky2->netdev, | ||
1272 | sky2->rx_data_size + NET_IP_ALIGN); | ||
1273 | if (!skb) | ||
1274 | goto nomem; | ||
1275 | skb_reserve(skb, NET_IP_ALIGN); | 1289 | skb_reserve(skb, NET_IP_ALIGN); |
1276 | } | ||
1277 | 1290 | ||
1278 | for (i = 0; i < sky2->rx_nfrags; i++) { | 1291 | for (i = 0; i < sky2->rx_nfrags; i++) { |
1279 | struct page *page = alloc_page(GFP_ATOMIC); | 1292 | struct page *page = alloc_page(GFP_ATOMIC); |
@@ -1350,6 +1363,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1350 | 1363 | ||
1351 | sky2->rx_data_size = size; | 1364 | sky2->rx_data_size = size; |
1352 | 1365 | ||
1366 | skb_queue_head_init(&sky2->rx_recycle); | ||
1367 | |||
1353 | /* Fill Rx ring */ | 1368 | /* Fill Rx ring */ |
1354 | for (i = 0; i < sky2->rx_pending; i++) { | 1369 | for (i = 0; i < sky2->rx_pending; i++) { |
1355 | re = sky2->rx_ring + i; | 1370 | re = sky2->rx_ring + i; |
@@ -1488,6 +1503,7 @@ static int sky2_up(struct net_device *dev) | |||
1488 | imask = sky2_read32(hw, B0_IMSK); | 1503 | imask = sky2_read32(hw, B0_IMSK); |
1489 | imask |= portirq_msk[port]; | 1504 | imask |= portirq_msk[port]; |
1490 | sky2_write32(hw, B0_IMSK, imask); | 1505 | sky2_write32(hw, B0_IMSK, imask); |
1506 | sky2_read32(hw, B0_IMSK); | ||
1491 | 1507 | ||
1492 | sky2_set_multicast(dev); | 1508 | sky2_set_multicast(dev); |
1493 | 1509 | ||
@@ -1756,14 +1772,22 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1756 | } | 1772 | } |
1757 | 1773 | ||
1758 | if (le->ctrl & EOP) { | 1774 | if (le->ctrl & EOP) { |
1775 | struct sk_buff *skb = re->skb; | ||
1776 | |||
1759 | if (unlikely(netif_msg_tx_done(sky2))) | 1777 | if (unlikely(netif_msg_tx_done(sky2))) |
1760 | printk(KERN_DEBUG "%s: tx done %u\n", | 1778 | printk(KERN_DEBUG "%s: tx done %u\n", |
1761 | dev->name, idx); | 1779 | dev->name, idx); |
1762 | 1780 | ||
1763 | dev->stats.tx_packets++; | 1781 | dev->stats.tx_packets++; |
1764 | dev->stats.tx_bytes += re->skb->len; | 1782 | dev->stats.tx_bytes += skb->len; |
1783 | |||
1784 | if (skb_queue_len(&sky2->rx_recycle) < sky2->rx_pending | ||
1785 | && skb_recycle_check(skb, sky2->rx_data_size | ||
1786 | + sky2_rx_pad(sky2->hw))) | ||
1787 | __skb_queue_head(&sky2->rx_recycle, skb); | ||
1788 | else | ||
1789 | dev_kfree_skb_any(skb); | ||
1765 | 1790 | ||
1766 | dev_kfree_skb_any(re->skb); | ||
1767 | sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); | 1791 | sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); |
1768 | } | 1792 | } |
1769 | } | 1793 | } |
@@ -1805,10 +1829,10 @@ static int sky2_down(struct net_device *dev) | |||
1805 | imask = sky2_read32(hw, B0_IMSK); | 1829 | imask = sky2_read32(hw, B0_IMSK); |
1806 | imask &= ~portirq_msk[port]; | 1830 | imask &= ~portirq_msk[port]; |
1807 | sky2_write32(hw, B0_IMSK, imask); | 1831 | sky2_write32(hw, B0_IMSK, imask); |
1832 | sky2_read32(hw, B0_IMSK); | ||
1808 | 1833 | ||
1809 | synchronize_irq(hw->pdev->irq); | 1834 | /* Force flow control off */ |
1810 | 1835 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | |
1811 | sky2_gmac_reset(hw, port); | ||
1812 | 1836 | ||
1813 | /* Stop transmitter */ | 1837 | /* Stop transmitter */ |
1814 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); | 1838 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); |
@@ -1821,9 +1845,6 @@ static int sky2_down(struct net_device *dev) | |||
1821 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); | 1845 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); |
1822 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | 1846 | gma_write16(hw, port, GM_GP_CTRL, ctrl); |
1823 | 1847 | ||
1824 | /* Make sure no packets are pending */ | ||
1825 | napi_synchronize(&hw->napi); | ||
1826 | |||
1827 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 1848 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1828 | 1849 | ||
1829 | /* Workaround shared GMAC reset */ | 1850 | /* Workaround shared GMAC reset */ |
@@ -1854,6 +1875,15 @@ static int sky2_down(struct net_device *dev) | |||
1854 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1875 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1855 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1876 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1856 | 1877 | ||
1878 | /* Force any delayed status interrrupt and NAPI */ | ||
1879 | sky2_write32(hw, STAT_LEV_TIMER_CNT, 0); | ||
1880 | sky2_write32(hw, STAT_TX_TIMER_CNT, 0); | ||
1881 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); | ||
1882 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); | ||
1883 | |||
1884 | synchronize_irq(hw->pdev->irq); | ||
1885 | napi_synchronize(&hw->napi); | ||
1886 | |||
1857 | sky2_phy_power_down(hw, port); | 1887 | sky2_phy_power_down(hw, port); |
1858 | 1888 | ||
1859 | /* turn off LED's */ | 1889 | /* turn off LED's */ |
@@ -2343,11 +2373,45 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
2343 | } | 2373 | } |
2344 | } | 2374 | } |
2345 | 2375 | ||
2376 | static inline void sky2_skb_rx(const struct sky2_port *sky2, | ||
2377 | u32 status, struct sk_buff *skb) | ||
2378 | { | ||
2379 | #ifdef SKY2_VLAN_TAG_USED | ||
2380 | u16 vlan_tag = be16_to_cpu(sky2->rx_tag); | ||
2381 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | ||
2382 | if (skb->ip_summed == CHECKSUM_NONE) | ||
2383 | vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag); | ||
2384 | else | ||
2385 | vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp, | ||
2386 | vlan_tag, skb); | ||
2387 | return; | ||
2388 | } | ||
2389 | #endif | ||
2390 | if (skb->ip_summed == CHECKSUM_NONE) | ||
2391 | netif_receive_skb(skb); | ||
2392 | else | ||
2393 | napi_gro_receive(&sky2->hw->napi, skb); | ||
2394 | } | ||
2395 | |||
2396 | static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port, | ||
2397 | unsigned packets, unsigned bytes) | ||
2398 | { | ||
2399 | if (packets) { | ||
2400 | struct net_device *dev = hw->dev[port]; | ||
2401 | |||
2402 | dev->stats.rx_packets += packets; | ||
2403 | dev->stats.rx_bytes += bytes; | ||
2404 | dev->last_rx = jiffies; | ||
2405 | sky2_rx_update(netdev_priv(dev), rxqaddr[port]); | ||
2406 | } | ||
2407 | } | ||
2408 | |||
2346 | /* Process status response ring */ | 2409 | /* Process status response ring */ |
2347 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | 2410 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) |
2348 | { | 2411 | { |
2349 | int work_done = 0; | 2412 | int work_done = 0; |
2350 | unsigned rx[2] = { 0, 0 }; | 2413 | unsigned int total_bytes[2] = { 0 }; |
2414 | unsigned int total_packets[2] = { 0 }; | ||
2351 | 2415 | ||
2352 | rmb(); | 2416 | rmb(); |
2353 | do { | 2417 | do { |
@@ -2374,7 +2438,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2374 | le->opcode = 0; | 2438 | le->opcode = 0; |
2375 | switch (opcode & ~HW_OWNER) { | 2439 | switch (opcode & ~HW_OWNER) { |
2376 | case OP_RXSTAT: | 2440 | case OP_RXSTAT: |
2377 | ++rx[port]; | 2441 | total_packets[port]++; |
2442 | total_bytes[port] += length; | ||
2378 | skb = sky2_receive(dev, length, status); | 2443 | skb = sky2_receive(dev, length, status); |
2379 | if (unlikely(!skb)) { | 2444 | if (unlikely(!skb)) { |
2380 | dev->stats.rx_dropped++; | 2445 | dev->stats.rx_dropped++; |
@@ -2392,18 +2457,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2392 | } | 2457 | } |
2393 | 2458 | ||
2394 | skb->protocol = eth_type_trans(skb, dev); | 2459 | skb->protocol = eth_type_trans(skb, dev); |
2395 | dev->stats.rx_packets++; | ||
2396 | dev->stats.rx_bytes += skb->len; | ||
2397 | dev->last_rx = jiffies; | ||
2398 | 2460 | ||
2399 | #ifdef SKY2_VLAN_TAG_USED | 2461 | sky2_skb_rx(sky2, status, skb); |
2400 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | ||
2401 | vlan_hwaccel_receive_skb(skb, | ||
2402 | sky2->vlgrp, | ||
2403 | be16_to_cpu(sky2->rx_tag)); | ||
2404 | } else | ||
2405 | #endif | ||
2406 | netif_receive_skb(skb); | ||
2407 | 2462 | ||
2408 | /* Stop after net poll weight */ | 2463 | /* Stop after net poll weight */ |
2409 | if (++work_done >= to_do) | 2464 | if (++work_done >= to_do) |
@@ -2473,11 +2528,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2473 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2528 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2474 | 2529 | ||
2475 | exit_loop: | 2530 | exit_loop: |
2476 | if (rx[0]) | 2531 | sky2_rx_done(hw, 0, total_packets[0], total_bytes[0]); |
2477 | sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1); | 2532 | sky2_rx_done(hw, 1, total_packets[1], total_bytes[1]); |
2478 | |||
2479 | if (rx[1]) | ||
2480 | sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2); | ||
2481 | 2533 | ||
2482 | return work_done; | 2534 | return work_done; |
2483 | } | 2535 | } |
@@ -4364,6 +4416,22 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4364 | goto err_out; | 4416 | goto err_out; |
4365 | } | 4417 | } |
4366 | 4418 | ||
4419 | /* Get configuration information | ||
4420 | * Note: only regular PCI config access once to test for HW issues | ||
4421 | * other PCI access through shared memory for speed and to | ||
4422 | * avoid MMCONFIG problems. | ||
4423 | */ | ||
4424 | err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
4425 | if (err) { | ||
4426 | dev_err(&pdev->dev, "PCI read config failed\n"); | ||
4427 | goto err_out; | ||
4428 | } | ||
4429 | |||
4430 | if (~reg == 0) { | ||
4431 | dev_err(&pdev->dev, "PCI configuration read error\n"); | ||
4432 | goto err_out; | ||
4433 | } | ||
4434 | |||
4367 | err = pci_request_regions(pdev, DRV_NAME); | 4435 | err = pci_request_regions(pdev, DRV_NAME); |
4368 | if (err) { | 4436 | if (err) { |
4369 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); | 4437 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); |
@@ -4389,21 +4457,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4389 | } | 4457 | } |
4390 | } | 4458 | } |
4391 | 4459 | ||
4392 | /* Get configuration information | ||
4393 | * Note: only regular PCI config access once to test for HW issues | ||
4394 | * other PCI access through shared memory for speed and to | ||
4395 | * avoid MMCONFIG problems. | ||
4396 | */ | ||
4397 | err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
4398 | if (err) { | ||
4399 | dev_err(&pdev->dev, "PCI read config failed\n"); | ||
4400 | goto err_out_free_regions; | ||
4401 | } | ||
4402 | |||
4403 | /* size of available VPD, only impact sysfs */ | ||
4404 | err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8)); | ||
4405 | if (err) | ||
4406 | dev_warn(&pdev->dev, "Can't set VPD size\n"); | ||
4407 | 4460 | ||
4408 | #ifdef __BIG_ENDIAN | 4461 | #ifdef __BIG_ENDIAN |
4409 | /* The sk98lin vendor driver uses hardware byte swapping but | 4462 | /* The sk98lin vendor driver uses hardware byte swapping but |