diff options
author | Paul Mackerras <paulus@samba.org> | 2008-01-23 18:07:21 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-01-23 18:07:21 -0500 |
commit | 9156ad48338e0306e508ead5c0d9986050744475 (patch) | |
tree | 37f3a90e38190052ecf3cdf9171dfdddd37b56fd /drivers/net/cassini.c | |
parent | fa28237cfcc5827553044cbd6ee52e33692b0faa (diff) | |
parent | 8f7b3d156d348b6766833cd4e272d0d19b501e64 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'drivers/net/cassini.c')
-rw-r--r-- | drivers/net/cassini.c | 139 |
1 files changed, 100 insertions, 39 deletions
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7df31b5561cc..d66915d82b24 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -142,8 +142,8 @@ | |||
142 | 142 | ||
143 | #define DRV_MODULE_NAME "cassini" | 143 | #define DRV_MODULE_NAME "cassini" |
144 | #define PFX DRV_MODULE_NAME ": " | 144 | #define PFX DRV_MODULE_NAME ": " |
145 | #define DRV_MODULE_VERSION "1.4" | 145 | #define DRV_MODULE_VERSION "1.5" |
146 | #define DRV_MODULE_RELDATE "1 July 2004" | 146 | #define DRV_MODULE_RELDATE "4 Jan 2008" |
147 | 147 | ||
148 | #define CAS_DEF_MSG_ENABLE \ | 148 | #define CAS_DEF_MSG_ENABLE \ |
149 | (NETIF_MSG_DRV | \ | 149 | (NETIF_MSG_DRV | \ |
@@ -336,30 +336,6 @@ static inline void cas_mask_intr(struct cas *cp) | |||
336 | cas_disable_irq(cp, i); | 336 | cas_disable_irq(cp, i); |
337 | } | 337 | } |
338 | 338 | ||
339 | static inline void cas_buffer_init(cas_page_t *cp) | ||
340 | { | ||
341 | struct page *page = cp->buffer; | ||
342 | atomic_set((atomic_t *)&page->lru.next, 1); | ||
343 | } | ||
344 | |||
345 | static inline int cas_buffer_count(cas_page_t *cp) | ||
346 | { | ||
347 | struct page *page = cp->buffer; | ||
348 | return atomic_read((atomic_t *)&page->lru.next); | ||
349 | } | ||
350 | |||
351 | static inline void cas_buffer_inc(cas_page_t *cp) | ||
352 | { | ||
353 | struct page *page = cp->buffer; | ||
354 | atomic_inc((atomic_t *)&page->lru.next); | ||
355 | } | ||
356 | |||
357 | static inline void cas_buffer_dec(cas_page_t *cp) | ||
358 | { | ||
359 | struct page *page = cp->buffer; | ||
360 | atomic_dec((atomic_t *)&page->lru.next); | ||
361 | } | ||
362 | |||
363 | static void cas_enable_irq(struct cas *cp, const int ring) | 339 | static void cas_enable_irq(struct cas *cp, const int ring) |
364 | { | 340 | { |
365 | if (ring == 0) { /* all but TX_DONE */ | 341 | if (ring == 0) { /* all but TX_DONE */ |
@@ -497,7 +473,6 @@ static int cas_page_free(struct cas *cp, cas_page_t *page) | |||
497 | { | 473 | { |
498 | pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, | 474 | pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, |
499 | PCI_DMA_FROMDEVICE); | 475 | PCI_DMA_FROMDEVICE); |
500 | cas_buffer_dec(page); | ||
501 | __free_pages(page->buffer, cp->page_order); | 476 | __free_pages(page->buffer, cp->page_order); |
502 | kfree(page); | 477 | kfree(page); |
503 | return 0; | 478 | return 0; |
@@ -527,7 +502,6 @@ static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags) | |||
527 | page->buffer = alloc_pages(flags, cp->page_order); | 502 | page->buffer = alloc_pages(flags, cp->page_order); |
528 | if (!page->buffer) | 503 | if (!page->buffer) |
529 | goto page_err; | 504 | goto page_err; |
530 | cas_buffer_init(page); | ||
531 | page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, | 505 | page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, |
532 | cp->page_size, PCI_DMA_FROMDEVICE); | 506 | cp->page_size, PCI_DMA_FROMDEVICE); |
533 | return page; | 507 | return page; |
@@ -606,7 +580,7 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags) | |||
606 | list_for_each_safe(elem, tmp, &list) { | 580 | list_for_each_safe(elem, tmp, &list) { |
607 | cas_page_t *page = list_entry(elem, cas_page_t, list); | 581 | cas_page_t *page = list_entry(elem, cas_page_t, list); |
608 | 582 | ||
609 | if (cas_buffer_count(page) > 1) | 583 | if (page_count(page->buffer) > 1) |
610 | continue; | 584 | continue; |
611 | 585 | ||
612 | list_del(elem); | 586 | list_del(elem); |
@@ -1374,7 +1348,7 @@ static inline cas_page_t *cas_page_spare(struct cas *cp, const int index) | |||
1374 | cas_page_t *page = cp->rx_pages[1][index]; | 1348 | cas_page_t *page = cp->rx_pages[1][index]; |
1375 | cas_page_t *new; | 1349 | cas_page_t *new; |
1376 | 1350 | ||
1377 | if (cas_buffer_count(page) == 1) | 1351 | if (page_count(page->buffer) == 1) |
1378 | return page; | 1352 | return page; |
1379 | 1353 | ||
1380 | new = cas_page_dequeue(cp); | 1354 | new = cas_page_dequeue(cp); |
@@ -1394,7 +1368,7 @@ static cas_page_t *cas_page_swap(struct cas *cp, const int ring, | |||
1394 | cas_page_t **page1 = cp->rx_pages[1]; | 1368 | cas_page_t **page1 = cp->rx_pages[1]; |
1395 | 1369 | ||
1396 | /* swap if buffer is in use */ | 1370 | /* swap if buffer is in use */ |
1397 | if (cas_buffer_count(page0[index]) > 1) { | 1371 | if (page_count(page0[index]->buffer) > 1) { |
1398 | cas_page_t *new = cas_page_spare(cp, index); | 1372 | cas_page_t *new = cas_page_spare(cp, index); |
1399 | if (new) { | 1373 | if (new) { |
1400 | page1[index] = page0[index]; | 1374 | page1[index] = page0[index]; |
@@ -1979,6 +1953,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, | |||
1979 | struct cas_page *page; | 1953 | struct cas_page *page; |
1980 | struct sk_buff *skb; | 1954 | struct sk_buff *skb; |
1981 | void *addr, *crcaddr; | 1955 | void *addr, *crcaddr; |
1956 | __sum16 csum; | ||
1982 | char *p; | 1957 | char *p; |
1983 | 1958 | ||
1984 | hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]); | 1959 | hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]); |
@@ -2062,10 +2037,10 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, | |||
2062 | 2037 | ||
2063 | skb_shinfo(skb)->nr_frags++; | 2038 | skb_shinfo(skb)->nr_frags++; |
2064 | skb->data_len += hlen - swivel; | 2039 | skb->data_len += hlen - swivel; |
2040 | skb->truesize += hlen - swivel; | ||
2065 | skb->len += hlen - swivel; | 2041 | skb->len += hlen - swivel; |
2066 | 2042 | ||
2067 | get_page(page->buffer); | 2043 | get_page(page->buffer); |
2068 | cas_buffer_inc(page); | ||
2069 | frag->page = page->buffer; | 2044 | frag->page = page->buffer; |
2070 | frag->page_offset = off; | 2045 | frag->page_offset = off; |
2071 | frag->size = hlen - swivel; | 2046 | frag->size = hlen - swivel; |
@@ -2090,7 +2065,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, | |||
2090 | frag++; | 2065 | frag++; |
2091 | 2066 | ||
2092 | get_page(page->buffer); | 2067 | get_page(page->buffer); |
2093 | cas_buffer_inc(page); | ||
2094 | frag->page = page->buffer; | 2068 | frag->page = page->buffer; |
2095 | frag->page_offset = 0; | 2069 | frag->page_offset = 0; |
2096 | frag->size = hlen; | 2070 | frag->size = hlen; |
@@ -2158,14 +2132,15 @@ end_copy_pkt: | |||
2158 | skb_put(skb, alloclen); | 2132 | skb_put(skb, alloclen); |
2159 | } | 2133 | } |
2160 | 2134 | ||
2161 | i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]); | 2135 | csum = (__force __sum16)htons(CAS_VAL(RX_COMP4_TCP_CSUM, words[3])); |
2162 | if (cp->crc_size) { | 2136 | if (cp->crc_size) { |
2163 | /* checksum includes FCS. strip it out. */ | 2137 | /* checksum includes FCS. strip it out. */ |
2164 | i = csum_fold(csum_partial(crcaddr, cp->crc_size, i)); | 2138 | csum = csum_fold(csum_partial(crcaddr, cp->crc_size, |
2139 | csum_unfold(csum))); | ||
2165 | if (addr) | 2140 | if (addr) |
2166 | cas_page_unmap(addr); | 2141 | cas_page_unmap(addr); |
2167 | } | 2142 | } |
2168 | skb->csum = ntohs(i ^ 0xffff); | 2143 | skb->csum = csum_unfold(~csum); |
2169 | skb->ip_summed = CHECKSUM_COMPLETE; | 2144 | skb->ip_summed = CHECKSUM_COMPLETE; |
2170 | skb->protocol = eth_type_trans(skb, cp->dev); | 2145 | skb->protocol = eth_type_trans(skb, cp->dev); |
2171 | return len; | 2146 | return len; |
@@ -2253,7 +2228,7 @@ static int cas_post_rxds_ringN(struct cas *cp, int ring, int num) | |||
2253 | released = 0; | 2228 | released = 0; |
2254 | while (entry != last) { | 2229 | while (entry != last) { |
2255 | /* make a new buffer if it's still in use */ | 2230 | /* make a new buffer if it's still in use */ |
2256 | if (cas_buffer_count(page[entry]) > 1) { | 2231 | if (page_count(page[entry]->buffer) > 1) { |
2257 | cas_page_t *new = cas_page_dequeue(cp); | 2232 | cas_page_t *new = cas_page_dequeue(cp); |
2258 | if (!new) { | 2233 | if (!new) { |
2259 | /* let the timer know that we need to | 2234 | /* let the timer know that we need to |
@@ -2611,7 +2586,7 @@ static int cas_poll(struct napi_struct *napi, int budget) | |||
2611 | { | 2586 | { |
2612 | struct cas *cp = container_of(napi, struct cas, napi); | 2587 | struct cas *cp = container_of(napi, struct cas, napi); |
2613 | struct net_device *dev = cp->dev; | 2588 | struct net_device *dev = cp->dev; |
2614 | int i, enable_intr, todo, credits; | 2589 | int i, enable_intr, credits; |
2615 | u32 status = readl(cp->regs + REG_INTR_STATUS); | 2590 | u32 status = readl(cp->regs + REG_INTR_STATUS); |
2616 | unsigned long flags; | 2591 | unsigned long flags; |
2617 | 2592 | ||
@@ -4375,7 +4350,7 @@ static int cas_close(struct net_device *dev) | |||
4375 | struct cas *cp = netdev_priv(dev); | 4350 | struct cas *cp = netdev_priv(dev); |
4376 | 4351 | ||
4377 | #ifdef USE_NAPI | 4352 | #ifdef USE_NAPI |
4378 | napi_enable(&cp->napi); | 4353 | napi_disable(&cp->napi); |
4379 | #endif | 4354 | #endif |
4380 | /* Make sure we don't get distracted by suspend/resume */ | 4355 | /* Make sure we don't get distracted by suspend/resume */ |
4381 | mutex_lock(&cp->pm_mutex); | 4356 | mutex_lock(&cp->pm_mutex); |
@@ -4872,6 +4847,90 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
4872 | return rc; | 4847 | return rc; |
4873 | } | 4848 | } |
4874 | 4849 | ||
4850 | /* When this chip sits underneath an Intel 31154 bridge, it is the | ||
4851 | * only subordinate device and we can tweak the bridge settings to | ||
4852 | * reflect that fact. | ||
4853 | */ | ||
4854 | static void __devinit cas_program_bridge(struct pci_dev *cas_pdev) | ||
4855 | { | ||
4856 | struct pci_dev *pdev = cas_pdev->bus->self; | ||
4857 | u32 val; | ||
4858 | |||
4859 | if (!pdev) | ||
4860 | return; | ||
4861 | |||
4862 | if (pdev->vendor != 0x8086 || pdev->device != 0x537c) | ||
4863 | return; | ||
4864 | |||
4865 | /* Clear bit 10 (Bus Parking Control) in the Secondary | ||
4866 | * Arbiter Control/Status Register which lives at offset | ||
4867 | * 0x41. Using a 32-bit word read/modify/write at 0x40 | ||
4868 | * is much simpler so that's how we do this. | ||
4869 | */ | ||
4870 | pci_read_config_dword(pdev, 0x40, &val); | ||
4871 | val &= ~0x00040000; | ||
4872 | pci_write_config_dword(pdev, 0x40, val); | ||
4873 | |||
4874 | /* Max out the Multi-Transaction Timer settings since | ||
4875 | * Cassini is the only device present. | ||
4876 | * | ||
4877 | * The register is 16-bit and lives at 0x50. When the | ||
4878 | * settings are enabled, it extends the GRANT# signal | ||
4879 | * for a requestor after a transaction is complete. This | ||
4880 | * allows the next request to run without first needing | ||
4881 | * to negotiate the GRANT# signal back. | ||
4882 | * | ||
4883 | * Bits 12:10 define the grant duration: | ||
4884 | * | ||
4885 | * 1 -- 16 clocks | ||
4886 | * 2 -- 32 clocks | ||
4887 | * 3 -- 64 clocks | ||
4888 | * 4 -- 128 clocks | ||
4889 | * 5 -- 256 clocks | ||
4890 | * | ||
4891 | * All other values are illegal. | ||
4892 | * | ||
4893 | * Bits 09:00 define which REQ/GNT signal pairs get the | ||
4894 | * GRANT# signal treatment. We set them all. | ||
4895 | */ | ||
4896 | pci_write_config_word(pdev, 0x50, (5 << 10) | 0x3ff); | ||
4897 | |||
4898 | /* The Read Prefecth Policy register is 16-bit and sits at | ||
4899 | * offset 0x52. It enables a "smart" pre-fetch policy. We | ||
4900 | * enable it and max out all of the settings since only one | ||
4901 | * device is sitting underneath and thus bandwidth sharing is | ||
4902 | * not an issue. | ||
4903 | * | ||
4904 | * The register has several 3 bit fields, which indicates a | ||
4905 | * multiplier applied to the base amount of prefetching the | ||
4906 | * chip would do. These fields are at: | ||
4907 | * | ||
4908 | * 15:13 --- ReRead Primary Bus | ||
4909 | * 12:10 --- FirstRead Primary Bus | ||
4910 | * 09:07 --- ReRead Secondary Bus | ||
4911 | * 06:04 --- FirstRead Secondary Bus | ||
4912 | * | ||
4913 | * Bits 03:00 control which REQ/GNT pairs the prefetch settings | ||
4914 | * get enabled on. Bit 3 is a grouped enabler which controls | ||
4915 | * all of the REQ/GNT pairs from [8:3]. Bits 2 to 0 control | ||
4916 | * the individual REQ/GNT pairs [2:0]. | ||
4917 | */ | ||
4918 | pci_write_config_word(pdev, 0x52, | ||
4919 | (0x7 << 13) | | ||
4920 | (0x7 << 10) | | ||
4921 | (0x7 << 7) | | ||
4922 | (0x7 << 4) | | ||
4923 | (0xf << 0)); | ||
4924 | |||
4925 | /* Force cacheline size to 0x8 */ | ||
4926 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); | ||
4927 | |||
4928 | /* Force latency timer to maximum setting so Cassini can | ||
4929 | * sit on the bus as long as it likes. | ||
4930 | */ | ||
4931 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xff); | ||
4932 | } | ||
4933 | |||
4875 | static int __devinit cas_init_one(struct pci_dev *pdev, | 4934 | static int __devinit cas_init_one(struct pci_dev *pdev, |
4876 | const struct pci_device_id *ent) | 4935 | const struct pci_device_id *ent) |
4877 | { | 4936 | { |
@@ -4927,6 +4986,8 @@ static int __devinit cas_init_one(struct pci_dev *pdev, | |||
4927 | printk(KERN_WARNING PFX "Could not enable MWI for %s\n", | 4986 | printk(KERN_WARNING PFX "Could not enable MWI for %s\n", |
4928 | pci_name(pdev)); | 4987 | pci_name(pdev)); |
4929 | 4988 | ||
4989 | cas_program_bridge(pdev); | ||
4990 | |||
4930 | /* | 4991 | /* |
4931 | * On some architectures, the default cache line size set | 4992 | * On some architectures, the default cache line size set |
4932 | * by pci_try_set_mwi reduces perforamnce. We have to increase | 4993 | * by pci_try_set_mwi reduces perforamnce. We have to increase |