]> bbs.cooldavid.org Git - jme.git/blame - jme.c
Import jme 0.4 source
[jme.git] / jme.c
CommitLineData
d7699f87
GFT
1/*
2 * JMicron JMC2x0 series PCIe Ethernet Linux Device Driver
3 *
4 * Copyright 2008 JMicron Technology Corporation
5 * http://www.jmicron.com/
6 *
3bf61c55
GFT
7 * Author: Guo-Fu Tseng <cooldavid@cooldavid.org>
8 *
d7699f87
GFT
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
3bf61c55
GFT
24/*
25 * Note:
26 * Watchdog:
27 * check if rx queue stoped.
28 * And restart it after rx ring cleaned.
29 */
30
d7699f87 31/*
4330c2f2 32 * Timeline before release:
4330c2f2
GFT
33 * Stage 2: Error handling.
34 * - Wathch dog
35 * - Transmit timeout
36 *
37 * Stage 3: Basic offloading support.
3bf61c55 38 * - Use pci_map_page on scattered sk_buff for HIGHMEM support
4330c2f2
GFT
39 * - Implement scatter-gather offloading.
40 * A system page per RX (buffer|descriptor)?
41 * Handle fraged sk_buff to TX descriptors.
42 * - Implement tx/rx ipv6/ip/tcp/udp checksum offloading
43 *
44 * Stage 4: Basic feature support.
45 * - Implement Power Managemt related functions.
46 * - Implement Jumboframe.
47 * - Implement MSI.
48 *
49 * Stage 5: Advanced offloading support.
50 * - Implement VLAN offloading.
51 * - Implement TCP Segement offloading.
52 *
53 * Stage 6: CPU Load balancing.
54 * - Implement MSI-X.
55 * Along with multiple RX queue, for CPU load balancing.
4330c2f2
GFT
56 *
57 * Stage 7:
3bf61c55
GFT
58 * - Use NAPI instead of rx_tasklet?
59 * PCC Support Both Packet Counter and Timeout Interrupt for
60 * receive and transmit complete, does NAPI really needed?
4330c2f2
GFT
61 * - Cleanup/re-orginize code, performence tuneing(alignment etc...).
62 * - Test and Release 1.0
d7699f87
GFT
63 */
64
4330c2f2 65#include <linux/version.h>
d7699f87
GFT
66#include <linux/module.h>
67#include <linux/kernel.h>
68#include <linux/pci.h>
69#include <linux/netdevice.h>
70#include <linux/etherdevice.h>
71#include <linux/ethtool.h>
72#include <linux/mii.h>
73#include <linux/crc32.h>
4330c2f2 74#include <linux/delay.h>
d7699f87
GFT
75#include "jme.h"
76
4330c2f2 77#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21)
3bf61c55
GFT
78static struct net_device_stats *
79jme_get_stats(struct net_device *netdev)
4330c2f2
GFT
80{
81 struct jme_adapter *jme = netdev_priv(netdev);
82 return &jme->stats;
83}
84#endif
85
3bf61c55
GFT
86static int
87jme_mdio_read(struct net_device *netdev, int phy, int reg)
d7699f87
GFT
88{
89 struct jme_adapter *jme = netdev_priv(netdev);
90 int i, val;
91
92 jwrite32(jme, JME_SMI, SMI_OP_REQ |
3bf61c55
GFT
93 smi_phy_addr(phy) |
94 smi_reg_addr(reg));
d7699f87
GFT
95
96 wmb();
97 for (i = JME_PHY_TIMEOUT; i > 0; --i) {
3bf61c55
GFT
98 udelay(1);
99 if (((val = jread32(jme, JME_SMI)) & SMI_OP_REQ) == 0)
100 break;
d7699f87
GFT
101 }
102
103 if (i == 0) {
3bf61c55
GFT
104 jeprintk(netdev->name, "phy read timeout : %d\n", reg);
105 return 0;
d7699f87
GFT
106 }
107
3bf61c55 108 return ((val & SMI_DATA_MASK) >> SMI_DATA_SHIFT);
d7699f87
GFT
109}
110
3bf61c55
GFT
111static void
112jme_mdio_write(struct net_device *netdev,
113 int phy, int reg, int val)
d7699f87
GFT
114{
115 struct jme_adapter *jme = netdev_priv(netdev);
116 int i;
117
3bf61c55
GFT
118 jwrite32(jme, JME_SMI, SMI_OP_WRITE | SMI_OP_REQ |
119 ((val << SMI_DATA_SHIFT) & SMI_DATA_MASK) |
120 smi_phy_addr(phy) | smi_reg_addr(reg));
d7699f87
GFT
121
122 wmb();
3bf61c55
GFT
123 for (i = JME_PHY_TIMEOUT ; i > 0 ; --i) {
124 udelay(1);
125 if (((val = jread32(jme, JME_SMI)) & SMI_OP_REQ) == 0)
126 break;
127 }
d7699f87 128
3bf61c55
GFT
129 if (i == 0)
130 jeprintk(netdev->name, "phy write timeout : %d\n", reg);
d7699f87 131
3bf61c55 132 return;
d7699f87
GFT
133}
134
3bf61c55
GFT
135__always_inline static void
136jme_reset_phy_processor(struct jme_adapter *jme)
d7699f87 137{
fcf45b4c 138 __u32 val;
3bf61c55
GFT
139
140 jme_mdio_write(jme->dev,
141 jme->mii_if.phy_id,
142 MII_ADVERTISE, ADVERTISE_ALL);
143
144 jme_mdio_write(jme->dev,
145 jme->mii_if.phy_id,
146 MII_CTRL1000,
147 ADVERTISE_1000FULL | ADVERTISE_1000HALF);
148
fcf45b4c
GFT
149 val = jme_mdio_read(jme->dev,
150 jme->mii_if.phy_id,
151 MII_BMCR);
152
153 jme_mdio_write(jme->dev,
154 jme->mii_if.phy_id,
155 MII_BMCR, val | BMCR_RESET);
156
3bf61c55
GFT
157 return;
158}
159
160
161__always_inline static void
162jme_reset_mac_processor(struct jme_adapter *jme)
163{
164 jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST);
d7699f87 165 udelay(2);
3bf61c55 166 jwrite32(jme, JME_GHC, jme->reg_ghc);
4330c2f2
GFT
167 jwrite32(jme, JME_RXMCHT_LO, 0x00000000);
168 jwrite32(jme, JME_RXMCHT_HI, 0x00000000);
d7699f87
GFT
169 jwrite32(jme, JME_WFODP, 0);
170 jwrite32(jme, JME_WFOI, 0);
4330c2f2
GFT
171 jwrite32(jme, JME_GPREG0, GPREG0_DEFAULT);
172 jwrite32(jme, JME_GPREG1, 0);
d7699f87
GFT
173}
174
3bf61c55
GFT
175__always_inline static void
176jme_clear_pm(struct jme_adapter *jme)
d7699f87
GFT
177{
178 jwrite32(jme, JME_PMCS, 0xFFFF0000);
4330c2f2 179 pci_set_power_state(jme->pdev, PCI_D0);
d7699f87
GFT
180}
181
3bf61c55
GFT
182static int
183jme_reload_eeprom(struct jme_adapter *jme)
d7699f87
GFT
184{
185 __u32 val;
186 int i;
187
188 val = jread32(jme, JME_SMBCSR);
189
190 if(val & SMBCSR_EEPROMD)
191 {
192 val |= SMBCSR_CNACK;
193 jwrite32(jme, JME_SMBCSR, val);
194 val |= SMBCSR_RELOAD;
195 jwrite32(jme, JME_SMBCSR, val);
196 mdelay(12);
197
198 for (i = JME_SMB_TIMEOUT; i > 0; --i)
199 {
200 mdelay(1);
201 if ((jread32(jme, JME_SMBCSR) & SMBCSR_RELOAD) == 0)
202 break;
203 }
204
205 if(i == 0) {
4330c2f2 206 jeprintk(jme->dev->name, "eeprom reload timeout\n");
d7699f87
GFT
207 return -EIO;
208 }
209 }
210 else
211 return -EIO;
3bf61c55 212
d7699f87
GFT
213 return 0;
214}
215
3bf61c55
GFT
216static void
217jme_load_macaddr(struct net_device *netdev)
d7699f87
GFT
218{
219 struct jme_adapter *jme = netdev_priv(netdev);
220 unsigned char macaddr[6];
221 __u32 val;
222
fcf45b4c 223 spin_lock(&jme->macaddr_lock);
4330c2f2 224 val = jread32(jme, JME_RXUMA_LO);
d7699f87
GFT
225 macaddr[0] = (val >> 0) & 0xFF;
226 macaddr[1] = (val >> 8) & 0xFF;
227 macaddr[2] = (val >> 16) & 0xFF;
228 macaddr[3] = (val >> 24) & 0xFF;
4330c2f2 229 val = jread32(jme, JME_RXUMA_HI);
d7699f87
GFT
230 macaddr[4] = (val >> 0) & 0xFF;
231 macaddr[5] = (val >> 8) & 0xFF;
232 memcpy(netdev->dev_addr, macaddr, 6);
fcf45b4c 233 spin_unlock(&jme->macaddr_lock);
3bf61c55
GFT
234}
235
fcf45b4c 236__always_inline static void
3bf61c55
GFT
237jme_set_rx_pcc(struct jme_adapter *jme, int p)
238{
239 switch(p) {
240 case PCC_P1:
241 jwrite32(jme, JME_PCCRX0,
242 ((PCC_P1_TO << PCCRXTO_SHIFT) & PCCRXTO_MASK) |
243 ((PCC_P1_CNT << PCCRX_SHIFT) & PCCRX_MASK));
244 break;
245 case PCC_P2:
246 jwrite32(jme, JME_PCCRX0,
247 ((PCC_P2_TO << PCCRXTO_SHIFT) & PCCRXTO_MASK) |
248 ((PCC_P2_CNT << PCCRX_SHIFT) & PCCRX_MASK));
249 break;
250 case PCC_P3:
251 jwrite32(jme, JME_PCCRX0,
252 ((PCC_P3_TO << PCCRXTO_SHIFT) & PCCRXTO_MASK) |
253 ((PCC_P3_CNT << PCCRX_SHIFT) & PCCRX_MASK));
254 break;
255 default:
256 break;
257 }
258
259 dprintk(jme->dev->name, "Switched to PCC_P%d\n", p);
d7699f87
GFT
260}
261
fcf45b4c 262static void
3bf61c55 263jme_start_irq(struct jme_adapter *jme)
d7699f87 264{
3bf61c55
GFT
265 register struct dynpcc_info *dpi = &(jme->dpi);
266
267 jme_set_rx_pcc(jme, PCC_P1);
268
269 dpi->check_point = jiffies + PCC_INTERVAL;
270 dpi->last_bytes = NET_STAT(jme).rx_bytes;
271 dpi->last_pkts = NET_STAT(jme).rx_packets;
272 dpi->cur = PCC_P1;
273 dpi->attempt = PCC_P1;
274 dpi->cnt = 0;
275
276 jwrite32(jme, JME_PCCTX,
277 ((60000 << PCCTXTO_SHIFT) & PCCTXTO_MASK) |
278 ((8 << PCCTX_SHIFT) & PCCTX_MASK) |
279 PCCTXQ0_EN
280 );
281
d7699f87
GFT
282 /*
283 * Enable Interrupts
284 */
285 jwrite32(jme, JME_IENS, INTR_ENABLE);
286}
287
3bf61c55
GFT
288__always_inline static void
289jme_stop_irq(struct jme_adapter *jme)
d7699f87
GFT
290{
291 /*
292 * Disable Interrupts
293 */
294 jwrite32(jme, JME_IENC, INTR_ENABLE);
295}
296
4330c2f2 297
3bf61c55
GFT
298__always_inline static void
299jme_enable_shadow(struct jme_adapter *jme)
4330c2f2
GFT
300{
301 jwrite32(jme,
302 JME_SHBA_LO,
303 ((__u32)jme->shadow_dma & ~((__u32)0x1F)) | SHBA_POSTEN);
304}
305
3bf61c55
GFT
306__always_inline static void
307jme_disable_shadow(struct jme_adapter *jme)
4330c2f2
GFT
308{
309 jwrite32(jme, JME_SHBA_LO, 0x0);
310}
311
fcf45b4c
GFT
312static int
313jme_check_link(struct net_device *netdev, int testonly)
d7699f87
GFT
314{
315 struct jme_adapter *jme = netdev_priv(netdev);
fcf45b4c 316 __u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT;
d7699f87 317 char linkmsg[32];
fcf45b4c 318 int rc = 0;
d7699f87
GFT
319
320 phylink = jread32(jme, JME_PHY_LINK);
321
322 if (phylink & PHY_LINK_UP) {
323 /*
324 * Keep polling for autoneg complete
325 */
fcf45b4c
GFT
326 while(!(phylink & PHY_LINK_SPEEDDPU_RESOLVED) && --cnt > 0) {
327 udelay(1);
d7699f87
GFT
328 phylink = jread32(jme, JME_PHY_LINK);
329 }
330
fcf45b4c
GFT
331 if(jme->phylink == phylink) {
332 rc = 1;
333 goto out;
334 }
335 if(testonly)
336 goto out;
337
338 jme->phylink = phylink;
339
d7699f87 340 if(!cnt)
fcf45b4c
GFT
341 jeprintk(netdev->name,
342 "Waiting speed resolve timeout.\n");
343
344 if(!(phylink & PHY_LINK_AUTONEG_COMPLETE))
345 jprintk(netdev->name,
346 "Link partener does not support AN.\n");
d7699f87
GFT
347
348 switch(phylink & PHY_LINK_SPEED_MASK) {
349 case PHY_LINK_SPEED_10M:
350 ghc = GHC_SPEED_10M;
351 strcpy(linkmsg, "10 Mbps, ");
352 break;
353 case PHY_LINK_SPEED_100M:
354 ghc = GHC_SPEED_100M;
355 strcpy(linkmsg, "100 Mbps, ");
356 break;
357 case PHY_LINK_SPEED_1000M:
358 ghc = GHC_SPEED_1000M;
359 strcpy(linkmsg, "1000 Mbps, ");
360 break;
361 default:
362 ghc = 0;
363 break;
364 }
365 ghc |= (phylink & PHY_LINK_DUPLEX) ? GHC_DPX : 0;
fcf45b4c 366
d7699f87 367 strcat(linkmsg, (phylink &PHY_LINK_DUPLEX) ?
fcf45b4c
GFT
368 "Full-Duplex, " :
369 "Half-Duplex, ");
370
371 if(phylink & PHY_LINK_MDI_STAT)
372 strcat(linkmsg, "MDI");
373 else
374 strcat(linkmsg, "MDI-X");
d7699f87
GFT
375
376 if(phylink & PHY_LINK_DUPLEX)
377 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT);
378 else
379 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT |
3bf61c55
GFT
380 TXMCS_BACKOFF |
381 TXMCS_CARRIERSENSE |
382 TXMCS_COLLISION);
d7699f87 383
fcf45b4c
GFT
384 jme->reg_ghc = ghc;
385 jwrite32(jme, JME_GHC, ghc);
386
4330c2f2 387 jprintk(netdev->name, "Link is up at %s.\n", linkmsg);
d7699f87
GFT
388 netif_carrier_on(netdev);
389 }
390 else {
fcf45b4c
GFT
391 if(testonly)
392 goto out;
393
4330c2f2 394 jprintk(netdev->name, "Link is down.\n");
fcf45b4c 395 jme->phylink = 0;
d7699f87
GFT
396 netif_carrier_off(netdev);
397 }
fcf45b4c
GFT
398
399out:
400 return rc;
d7699f87
GFT
401}
402
3bf61c55
GFT
403
404static int
405jme_alloc_txdesc(struct jme_adapter *jme,
406 int nr_alloc)
4330c2f2 407{
3bf61c55
GFT
408 struct jme_ring *txring = jme->txring;
409 int idx;
410
411 idx = txring->next_to_use;
412
413 if(unlikely(txring->nr_free < nr_alloc))
414 return -1;
415
416 spin_lock(&jme->tx_lock);
417 txring->nr_free -= nr_alloc;
418
419 if((txring->next_to_use += nr_alloc) >= RING_DESC_NR)
420 txring->next_to_use -= RING_DESC_NR;
421 spin_unlock(&jme->tx_lock);
422
423 return idx;
4330c2f2
GFT
424}
425
3bf61c55
GFT
426static int
427jme_set_new_txdesc(struct jme_adapter *jme,
428 struct sk_buff *skb)
d7699f87
GFT
429{
430 struct jme_ring *txring = jme->txring;
3bf61c55
GFT
431 volatile struct txdesc *txdesc = txring->desc, *ctxdesc;
432 struct jme_buffer_info *txbi = txring->bufinf, *ctxbi;
4330c2f2 433 dma_addr_t dmaaddr;
3bf61c55
GFT
434 int i, idx, nr_desc;
435
436 nr_desc = 2;
437 idx = jme_alloc_txdesc(jme, nr_desc);
438
439 if(unlikely(idx<0))
440 return NETDEV_TX_BUSY;
441
442 for(i = 1 ; i < nr_desc ; ++i) {
443 ctxdesc = txdesc + ((idx + i) & (RING_DESC_NR-1));
444 ctxbi = txbi + ((idx + i) & (RING_DESC_NR-1));
4330c2f2 445
3bf61c55
GFT
446 dmaaddr = pci_map_single(jme->pdev,
447 skb->data,
448 skb->len,
449 PCI_DMA_TODEVICE);
450
451 pci_dma_sync_single_for_device(jme->pdev,
452 dmaaddr,
453 skb->len,
454 PCI_DMA_TODEVICE);
455
456 ctxdesc->dw[0] = 0;
457 ctxdesc->dw[1] = 0;
458 ctxdesc->desc2.flags = TXFLAG_OWN;
459 if(jme->dev->features & NETIF_F_HIGHDMA)
460 ctxdesc->desc2.flags |= TXFLAG_64BIT;
461 ctxdesc->desc2.datalen = cpu_to_le16(skb->len);
462 ctxdesc->desc2.bufaddrh = cpu_to_le32((__u64)dmaaddr >> 32);
fcf45b4c
GFT
463 ctxdesc->desc2.bufaddrl = cpu_to_le32(
464 (__u64)dmaaddr & 0xFFFFFFFFUL);
3bf61c55
GFT
465
466 ctxbi->mapping = dmaaddr;
467 ctxbi->len = skb->len;
468 }
469
470 ctxdesc = txdesc + idx;
471 ctxbi = txbi + idx;
472
473 ctxdesc->dw[0] = 0;
474 ctxdesc->dw[1] = 0;
475 ctxdesc->dw[2] = 0;
476 ctxdesc->dw[3] = 0;
477 ctxdesc->desc1.pktsize = cpu_to_le16(skb->len);
d7699f87
GFT
478 /*
479 * Set OWN bit at final.
3bf61c55
GFT
480 * When kernel transmit faster than NIC.
481 * And NIC trying to send this descriptor before we tell
d7699f87
GFT
482 * it to start sending this TX queue.
483 * Other fields are already filled correctly.
484 */
485 wmb();
3bf61c55
GFT
486 ctxdesc->desc1.flags = TXFLAG_OWN | TXFLAG_INT;
487 /*
488 * Set tx buffer info after telling NIC to send
489 * For better tx_clean timing
490 */
491 wmb();
492 ctxbi->nr_desc = nr_desc;
493 ctxbi->skb = skb;
494
495 tx_dbg(jme->dev->name, "Xmit: %d+%d\n", idx, nr_desc);
d7699f87 496
3bf61c55 497 return 0;
d7699f87
GFT
498}
499
500
3bf61c55
GFT
501static int
502jme_setup_tx_resources(struct jme_adapter *jme)
d7699f87 503{
d7699f87
GFT
504 struct jme_ring *txring = &(jme->txring[0]);
505
506 txring->alloc = dma_alloc_coherent(&(jme->pdev->dev),
507 TX_RING_ALLOC_SIZE,
3bf61c55 508 &(txring->dmaalloc),
fcf45b4c
GFT
509 GFP_ATOMIC);
510
4330c2f2
GFT
511 if(!txring->alloc) {
512 txring->desc = NULL;
513 txring->dmaalloc = 0;
514 txring->dma = 0;
d7699f87 515 return -ENOMEM;
4330c2f2 516 }
d7699f87
GFT
517
518 /*
519 * 16 Bytes align
520 */
3bf61c55
GFT
521 txring->desc = (void*)ALIGN((unsigned long)(txring->alloc),
522 RING_DESC_ALIGN);
4330c2f2 523 txring->dma = ALIGN(txring->dmaalloc, RING_DESC_ALIGN);
d7699f87
GFT
524 txring->next_to_use = 0;
525 txring->next_to_clean = 0;
3bf61c55 526 txring->nr_free = RING_DESC_NR;
d7699f87
GFT
527
528 /*
529 * Initiallize Transmit Descriptors
530 */
531 memset(txring->alloc, 0, TX_RING_ALLOC_SIZE);
3bf61c55
GFT
532 memset(txring->bufinf, 0,
533 sizeof(struct jme_buffer_info) * RING_DESC_NR);
d7699f87
GFT
534
535 return 0;
536}
537
3bf61c55
GFT
538static void
539jme_free_tx_resources(struct jme_adapter *jme)
d7699f87
GFT
540{
541 int i;
542 struct jme_ring *txring = &(jme->txring[0]);
4330c2f2 543 struct jme_buffer_info *txbi = txring->bufinf;
d7699f87
GFT
544
545 if(txring->alloc) {
3bf61c55 546 for(i = 0 ; i < RING_DESC_NR ; ++i) {
4330c2f2
GFT
547 txbi = txring->bufinf + i;
548 if(txbi->skb) {
549 dev_kfree_skb(txbi->skb);
550 txbi->skb = NULL;
d7699f87 551 }
3bf61c55
GFT
552 txbi->mapping = 0;
553 txbi->len = 0;
554 txbi->nr_desc = 0;
d7699f87
GFT
555 }
556
557 dma_free_coherent(&(jme->pdev->dev),
558 TX_RING_ALLOC_SIZE,
559 txring->alloc,
560 txring->dmaalloc);
3bf61c55
GFT
561
562 txring->alloc = NULL;
563 txring->desc = NULL;
564 txring->dmaalloc = 0;
565 txring->dma = 0;
d7699f87 566 }
3bf61c55
GFT
567 txring->next_to_use = 0;
568 txring->next_to_clean = 0;
569 txring->nr_free = 0;
d7699f87
GFT
570
571}
572
3bf61c55
GFT
573__always_inline static void
574jme_enable_tx_engine(struct jme_adapter *jme)
d7699f87
GFT
575{
576 /*
577 * Select Queue 0
578 */
579 jwrite32(jme, JME_TXCS, TXCS_DEFAULT | TXCS_SELECT_QUEUE0);
580
581 /*
582 * Setup TX Queue 0 DMA Bass Address
583 */
fcf45b4c 584 jwrite32(jme, JME_TXDBA_LO, (__u64)jme->txring[0].dma & 0xFFFFFFFFUL);
3bf61c55 585 jwrite32(jme, JME_TXDBA_HI, (__u64)(jme->txring[0].dma) >> 32);
fcf45b4c 586 jwrite32(jme, JME_TXNDA, (__u64)jme->txring[0].dma & 0xFFFFFFFFUL);
d7699f87
GFT
587
588 /*
589 * Setup TX Descptor Count
590 */
591 jwrite32(jme, JME_TXQDC, RING_DESC_NR);
592
593 /*
594 * Enable TX Engine
595 */
596 wmb();
4330c2f2
GFT
597 jwrite32(jme, JME_TXCS, jme->reg_txcs |
598 TXCS_SELECT_QUEUE0 |
599 TXCS_ENABLE);
d7699f87
GFT
600
601}
602
3bf61c55
GFT
603__always_inline static void
604jme_disable_tx_engine(struct jme_adapter *jme)
d7699f87
GFT
605{
606 int i;
607 __u32 val;
608
609 /*
610 * Disable TX Engine
611 */
fcf45b4c 612 jwrite32(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0);
d7699f87
GFT
613
614 val = jread32(jme, JME_TXCS);
615 for(i = JME_TX_DISABLE_TIMEOUT ; (val & TXCS_ENABLE) && i > 0 ; --i)
616 {
fcf45b4c 617 mdelay(1);
d7699f87
GFT
618 val = jread32(jme, JME_TXCS);
619 }
620
621 if(!i)
4330c2f2 622 jeprintk(jme->dev->name, "Disable TX engine timeout.\n");
d7699f87
GFT
623
624
625}
626
3bf61c55
GFT
627static void
628jme_set_clean_rxdesc(struct jme_adapter *jme, int i)
d7699f87
GFT
629{
630 struct jme_ring *rxring = jme->rxring;
3bf61c55 631 register volatile struct rxdesc* rxdesc = rxring->desc;
4330c2f2
GFT
632 struct jme_buffer_info *rxbi = rxring->bufinf;
633 rxdesc += i;
634 rxbi += i;
635
636 rxdesc->dw[0] = 0;
637 rxdesc->dw[1] = 0;
3bf61c55 638 rxdesc->desc1.bufaddrh = cpu_to_le32((__u64)rxbi->mapping >> 32);
fcf45b4c
GFT
639 rxdesc->desc1.bufaddrl = cpu_to_le32(
640 (__u64)rxbi->mapping & 0xFFFFFFFFUL);
3bf61c55
GFT
641 rxdesc->desc1.datalen = cpu_to_le16(rxbi->len);
642 if(jme->dev->features & NETIF_F_HIGHDMA)
643 rxdesc->desc1.flags = RXFLAG_64BIT;
d7699f87 644 wmb();
3bf61c55 645 rxdesc->desc1.flags |= RXFLAG_OWN | RXFLAG_INT;
d7699f87
GFT
646}
647
3bf61c55
GFT
648static int
649jme_make_new_rx_buf(struct jme_adapter *jme, int i)
4330c2f2
GFT
650{
651 struct jme_ring *rxring = &(jme->rxring[0]);
652 struct jme_buffer_info *rxbi = rxring->bufinf;
653 unsigned long offset;
654 struct sk_buff* skb;
655
656 skb = netdev_alloc_skb(jme->dev, RX_BUF_ALLOC_SIZE);
657 if(unlikely(!skb))
658 return -ENOMEM;
3bf61c55
GFT
659
660 if(unlikely(skb_is_nonlinear(skb))) {
661 dprintk(jme->dev->name,
662 "Allocated skb fragged(%d).\n",
663 skb_shinfo(skb)->nr_frags);
4330c2f2
GFT
664 dev_kfree_skb(skb);
665 return -ENOMEM;
666 }
667
3bf61c55
GFT
668 if(unlikely(offset =
669 (unsigned long)(skb->data)
670 & (unsigned long)(RX_BUF_DMA_ALIGN - 1)))
4330c2f2 671 skb_reserve(skb, RX_BUF_DMA_ALIGN - offset);
4330c2f2
GFT
672
673 rxbi += i;
674 rxbi->skb = skb;
3bf61c55 675 rxbi->len = skb_tailroom(skb);
4330c2f2
GFT
676 rxbi->mapping = pci_map_single(jme->pdev,
677 skb->data,
3bf61c55 678 rxbi->len,
4330c2f2
GFT
679 PCI_DMA_FROMDEVICE);
680
681 return 0;
682}
683
3bf61c55
GFT
684static void
685jme_free_rx_buf(struct jme_adapter *jme, int i)
4330c2f2
GFT
686{
687 struct jme_ring *rxring = &(jme->rxring[0]);
688 struct jme_buffer_info *rxbi = rxring->bufinf;
689 rxbi += i;
690
691 if(rxbi->skb) {
692 pci_unmap_single(jme->pdev,
693 rxbi->mapping,
3bf61c55 694 rxbi->len,
4330c2f2
GFT
695 PCI_DMA_FROMDEVICE);
696 dev_kfree_skb(rxbi->skb);
697 rxbi->skb = NULL;
698 rxbi->mapping = 0;
3bf61c55 699 rxbi->len = 0;
4330c2f2
GFT
700 }
701}
702
3bf61c55
GFT
703static void
704jme_free_rx_resources(struct jme_adapter *jme)
705{
706 int i;
707 struct jme_ring *rxring = &(jme->rxring[0]);
708
709 if(rxring->alloc) {
710 for(i = 0 ; i < RING_DESC_NR ; ++i)
711 jme_free_rx_buf(jme, i);
712
713 dma_free_coherent(&(jme->pdev->dev),
714 RX_RING_ALLOC_SIZE,
715 rxring->alloc,
716 rxring->dmaalloc);
717 rxring->alloc = NULL;
718 rxring->desc = NULL;
719 rxring->dmaalloc = 0;
720 rxring->dma = 0;
721 }
722 rxring->next_to_use = 0;
723 rxring->next_to_clean = 0;
724}
725
726static int
727jme_setup_rx_resources(struct jme_adapter *jme)
d7699f87
GFT
728{
729 int i;
730 struct jme_ring *rxring = &(jme->rxring[0]);
731
732 rxring->alloc = dma_alloc_coherent(&(jme->pdev->dev),
733 RX_RING_ALLOC_SIZE,
3bf61c55 734 &(rxring->dmaalloc),
fcf45b4c 735 GFP_ATOMIC);
4330c2f2
GFT
736 if(!rxring->alloc) {
737 rxring->desc = NULL;
738 rxring->dmaalloc = 0;
739 rxring->dma = 0;
d7699f87 740 return -ENOMEM;
4330c2f2 741 }
d7699f87
GFT
742
743 /*
744 * 16 Bytes align
745 */
3bf61c55
GFT
746 rxring->desc = (void*)ALIGN((unsigned long)(rxring->alloc),
747 RING_DESC_ALIGN);
4330c2f2 748 rxring->dma = ALIGN(rxring->dmaalloc, RING_DESC_ALIGN);
d7699f87
GFT
749 rxring->next_to_use = 0;
750 rxring->next_to_clean = 0;
751
d7699f87
GFT
752 /*
753 * Initiallize Receive Descriptors
754 */
755 for(i = 0 ; i < RING_DESC_NR ; ++i) {
3bf61c55
GFT
756 if(unlikely(jme_make_new_rx_buf(jme, i))) {
757 jme_free_rx_resources(jme);
758 return -ENOMEM;
759 }
d7699f87
GFT
760
761 jme_set_clean_rxdesc(jme, i);
762 }
763
d7699f87
GFT
764 return 0;
765}
766
3bf61c55
GFT
767__always_inline static void
768jme_enable_rx_engine(struct jme_adapter *jme)
d7699f87 769{
d7699f87
GFT
770 /*
771 * Setup RX DMA Bass Address
772 */
fcf45b4c 773 jwrite32(jme, JME_RXDBA_LO, (__u64)jme->rxring[0].dma & 0xFFFFFFFFUL);
3bf61c55 774 jwrite32(jme, JME_RXDBA_HI, (__u64)(jme->rxring[0].dma) >> 32);
fcf45b4c 775 jwrite32(jme, JME_RXNDA, (__u64)jme->rxring[0].dma & 0xFFFFFFFFUL);
d7699f87
GFT
776
777 /*
778 * Setup RX Descptor Count
779 */
780 jwrite32(jme, JME_RXQDC, RING_DESC_NR);
781
3bf61c55 782 /*
d7699f87
GFT
783 * Setup Unicast Filter
784 */
3bf61c55 785 jme->reg_rxmcs = RXMCS_VTAGRM | RXMCS_PREPAD;
d7699f87
GFT
786 jme_set_multi(jme->dev);
787
788 /*
789 * Enable RX Engine
790 */
791 wmb();
4330c2f2
GFT
792 jwrite32(jme, JME_RXCS, RXCS_DEFAULT |
793 RXCS_QUEUESEL_Q0 |
794 RXCS_ENABLE |
795 RXCS_QST);
d7699f87
GFT
796}
797
3bf61c55
GFT
798__always_inline static void
799jme_restart_rx_engine(struct jme_adapter *jme)
4330c2f2
GFT
800{
801 /*
3bf61c55 802 * Start RX Engine
4330c2f2
GFT
803 */
804 jwrite32(jme, JME_RXCS, RXCS_DEFAULT |
805 RXCS_QUEUESEL_Q0 |
806 RXCS_ENABLE |
807 RXCS_QST);
808}
809
810
3bf61c55
GFT
811__always_inline static void
812jme_disable_rx_engine(struct jme_adapter *jme)
d7699f87
GFT
813{
814 int i;
815 __u32 val;
816
817 /*
818 * Disable RX Engine
819 */
820 val = jread32(jme, JME_RXCS);
821 val &= ~RXCS_ENABLE;
822 jwrite32(jme, JME_RXCS, val);
823
824 val = jread32(jme, JME_RXCS);
825 for(i = JME_RX_DISABLE_TIMEOUT ; (val & RXCS_ENABLE) && i > 0 ; --i)
826 {
fcf45b4c 827 mdelay(100);
d7699f87
GFT
828 val = jread32(jme, JME_RXCS);
829 }
830
831 if(!i)
4330c2f2 832 jeprintk(jme->dev->name, "Disable RX engine timeout.\n");
d7699f87
GFT
833
834}
835
3bf61c55
GFT
836static void
837jme_attempt_pcc(struct dynpcc_info *dpi, int atmp)
d7699f87 838{
3bf61c55
GFT
839 if(dpi->attempt == atmp) {
840 ++(dpi->cnt);
841 }
842 else {
843 dpi->attempt = atmp;
844 dpi->cnt = 0;
845 }
846}
4330c2f2 847
3bf61c55
GFT
848static void
849jme_dynamic_pcc(struct jme_adapter *jme)
850{
851 register struct dynpcc_info *dpi = &(jme->dpi);
4330c2f2 852
3bf61c55 853 if(jiffies >= dpi->check_point) {
fcf45b4c
GFT
854 if(jiffies > (dpi->check_point + PCC_INTERVAL))
855 jme_attempt_pcc(dpi, PCC_P1);
856 else if((NET_STAT(jme).rx_bytes - dpi->last_bytes) >
857 PCC_P3_THRESHOLD)
858 jme_attempt_pcc(dpi, PCC_P3);
859 else if((NET_STAT(jme).rx_bytes - dpi->last_bytes) >
860 PCC_P2_THRESHOLD)
861 jme_attempt_pcc(dpi, PCC_P2);
862 else
3bf61c55 863 jme_attempt_pcc(dpi, PCC_P1);
4330c2f2 864
3bf61c55
GFT
865 if(unlikely(dpi->attempt != dpi->cur && dpi->cnt > 5)) {
866 jme_set_rx_pcc(jme, dpi->attempt);
867 dpi->cur = dpi->attempt;
868 dpi->cnt = 0;
869 }
4330c2f2 870
3bf61c55
GFT
871 dpi->last_bytes = NET_STAT(jme).rx_bytes;
872 dpi->last_pkts = NET_STAT(jme).rx_packets;
873 dpi->check_point = jiffies + PCC_INTERVAL;
874 }
d7699f87
GFT
875}
876
3bf61c55
GFT
877static void
878jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
d7699f87 879{
d7699f87 880 struct jme_ring *rxring = &(jme->rxring[0]);
3bf61c55
GFT
881 volatile struct rxdesc *rxdesc = rxring->desc;
882 struct jme_buffer_info *rxbi = rxring->bufinf;
d7699f87 883 struct sk_buff *skb;
3bf61c55 884 int framesize;
d7699f87 885
3bf61c55
GFT
886 rxdesc += idx;
887 rxbi += idx;
d7699f87 888
3bf61c55
GFT
889 skb = rxbi->skb;
890 pci_dma_sync_single_for_cpu(jme->pdev,
891 rxbi->mapping,
892 rxbi->len,
893 PCI_DMA_FROMDEVICE);
894
895 if(unlikely(jme_make_new_rx_buf(jme, idx))) {
896 pci_dma_sync_single_for_device(jme->pdev,
897 rxbi->mapping,
898 rxbi->len,
899 PCI_DMA_FROMDEVICE);
900
901 ++(NET_STAT(jme).rx_dropped);
902 }
903 else {
904 framesize = le16_to_cpu(rxdesc->descwb.framesize)
905 - RX_PREPAD_SIZE;
906
907 skb_reserve(skb, RX_PREPAD_SIZE);
908 skb_put(skb, framesize);
909 skb->protocol = eth_type_trans(skb, jme->dev);
910
911 netif_rx(skb);
912
913 if(le16_to_cpu(rxdesc->descwb.flags) & RXWBFLAG_DEST_MUL)
914 ++(NET_STAT(jme).multicast);
915
916 jme->dev->last_rx = jiffies;
917 NET_STAT(jme).rx_bytes += framesize;
918 ++(NET_STAT(jme).rx_packets);
919 }
920
921 jme_set_clean_rxdesc(jme, idx);
922
fcf45b4c
GFT
923 jme_dynamic_pcc(jme);
924
3bf61c55
GFT
925}
926
927static int
928jme_process_receive(struct jme_adapter *jme, int limit)
929{
930 struct jme_ring *rxring = &(jme->rxring[0]);
931 volatile struct rxdesc *rxdesc = rxring->desc;
932 int i, j, ccnt, desccnt;
933
934 i = rxring->next_to_clean;
935 while( limit-- > 0 )
d7699f87 936 {
3bf61c55
GFT
937 rxdesc = rxring->desc;
938 rxdesc += i;
939
4330c2f2 940 if((rxdesc->descwb.flags & RXWBFLAG_OWN) ||
3bf61c55
GFT
941 !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL))
942 goto out;
d7699f87 943
4330c2f2
GFT
944 desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT;
945
3bf61c55 946 rx_dbg(jme->dev->name, "RX: Cleaning %d\n", i);
4330c2f2 947
3bf61c55
GFT
948 if(desccnt > 1 ||
949 rxdesc->descwb.errstat & RXWBERR_ALLERR) {
d7699f87 950
3bf61c55
GFT
951 if(rxdesc->descwb.errstat & RXWBERR_CRCERR)
952 ++(NET_STAT(jme).rx_crc_errors);
953 else if(rxdesc->descwb.errstat & RXWBERR_OVERUN)
954 ++(NET_STAT(jme).rx_fifo_errors);
955 else
956 ++(NET_STAT(jme).rx_errors);
4330c2f2
GFT
957
958 if(desccnt > 1)
3bf61c55 959 limit -= desccnt - 1;
4330c2f2 960
3bf61c55 961 for(j = i, ccnt = desccnt ; ccnt-- ; ) {
4330c2f2
GFT
962 jme_set_clean_rxdesc(jme, j);
963
964 if(unlikely(++j == RING_DESC_NR))
965 j = 0;
966 }
3bf61c55 967
d7699f87
GFT
968 }
969 else {
3bf61c55
GFT
970 jme_alloc_and_feed_skb(jme, i);
971 }
4330c2f2 972
4330c2f2 973
3bf61c55
GFT
974 if((i += desccnt) >= RING_DESC_NR)
975 i -= RING_DESC_NR;
976 }
4330c2f2 977
3bf61c55
GFT
978out:
979 rx_dbg(jme->dev->name, "RX: Stop at %d\n", i);
980 rx_dbg(jme->dev->name, "RX: RXNDA offset %d\n",
981 (jread32(jme, JME_RXNDA) - jread32(jme, JME_RXDBA_LO))
982 >> 4);
4330c2f2 983
3bf61c55 984 rxring->next_to_clean = i;
4330c2f2 985
3bf61c55 986 return limit > 0 ? limit : 0;
4330c2f2 987
3bf61c55 988}
d7699f87 989
3bf61c55
GFT
990static void
991jme_link_change_tasklet(unsigned long arg)
992{
993 struct jme_adapter *jme = (struct jme_adapter*)arg;
fcf45b4c
GFT
994 struct net_device *netdev = jme->dev;
995 int timeout = WAIT_TASKLET_TIMEOUT;
996 int rc;
997
998 if(!atomic_dec_and_test(&jme->link_changing))
999 goto out;
1000
1001 if(jme_check_link(netdev, 1))
1002 goto out;
1003
1004 netif_stop_queue(netdev);
1005
1006 while(--timeout > 0 &&
1007 (
1008 atomic_read(&jme->rx_cleaning) != 1 ||
1009 atomic_read(&jme->tx_cleaning) != 1
1010 )) {
1011
1012 mdelay(1);
1013 }
1014
1015 if(netif_carrier_ok(netdev)) {
1016 jme_reset_mac_processor(jme);
1017 jme_free_rx_resources(jme);
1018 jme_free_tx_resources(jme);
1019 }
1020
1021 jme_check_link(netdev, 0);
1022 if(netif_carrier_ok(netdev)) {
1023 rc = jme_setup_rx_resources(jme);
1024 if(rc) {
1025 jeprintk(netdev->name,
1026 "Allocating resources for RX error"
1027 ", Device STOPPED!\n");
1028 goto out;
1029 }
1030
1031
1032 rc = jme_setup_tx_resources(jme);
1033 if(rc) {
1034 jeprintk(netdev->name,
1035 "Allocating resources for TX error"
1036 ", Device STOPPED!\n");
1037 goto err_out_free_rx_resources;
1038 }
1039
1040 jme_enable_rx_engine(jme);
1041 jme_enable_tx_engine(jme);
1042
1043 netif_start_queue(netdev);
1044 }
1045
1046 goto out;
1047
1048err_out_free_rx_resources:
1049 jme_free_rx_resources(jme);
1050out:
1051 atomic_inc(&jme->link_changing);
3bf61c55 1052}
d7699f87 1053
3bf61c55
GFT
1054static void
1055jme_rx_clean_tasklet(unsigned long arg)
1056{
1057 struct jme_adapter *jme = (struct jme_adapter*)arg;
d7699f87 1058
fcf45b4c
GFT
1059 if(!atomic_dec_and_test(&jme->rx_cleaning))
1060 goto out;
1061
1062 if(atomic_read(&jme->link_changing) != 1)
1063 goto out;
1064
1065 if(unlikely(netif_queue_stopped(jme->dev)))
1066 goto out;
1067
3bf61c55 1068 jme_process_receive(jme, RING_DESC_NR);
fcf45b4c
GFT
1069
1070out:
1071 atomic_inc(&jme->rx_cleaning);
1072}
1073
1074static void
1075jme_rx_empty_tasklet(unsigned long arg)
1076{
1077 struct jme_adapter *jme = (struct jme_adapter*)arg;
1078
1079 if(atomic_read(&jme->link_changing) != 1)
1080 return;
1081
1082 if(unlikely(netif_queue_stopped(jme->dev)))
1083 return;
1084
1085 jme_rx_clean_tasklet(arg);
1086 jme_restart_rx_engine(jme);
4330c2f2
GFT
1087}
1088
3bf61c55
GFT
1089static void
1090jme_tx_clean_tasklet(unsigned long arg)
4330c2f2
GFT
1091{
1092 struct jme_adapter *jme = (struct jme_adapter*)arg;
3bf61c55
GFT
1093 struct jme_ring *txring = &(jme->txring[0]);
1094 volatile struct txdesc *txdesc = txring->desc;
1095 struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi;
1096 int i, j, cnt = 0, max;
1097
fcf45b4c
GFT
1098 if(!atomic_dec_and_test(&jme->tx_cleaning))
1099 goto out;
1100
1101 if(atomic_read(&jme->link_changing) != 1)
1102 goto out;
1103
1104 if(unlikely(netif_queue_stopped(jme->dev)))
1105 goto out;
1106
3bf61c55
GFT
1107 spin_lock(&jme->tx_lock);
1108 max = RING_DESC_NR - txring->nr_free;
1109 spin_unlock(&jme->tx_lock);
1110
1111 tx_dbg(jme->dev->name, "Tx Tasklet: In\n");
1112
1113 for(i = txring->next_to_clean ; cnt < max ; ) {
1114
1115 ctxbi = txbi + i;
1116
1117 if(ctxbi->skb && !(txdesc[i].desc1.flags & TXFLAG_OWN)) {
1118
1119 tx_dbg(jme->dev->name,
1120 "Tx Tasklet: Clean %d+%d\n",
1121 i, ctxbi->nr_desc);
1122
1123 for(j = 1 ; j < ctxbi->nr_desc ; ++j) {
1124 ttxbi = txbi + ((i + j) & (RING_DESC_NR - 1));
1125 txdesc[(i+j)&(RING_DESC_NR-1)].dw[0] = 0;
1126
1127 pci_unmap_single(jme->pdev,
1128 ttxbi->mapping,
1129 ttxbi->len,
1130 PCI_DMA_TODEVICE);
1131
1132 NET_STAT(jme).tx_bytes += ttxbi->len;
1133 ttxbi->mapping = 0;
1134 ttxbi->len = 0;
1135 }
1136
1137 dev_kfree_skb(ctxbi->skb);
1138 ctxbi->skb = NULL;
1139
1140 cnt += ctxbi->nr_desc;
1141
1142 ++(NET_STAT(jme).tx_packets);
1143 }
1144 else {
1145 if(!ctxbi->skb)
1146 tx_dbg(jme->dev->name,
1147 "Tx Tasklet:"
1148 " Stoped due to no skb.\n");
1149 else
1150 tx_dbg(jme->dev->name,
1151 "Tx Tasklet:"
1152 "Stoped due to not done.\n");
1153 break;
1154 }
1155
1156 if(unlikely((i += ctxbi->nr_desc) >= RING_DESC_NR))
1157 i -= RING_DESC_NR;
1158
1159 ctxbi->nr_desc = 0;
d7699f87
GFT
1160 }
1161
3bf61c55
GFT
1162 tx_dbg(jme->dev->name,
1163 "Tx Tasklet: Stop %d Jiffies %lu\n",
1164 i, jiffies);
1165 txring->next_to_clean = i;
1166
1167 spin_lock(&jme->tx_lock);
1168 txring->nr_free += cnt;
1169 spin_unlock(&jme->tx_lock);
1170
fcf45b4c
GFT
1171out:
1172 atomic_inc(&jme->tx_cleaning);
d7699f87
GFT
1173}
1174
3bf61c55
GFT
1175static irqreturn_t
1176jme_intr(int irq, void *dev_id)
d7699f87
GFT
1177{
1178 struct net_device *netdev = dev_id;
1179 struct jme_adapter *jme = netdev_priv(netdev);
1180 irqreturn_t rc = IRQ_HANDLED;
4330c2f2
GFT
1181 __u32 intrstat;
1182
1183#if USE_IEVE_SHADOW
1184 pci_dma_sync_single_for_cpu(jme->pdev,
1185 jme->shadow_dma,
1186 sizeof(__u32) * SHADOW_REG_NR,
1187 PCI_DMA_FROMDEVICE);
1188 intrstat = jme->shadow_regs[SHADOW_IEVE];
1189 jme->shadow_regs[SHADOW_IEVE] = 0;
1190#else
1191 intrstat = jread32(jme, JME_IEVE);
d7699f87
GFT
1192#endif
1193
d7699f87
GFT
1194 /*
1195 * Check if it's really an interrupt for us
d7699f87 1196 */
3bf61c55 1197 if(intrstat == 0) {
4330c2f2
GFT
1198 rc = IRQ_NONE;
1199 goto out;
1200 }
3bf61c55
GFT
1201
1202 /*
1203 * Check if the device still exist
1204 */
4330c2f2 1205 if(unlikely(intrstat == ~((typeof(intrstat))0))) {
d7699f87
GFT
1206 rc = IRQ_NONE;
1207 goto out;
1208 }
1209
3bf61c55
GFT
1210 /*
1211 * Allow one interrupt handling at a time
1212 */
1213 if(unlikely(!atomic_dec_and_test(&jme->intr_sem)))
fcf45b4c 1214 goto out_inc;
4330c2f2 1215
3bf61c55
GFT
1216 /*
1217 * Disable interrupt
1218 */
1219 jwrite32f(jme, JME_IENC, INTR_ENABLE);
d7699f87 1220
fcf45b4c 1221 if(intrstat & INTR_LINKCH) {
3bf61c55 1222 tasklet_schedule(&jme->linkch_task);
fcf45b4c
GFT
1223 goto out_deassert;
1224 }
d7699f87 1225
fcf45b4c
GFT
1226 if(intrstat & INTR_RX0EMP)
1227 tasklet_schedule(&jme->rxempty_task);
d7699f87 1228
fcf45b4c 1229 if(intrstat & (INTR_PCCRX0TO | INTR_PCCRX0))
4330c2f2 1230 tasklet_schedule(&jme->rxclean_task);
d7699f87 1231
3bf61c55 1232 if(intrstat & (INTR_PCCTXTO | INTR_PCCTX))
4330c2f2 1233 tasklet_schedule(&jme->txclean_task);
d7699f87 1234
4330c2f2 1235 if((intrstat & ~INTR_ENABLE) != 0) {
3bf61c55
GFT
1236 /*
1237 * Some interrupt not handled
1238 * but not enabled also (for debug)
1239 */
4330c2f2 1240 }
d7699f87 1241
fcf45b4c 1242out_deassert:
d7699f87 1243 /*
4330c2f2 1244 * Deassert interrupts
d7699f87 1245 */
3bf61c55
GFT
1246 jwrite32f(jme, JME_IEVE, intrstat);
1247
1248 /*
fcf45b4c 1249 * Re-enable interrupt
3bf61c55 1250 */
fcf45b4c 1251 jwrite32f(jme, JME_IENS, INTR_ENABLE);
3bf61c55 1252
fcf45b4c 1253out_inc:
3bf61c55 1254 /*
fcf45b4c 1255 * Enable next interrupt handling
3bf61c55 1256 */
fcf45b4c 1257 atomic_inc(&jme->intr_sem);
4330c2f2
GFT
1258
1259out:
d7699f87
GFT
1260 return rc;
1261}
1262
fcf45b4c
GFT
1263static void
1264jme_restart_an(struct jme_adapter *jme)
1265{
1266 __u32 bmcr;
1267
1268 bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
1269 bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
1270 jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
1271}
1272
3bf61c55
GFT
1273static int
1274jme_open(struct net_device *netdev)
d7699f87
GFT
1275{
1276 struct jme_adapter *jme = netdev_priv(netdev);
fcf45b4c
GFT
1277 int rc, timeout = 100;
1278
1279 while(
1280 --timeout > 0 &&
1281 (
1282 atomic_read(&jme->link_changing) != 1 ||
1283 atomic_read(&jme->rx_cleaning) != 1 ||
1284 atomic_read(&jme->tx_cleaning) != 1
1285 )
1286 )
1287 msleep(10);
1288
1289 jme_reset_mac_processor(jme);
d7699f87 1290
4330c2f2
GFT
1291 rc = request_irq(jme->pdev->irq, jme_intr,
1292 IRQF_SHARED, netdev->name, netdev);
1293 if(rc) {
1294 printk(KERN_ERR PFX "Requesting IRQ error.\n");
1295 goto err_out;
1296 }
4330c2f2 1297 jme_enable_shadow(jme);
d7699f87 1298 jme_start_irq(jme);
fcf45b4c 1299 jme_restart_an(jme);
d7699f87
GFT
1300
1301 return 0;
1302
d7699f87
GFT
1303err_out:
1304 netif_stop_queue(netdev);
1305 netif_carrier_off(netdev);
4330c2f2 1306 return rc;
d7699f87
GFT
1307}
1308
3bf61c55
GFT
1309static int
1310jme_close(struct net_device *netdev)
d7699f87
GFT
1311{
1312 struct jme_adapter *jme = netdev_priv(netdev);
1313
1314 netif_stop_queue(netdev);
1315 netif_carrier_off(netdev);
1316
1317 jme_stop_irq(jme);
4330c2f2 1318 jme_disable_shadow(jme);
d7699f87
GFT
1319 free_irq(jme->pdev->irq, jme->dev);
1320
4330c2f2
GFT
1321 tasklet_kill(&jme->linkch_task);
1322 tasklet_kill(&jme->txclean_task);
1323 tasklet_kill(&jme->rxclean_task);
fcf45b4c 1324 tasklet_kill(&jme->rxempty_task);
d7699f87
GFT
1325 jme_disable_rx_engine(jme);
1326 jme_disable_tx_engine(jme);
1327 jme_free_rx_resources(jme);
1328 jme_free_tx_resources(jme);
1329
1330 return 0;
1331}
1332
3bf61c55
GFT
1333/*
1334 * This function is already protected by netif_tx_lock()
1335 */
1336static int
1337jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
d7699f87
GFT
1338{
1339 struct jme_adapter *jme = netdev_priv(netdev);
3bf61c55 1340 int rc;
d7699f87 1341
fcf45b4c
GFT
1342 if(unlikely(netif_queue_stopped(jme->dev)))
1343 return NETDEV_TX_BUSY;
1344
3bf61c55 1345 rc = jme_set_new_txdesc(jme, skb);
d7699f87 1346
3bf61c55
GFT
1347 if(unlikely(rc != NETDEV_TX_OK))
1348 return rc;
d7699f87 1349
4330c2f2
GFT
1350 jwrite32(jme, JME_TXCS, jme->reg_txcs |
1351 TXCS_SELECT_QUEUE0 |
1352 TXCS_QUEUE0S |
1353 TXCS_ENABLE);
d7699f87
GFT
1354 netdev->trans_start = jiffies;
1355
4330c2f2 1356 return NETDEV_TX_OK;
d7699f87
GFT
1357}
1358
3bf61c55
GFT
1359static int
1360jme_set_macaddr(struct net_device *netdev, void *p)
d7699f87
GFT
1361{
1362 struct jme_adapter *jme = netdev_priv(netdev);
1363 struct sockaddr *addr = p;
1364 __u32 val;
1365
1366 if(netif_running(netdev))
1367 return -EBUSY;
1368
fcf45b4c 1369 spin_lock(&jme->macaddr_lock);
d7699f87
GFT
1370 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
1371
1372 val = addr->sa_data[3] << 24 |
1373 addr->sa_data[2] << 16 |
1374 addr->sa_data[1] << 8 |
1375 addr->sa_data[0];
4330c2f2 1376 jwrite32(jme, JME_RXUMA_LO, val);
d7699f87
GFT
1377 val = addr->sa_data[5] << 8 |
1378 addr->sa_data[4];
4330c2f2 1379 jwrite32(jme, JME_RXUMA_HI, val);
fcf45b4c 1380 spin_unlock(&jme->macaddr_lock);
d7699f87
GFT
1381
1382 return 0;
1383}
1384
3bf61c55
GFT
1385static void
1386jme_set_multi(struct net_device *netdev)
d7699f87 1387{
3bf61c55 1388 struct jme_adapter *jme = netdev_priv(netdev);
d7699f87
GFT
1389 u32 mc_hash[2] = {};
1390 __u32 val;
1391 int i;
1392
3bf61c55 1393 val = jme->reg_rxmcs | RXMCS_BRDFRAME | RXMCS_UNIFRAME;
d7699f87 1394
3bf61c55 1395 if (netdev->flags & IFF_PROMISC) {
d7699f87 1396 val |= RXMCS_ALLFRAME;
3bf61c55
GFT
1397 }
1398 else if (netdev->flags & IFF_ALLMULTI) {
d7699f87 1399 val |= RXMCS_ALLMULFRAME;
3bf61c55 1400 }
d7699f87 1401 else if(netdev->flags & IFF_MULTICAST) {
3bf61c55
GFT
1402 struct dev_mc_list *mclist;
1403 int bit_nr;
d7699f87
GFT
1404
1405 val |= RXMCS_MULFRAME | RXMCS_MULFILTERED;
3bf61c55
GFT
1406 for (i = 0, mclist = netdev->mc_list;
1407 mclist && i < netdev->mc_count;
1408 ++i, mclist = mclist->next) {
1409
d7699f87
GFT
1410 bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3F;
1411 mc_hash[bit_nr >> 5] |= 1 << (bit_nr & 0x1F);
d7699f87
GFT
1412 }
1413
4330c2f2
GFT
1414 jwrite32(jme, JME_RXMCHT_LO, mc_hash[0]);
1415 jwrite32(jme, JME_RXMCHT_HI, mc_hash[1]);
d7699f87
GFT
1416 }
1417
1418
1419 wmb();
1420 jwrite32(jme, JME_RXMCS, val);
d7699f87
GFT
1421}
1422
3bf61c55
GFT
1423static int
1424jme_change_mtu(struct net_device *dev, int new_mtu)
d7699f87
GFT
1425{
1426 /*
3bf61c55 1427 * Not supporting MTU change for now.
d7699f87
GFT
1428 */
1429 return -EINVAL;
1430}
1431
3bf61c55
GFT
1432static void
1433jme_get_drvinfo(struct net_device *netdev,
1434 struct ethtool_drvinfo *info)
d7699f87
GFT
1435{
1436 struct jme_adapter *jme = netdev_priv(netdev);
1437
1438 strcpy(info->driver, DRV_NAME);
1439 strcpy(info->version, DRV_VERSION);
1440 strcpy(info->bus_info, pci_name(jme->pdev));
1441}
1442
3bf61c55
GFT
1443static int
1444jme_get_settings(struct net_device *netdev,
1445 struct ethtool_cmd *ecmd)
d7699f87
GFT
1446{
1447 struct jme_adapter *jme = netdev_priv(netdev);
1448 int rc;
1449 spin_lock(&jme->phy_lock);
1450 rc = mii_ethtool_gset(&(jme->mii_if), ecmd);
1451 spin_unlock(&jme->phy_lock);
1452 return rc;
1453}
1454
3bf61c55
GFT
1455static int
1456jme_set_settings(struct net_device *netdev,
1457 struct ethtool_cmd *ecmd)
d7699f87
GFT
1458{
1459 struct jme_adapter *jme = netdev_priv(netdev);
1460 int rc;
fcf45b4c
GFT
1461 unsigned long flags;
1462
1463 spin_lock_irqsave(&jme->phy_lock, flags);
d7699f87 1464 rc = mii_ethtool_sset(&(jme->mii_if), ecmd);
fcf45b4c
GFT
1465 spin_unlock_irqrestore(&jme->phy_lock, flags);
1466
d7699f87
GFT
1467 return rc;
1468}
1469
3bf61c55
GFT
1470static __u32
1471jme_get_link(struct net_device *netdev)
1472{
d7699f87
GFT
1473 struct jme_adapter *jme = netdev_priv(netdev);
1474 return jread32(jme, JME_PHY_LINK) & PHY_LINK_UP;
1475}
1476
1477static const struct ethtool_ops jme_ethtool_ops = {
1478 .get_drvinfo = jme_get_drvinfo,
1479 .get_settings = jme_get_settings,
1480 .set_settings = jme_set_settings,
1481 .get_link = jme_get_link,
1482};
1483
3bf61c55
GFT
1484static int
1485jme_pci_dma64(struct pci_dev *pdev)
d7699f87 1486{
3bf61c55
GFT
1487 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
1488 if(!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1489 return 1;
1490
1491 if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
1492 if(!pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
1493 return 0;
1494
1495 return -1;
1496}
1497
1498static int __devinit
1499jme_init_one(struct pci_dev *pdev,
1500 const struct pci_device_id *ent)
1501{
1502 int rc = 0, using_dac;
d7699f87
GFT
1503 struct net_device *netdev;
1504 struct jme_adapter *jme;
d7699f87
GFT
1505
1506 /*
1507 * set up PCI device basics
1508 */
4330c2f2
GFT
1509 rc = pci_enable_device(pdev);
1510 if(rc) {
1511 printk(KERN_ERR PFX "Cannot enable PCI device.\n");
1512 goto err_out;
1513 }
d7699f87 1514
3bf61c55
GFT
1515 using_dac = jme_pci_dma64(pdev);
1516 if(using_dac < 0) {
1517 printk(KERN_ERR PFX "Cannot set PCI DMA Mask.\n");
1518 rc = -EIO;
1519 goto err_out_disable_pdev;
1520 }
1521
4330c2f2
GFT
1522 if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1523 printk(KERN_ERR PFX "No PCI resource region found.\n");
1524 rc = -ENOMEM;
1525 goto err_out_disable_pdev;
1526 }
d7699f87 1527
4330c2f2
GFT
1528 rc = pci_request_regions(pdev, DRV_NAME);
1529 if(rc) {
1530 printk(KERN_ERR PFX "Cannot obtain PCI resource region.\n");
1531 goto err_out_disable_pdev;
1532 }
d7699f87
GFT
1533
1534 pci_set_master(pdev);
1535
1536 /*
1537 * alloc and init net device
1538 */
3bf61c55 1539 netdev = alloc_etherdev(sizeof(*jme));
d7699f87 1540 if(!netdev) {
4330c2f2
GFT
1541 rc = -ENOMEM;
1542 goto err_out_release_regions;
d7699f87
GFT
1543 }
1544 netdev->open = jme_open;
1545 netdev->stop = jme_close;
1546 netdev->hard_start_xmit = jme_start_xmit;
1547 netdev->irq = pdev->irq;
1548 netdev->set_mac_address = jme_set_macaddr;
1549 netdev->set_multicast_list = jme_set_multi;
1550 netdev->change_mtu = jme_change_mtu;
1551 netdev->ethtool_ops = &jme_ethtool_ops;
3bf61c55
GFT
1552 NETDEV_GET_STATS(netdev, &jme_get_stats);
1553
1554 if(using_dac)
1555 netdev->features = NETIF_F_HIGHDMA;
d7699f87
GFT
1556
1557 SET_NETDEV_DEV(netdev, &pdev->dev);
1558 pci_set_drvdata(pdev, netdev);
1559
1560 /*
1561 * init adapter info
1562 */
1563 jme = netdev_priv(netdev);
1564 jme->pdev = pdev;
1565 jme->dev = netdev;
3bf61c55 1566 jme->reg_ghc = GHC_DPX | GHC_SPEED_1000M;
fcf45b4c 1567 jme->phylink = 0;
d7699f87
GFT
1568 jme->regs = ioremap(pci_resource_start(pdev, 0),
1569 pci_resource_len(pdev, 0));
4330c2f2 1570 if (!(jme->regs)) {
d7699f87
GFT
1571 rc = -ENOMEM;
1572 goto err_out_free_netdev;
1573 }
4330c2f2
GFT
1574 jme->shadow_regs = pci_alloc_consistent(pdev,
1575 sizeof(__u32) * SHADOW_REG_NR,
1576 &(jme->shadow_dma));
1577 if (!(jme->shadow_regs)) {
1578 rc = -ENOMEM;
1579 goto err_out_unmap;
1580 }
1581
3bf61c55 1582 spin_lock_init(&jme->tx_lock);
d7699f87 1583 spin_lock_init(&jme->phy_lock);
fcf45b4c
GFT
1584 spin_lock_init(&jme->macaddr_lock);
1585
1586 atomic_set(&jme->intr_sem, 1);
1587 atomic_set(&jme->link_changing, 1);
1588 atomic_set(&jme->rx_cleaning, 1);
1589 atomic_set(&jme->tx_cleaning, 1);
1590
4330c2f2
GFT
1591 tasklet_init(&jme->linkch_task,
1592 &jme_link_change_tasklet,
1593 (unsigned long) jme);
1594 tasklet_init(&jme->txclean_task,
1595 &jme_tx_clean_tasklet,
1596 (unsigned long) jme);
1597 tasklet_init(&jme->rxclean_task,
1598 &jme_rx_clean_tasklet,
1599 (unsigned long) jme);
fcf45b4c
GFT
1600 tasklet_init(&jme->rxempty_task,
1601 &jme_rx_empty_tasklet,
1602 (unsigned long) jme);
d7699f87
GFT
1603 jme->mii_if.dev = netdev;
1604 jme->mii_if.phy_id = 1;
1605 jme->mii_if.supports_gmii = 1;
1606 jme->mii_if.mdio_read = jme_mdio_read;
1607 jme->mii_if.mdio_write = jme_mdio_write;
1608
fcf45b4c
GFT
1609 /*
1610 * Get Max Read Req Size from PCI Config Space
1611 */
1612 pci_read_config_byte(pdev, PCI_CONF_DCSR_MRRS, &jme->mrrs);
1613 switch(jme->mrrs) {
1614 case MRRS_128B:
1615 jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_128B;
1616 break;
1617 case MRRS_256B:
1618 jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_256B;
1619 break;
1620 default:
1621 jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_512B;
1622 break;
1623 };
1624
1625
d7699f87
GFT
1626 /*
1627 * Reset MAC processor and reload EEPROM for MAC Address
1628 */
1629 jme_clear_pm(jme);
3bf61c55 1630 jme_reset_phy_processor(jme);
d7699f87 1631 jme_reset_mac_processor(jme);
4330c2f2
GFT
1632 rc = jme_reload_eeprom(jme);
1633 if(rc) {
3bf61c55
GFT
1634 printk(KERN_ERR PFX
1635 "Rload eeprom for reading MAC Address error.\n");
4330c2f2
GFT
1636 goto err_out_free_shadow;
1637 }
d7699f87
GFT
1638 jme_load_macaddr(netdev);
1639
1640
1641 /*
1642 * Tell stack that we are not ready to work until open()
1643 */
1644 netif_carrier_off(netdev);
1645 netif_stop_queue(netdev);
1646
1647 /*
1648 * Register netdev
1649 */
4330c2f2
GFT
1650 rc = register_netdev(netdev);
1651 if(rc) {
1652 printk(KERN_ERR PFX "Cannot register net device.\n");
1653 goto err_out_free_shadow;
1654 }
d7699f87 1655
4330c2f2 1656 jprintk(netdev->name,
3bf61c55
GFT
1657 "JMC250 gigabit eth at %llx, "
1658 "%02x:%02x:%02x:%02x:%02x:%02x, IRQ %d\n",
4330c2f2
GFT
1659 (unsigned long long) pci_resource_start(pdev, 0),
1660 netdev->dev_addr[0],
1661 netdev->dev_addr[1],
1662 netdev->dev_addr[2],
1663 netdev->dev_addr[3],
1664 netdev->dev_addr[4],
1665 netdev->dev_addr[5],
1666 pdev->irq);
d7699f87
GFT
1667
1668 return 0;
1669
4330c2f2
GFT
1670err_out_free_shadow:
1671 pci_free_consistent(pdev,
1672 sizeof(__u32) * SHADOW_REG_NR,
1673 jme->shadow_regs,
1674 jme->shadow_dma);
d7699f87
GFT
1675err_out_unmap:
1676 iounmap(jme->regs);
1677err_out_free_netdev:
1678 pci_set_drvdata(pdev, NULL);
1679 free_netdev(netdev);
4330c2f2
GFT
1680err_out_release_regions:
1681 pci_release_regions(pdev);
d7699f87
GFT
1682err_out_disable_pdev:
1683 pci_disable_device(pdev);
d7699f87 1684err_out:
4330c2f2 1685 return rc;
d7699f87
GFT
1686}
1687
3bf61c55
GFT
1688static void __devexit
1689jme_remove_one(struct pci_dev *pdev)
1690{
d7699f87
GFT
1691 struct net_device *netdev = pci_get_drvdata(pdev);
1692 struct jme_adapter *jme = netdev_priv(netdev);
1693
1694 unregister_netdev(netdev);
4330c2f2
GFT
1695 pci_free_consistent(pdev,
1696 sizeof(__u32) * SHADOW_REG_NR,
1697 jme->shadow_regs,
1698 jme->shadow_dma);
d7699f87
GFT
1699 iounmap(jme->regs);
1700 pci_set_drvdata(pdev, NULL);
1701 free_netdev(netdev);
1702 pci_release_regions(pdev);
1703 pci_disable_device(pdev);
1704
1705}
1706
1707static struct pci_device_id jme_pci_tbl[] = {
1708 { PCI_VDEVICE(JMICRON, 0x250) },
1709 { }
1710};
1711
1712static struct pci_driver jme_driver = {
1713 .name = DRV_NAME,
1714 .id_table = jme_pci_tbl,
1715 .probe = jme_init_one,
1716 .remove = __devexit_p(jme_remove_one),
1717#if 0
1718#ifdef CONFIG_PM
1719 .suspend = jme_suspend,
1720 .resume = jme_resume,
1721#endif /* CONFIG_PM */
1722#endif
1723};
1724
3bf61c55
GFT
1725static int __init
1726jme_init_module(void)
d7699f87 1727{
4330c2f2
GFT
1728 printk(KERN_INFO PFX "JMicron JMC250 gigabit ethernet "
1729 "driver version %s\n", DRV_VERSION);
d7699f87
GFT
1730 return pci_register_driver(&jme_driver);
1731}
1732
3bf61c55
GFT
1733static void __exit
1734jme_cleanup_module(void)
d7699f87
GFT
1735{
1736 pci_unregister_driver(&jme_driver);
1737}
1738
1739module_init(jme_init_module);
1740module_exit(jme_cleanup_module);
1741
3bf61c55 1742MODULE_AUTHOR("Guo-Fu Tseng <cooldavid@cooldavid.org>");
d7699f87
GFT
1743MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver");
1744MODULE_LICENSE("GPL");
1745MODULE_VERSION(DRV_VERSION);
1746MODULE_DEVICE_TABLE(pci, jme_pci_tbl);
1747
1748