3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifdef CONFIG_DRV_PCNET32
32 #define AMD_VENDORID 0x1022
34 /* PCNet/Home Device IDs */
35 #define PCNET_DEVICEID 0x2000
37 /* I/O 32bit resources */
38 #define PCNET32_IO_APR 0x00
39 #define PCNET32_IO_RDP 0x10
40 #define PCNET32_IO_ADDR 0x12
41 #define PCNET32_IO_RAP 0x14
42 #define PCNET32_IO_RESET 0x18
43 #define PCNET32_IO_BDP 0x1C
46 #define PCNET32_BUF_ENC_TX 0
47 #define PCNET32_BUF_ENC_RX 0
49 #define PCNET32_RING_TX_SIZE (1 << (PCNET32_BUF_ENC_TX))
50 #define PCNET32_RING_TX_LEN_BITS ((PCNET32_BUF_ENC_TX) << 12)
52 #define PCNET32_RING_RX_SIZE (1 << (PCNET32_BUF_ENC_RX))
53 #define PCNET32_RING_RX_LEN_BITS ((PCNET32_BUF_ENC_RX) << 4)
55 #define PCNET32_RING_TX_BUF_LEN 1024
56 #define PCNET32_RING_RX_BUF_LEN 2048
58 /* Ring entries state */
59 #define PCNET32_FLAG_RX_OWN 0x8000
61 /* CSR port definition */
62 #define PCNET32_CSR_STATUS 0x0
64 /* BCR port definition */
65 #define PCNET32_BCR_BUSCTL 0x12
66 #define PCNET32_BCR_SWMODE 0x14
68 /* PCNnet32 CSR status */
69 #define PCNET32_STATUS_ERR 0x8000
70 #define PCNET32_STATUS_BABL 0x4000
71 #define PCNET32_STATUS_CERR 0x2000
72 #define PCNET32_STATUS_MISS 0x1000
73 #define PCNET32_STATUS_MERR 0x800
74 #define PCNET32_STATUS_RINT 0x400
75 #define PCNET32_STATUS_TINT 0x200
76 #define PCNET32_STATUS_IDON 0x100
77 #define PCNET32_STATUS_INTR 0x80
78 #define PCNET32_STATUS_IENA 0x40
79 #define PCNET32_STATUS_RXON 0x20
80 #define PCNET32_STATUS_TXON 0x10
81 #define PCNET32_STATUS_TDMD 0x8
82 #define PCNET32_STATUS_STOP 0x4
83 #define PCNET32_STATUS_START 0x2
84 #define PCNET32_STATUS_INIT 0x1
86 /* Interrupt status definition */
87 #define PCNET32_INT_RST 0x0000
88 #define PCNET32_INT_WINT 0x0200
89 #define PCNET32_INT_RINT 0x0400
90 #define PCNET32_INT_RERR 0x1000
91 #define PCNET32_INT_WERR 0x4000
92 #define PCNET32_INT_ERR 0x8000
94 static unsigned short pcnet32_ring_xlen
[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
96 /* init block structure */
97 struct pcnet32_init_t
{
98 unsigned short mode
; /* copied into csr15 */
99 unsigned short res1
:4; /* reserved */
100 unsigned char rlen
:1; /* number of receive descriptor ring entries */
101 unsigned char rlen2
:1;
102 unsigned char rlen3
:1;
103 unsigned char rlen4
:1;
104 unsigned short res2
:4; /* reserved */
105 unsigned short tlen
:1; /* number of transmit descriptor ring entries */
106 unsigned short tlen2
:1;
107 unsigned short tlen3
:1;
108 unsigned short tlen4
:1;
109 unsigned char padr
[6]; /* mac address */
110 unsigned short res3
; /* reserved */
111 unsigned short ladrf1
; /* logical address filter 0..15 */
112 unsigned short ladrf2
; /* logical address filter 16..31 */
113 unsigned short ladrf3
; /* logibal address filter 32..47 */
114 unsigned short ladrf4
; /* logical address filter 48..63 */
115 unsigned rdra
; /* address of receive descriptor ring */
116 unsigned tdra
; /* address of receive descriptor ring */
117 /* unsigned char res1:4;
118 unsigned char rlen:1;
119 unsigned char rlen2:1;
120 unsigned char rlen3:1;
121 unsigned char rlen4:1;
122 unsigned tdra:24; */ /* address of transmit descriptor ring */
123 /* unsigned char res2:4;
124 unsigned char tlen:1;
125 unsigned char tlen2:1;
126 unsigned char tlen3:1;
127 unsigned char tlen4:1;*/
130 /* rings structure */
131 /*struct pcnet32_ringtx_t {
138 /** Transmit Message Descriptor */
139 struct pcnet32_ringtx_t
143 unsigned tbadr
; /**< transmit buffer address */
147 unsigned bcnt
:12; /**< buffer byte count (two's complement) */
148 unsigned ones
:4; /**< must be 1111b */
149 unsigned res
:7; /**< reserved */
150 unsigned bpe
:1; /**< bus parity error */
151 unsigned enp
:1; /**< end of packet */
152 unsigned stp
:1; /**< start of packet */
153 unsigned def
:1; /**< deferred */
154 unsigned one
:1; /**< exactly one retry was needed to transmit a frame */
155 unsigned ltint
:1; /**< suppress interrupts after successful transmission */
156 unsigned nofcs
:1; /**< when set, the state of DXMTFCS is ignored and
157 transmitter FCS generation is activated. */
158 unsigned err
:1; /**< error occured */
159 unsigned own
:1; /**< 0=owned by guest driver, 1=owned by controller */
163 unsigned trc
:4; /**< transmit retry count */
164 unsigned res
:12; /**< reserved */
165 unsigned tdr
:10; /**< ??? */
166 unsigned rtry
:1; /**< retry error */
167 unsigned lcar
:1; /**< loss of carrier */
168 unsigned lcol
:1; /**< late collision */
169 unsigned exdef
:1; /**< excessive deferral */
170 unsigned uflo
:1; /**< underflow error */
171 unsigned buff
:1; /**< out of buffers (ENP not found) */
175 unsigned res
; /**< reserved for user defined space */
179 /** Receive Message Descriptor */
180 struct pcnet32_ringrx_t
{
183 unsigned rbadr
; /**< receive buffer address */
187 unsigned bcnt
:12; /**< buffer byte count (two's complement) */
188 unsigned ones
:4; /**< must be 1111b */
189 unsigned res
:4; /**< reserved */
190 unsigned bam
:1; /**< broadcast address match */
191 unsigned lafm
:1; /**< logical filter address match */
192 unsigned pam
:1; /**< physcial address match */
193 unsigned bpe
:1; /**< bus parity error */
194 unsigned enp
:1; /**< end of packet */
195 unsigned stp
:1; /**< start of packet */
196 unsigned buff
:1; /**< buffer error */
197 unsigned crc
:1; /**< crc error on incoming frame */
198 unsigned oflo
:1; /**< overflow error (lost all or part of incoming frame) */
199 unsigned fram
:1; /**< frame error */
200 unsigned err
:1; /**< error occured */
201 unsigned own
:1; /**< 0=owned by guest driver, 1=owned by controller */
205 unsigned mcnt
:12; /**< message byte count */
206 unsigned zeros
:4; /**< 0000b */
207 unsigned rpc
:8; /**< receive frame tag */
208 unsigned rcc
:8; /**< receive frame tag + reserved */
212 unsigned res
; /**< reserved for user defined space */
216 /* pcnet32 device structure */
217 struct pcnet32_dev_t
{
220 unsigned short addr_io
;
224 struct pcnet32_dev_t
*pcnet32_dev
;
226 static void outl (unsigned short portno
, unsigned long val
) {
227 __asm__
__volatile__ ("outl %0, %w1" :: "a" (val
), "Nd" (portno
));
230 static unsigned long inl (unsigned short portno
) {
231 unsigned long retval
;
232 __asm__
__volatile__ ("inl %w1, %0" : "=a" (retval
) : "Nd" (portno
));
237 unsigned char pcnet32_read8 (struct pcnet32_dev_t
*dev
, unsigned short port
)
239 return inb (dev
->addr_io
+ port
);
242 unsigned short pcnet32_read16 (struct pcnet32_dev_t
*dev
, unsigned short port
)
244 return inw (dev
->addr_io
+ port
);
247 unsigned pcnet32_read32 (struct pcnet32_dev_t
*dev
, unsigned short port
)
249 return inl (dev
->addr_io
+ port
);
252 void pcnet32_write32 (struct pcnet32_dev_t
*dev
, unsigned short port
, unsigned val
)
254 outl (dev
->addr_io
+ port
, val
);
257 /* Register access */
258 unsigned pcnet32_read_csr (struct pcnet32_dev_t
*dev
, unsigned short reg
)
260 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
261 return pcnet32_read32 (dev
, PCNET32_IO_RDP
);
264 void pcnet32_write_csr (struct pcnet32_dev_t
*dev
, unsigned short reg
, unsigned short val
)
266 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
267 pcnet32_write32 (dev
, PCNET32_IO_RDP
, val
);
270 void pcnet32_write_bcr (struct pcnet32_dev_t
*dev
, unsigned short reg
, unsigned short val
)
272 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
273 pcnet32_write32 (dev
, PCNET32_IO_BDP
, val
);
278 bool pcnet32_acthandler (unsigned act
, char *block
, unsigned block_len
);
279 unsigned pcnet32_ring_create (struct pcnet32_dev_t
*dev
, struct pcnet32_init_t
*iblock
);
280 unsigned pcnet32_start (struct pcnet32_dev_t
*dev
);
282 unsigned pcnet32_int_rx (struct pcnet32_dev_t
*dev
);
285 /* READ/WRITE func */
286 unsigned pcnet32_read (char *buf
, unsigned len
)
288 pcnet32_acthandler (DEV_ACT_READ
, buf
, len
);
291 unsigned pcnet32_write (char *buf
, unsigned len
)
293 pcnet32_acthandler (DEV_ACT_WRITE
, buf
, len
);
297 /* detect pcnet32 device in PC */
298 pcidev_t
*pcnet32_detect ()
300 /* First detect network card - is connected to PCI bus ?*/
301 pcidev_t
*pcidev
= pcidev_find (AMD_VENDORID
, PCNET_DEVICEID
);
310 unsigned init_pcnet32 ()
314 pcidev_t
*pcidev
= pcnet32_detect ();
319 struct pcnet32_dev_t
*dev
= (struct pcnet32_dev_t
*) kmalloc (sizeof (struct pcnet32_dev_t
));
325 dev
->irq
= pcidev
->u
.h0
.interrupt_line
;
326 dev
->addr_io
= pcidev
->u
.h0
.base_registers
[0];
328 // get mac address from ethernet
329 for (i
= 0; i
< 6; i
++)
330 dev
->addr_mac
[i
] = pcnet32_read8 (dev
, i
);
332 irq_install_handler (dev
->irq
, pcnet32_int
);
336 return pcnet32_start (dev
);
339 unsigned pcnet32_start (struct pcnet32_dev_t
*dev
)
341 struct pcnet32_init_t
*iblock
= (struct pcnet32_init_t
*) 0x50000; // TODO: page aligned address
346 int ret
= pcnet32_ring_create (dev
, iblock
);
348 pcnet32_read32 (dev
, PCNET32_IO_RESET
);
349 pcnet32_write32 (dev
, PCNET32_IO_RESET
, 0);
351 outl (dev
->addr_io
+ PCNET32_IO_RDP
, 0);
352 pcnet32_write_bcr (dev
, PCNET32_BCR_SWMODE
, 0x0002);
355 iblock
->mode
= 0x0; // 0x8000 promiskuitni rezim
367 memcpy (iblock
->padr
, dev
->addr_mac
, 6);
369 iblock
->ladrf1
= (unsigned short) ~0;
370 iblock
->ladrf2
= (unsigned short) ~0;
371 iblock
->ladrf3
= (unsigned short) ~0;
372 iblock
->ladrf4
= (unsigned short) ~0;
374 kprintf ("init block: %d\n", sizeof (struct pcnet32_init_t
));
375 kprintf ("rxring: 0x%x / txring: 0x%x\n", iblock
->rdra
, iblock
->tdra
);
377 out_word(ioaddr+LANCE_ADDR, 0x1);
378 (void)in_word(ioaddr+LANCE_ADDR);
380 out_word(ioaddr+LANCE_DATA, (short)l);
381 out_word(ioaddr+LANCE_ADDR, 0x2);
382 (void)in_word(ioaddr+LANCE_ADDR);
384 out_word(ioaddr+LANCE_DATA, (short)(l >> 16));
385 out_word(ioaddr+LANCE_ADDR, 0x4);
386 (void)in_word(ioaddr+LANCE_ADDR);
388 out_word(ioaddr+LANCE_DATA, 0x915);
389 out_word(ioaddr+LANCE_ADDR, 0x0);
390 (void)in_word(ioaddr+LANCE_ADDR);*/
392 /* ----- start when init done. ----- */
393 // out_word(ioaddr+LANCE_DATA, 0x4); /* stop */
394 // out_word(ioaddr+LANCE_DATA, 0x1); /* init */
397 //outw (dev->addr_io + PCNET32_IO_ADDR, 0x1);
398 //inw (dev->addr_io + PCNET32_IO_ADDR);
402 //outw (dev->addr_io + PCNET32_IO_RDP, 0x4);
403 //outw (dev->addr_io + PCNET32_IO_RDP, 0x1);
404 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_STOP
);
406 init_block
= (unsigned) iblock
;
408 pcnet32_write_csr (dev
, 1, init_block
);
409 pcnet32_write_csr (dev
, 2, ((unsigned) init_block
>> 16));
411 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_INIT
);
413 while (!(pcnet32_read_csr (dev
, PCNET32_CSR_STATUS
) & PCNET32_STATUS_IDON
));
416 unsigned ring
= pcnet32_read_csr (pcnet32_dev
, 24) | (pcnet32_read_csr (pcnet32_dev
, 25) << 16);
417 printf ("rxring: 0x%x\n", ring
);
419 ring
= pcnet32_read_csr (pcnet32_dev
, 30) | (pcnet32_read_csr (pcnet32_dev
, 31) << 16);
420 printf ("txring: 0x%x\n", ring
);
422 ring
= pcnet32_read_csr (pcnet32_dev
, 76);
423 printf ("rlen: 0x%x\n", ring
);
426 ring
= pcnet32_read_csr (pcnet32_dev
, 78);
427 printf ("tlen: 0x%x\n", ring
);
431 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_START
| PCNET32_STATUS_IENA
);
433 //timer_wait (10000);
435 netdev_t
*ifdev
= netdev_create ();
440 memcpy (ifdev
->dev_addr
, dev
->addr_mac
, sizeof (dev
->addr_mac
));
442 ifdev
->read
= &pcnet32_read
;
443 ifdev
->write
= &pcnet32_write
;
445 // timer_wait (30000);
450 unsigned pcnet32_ring_create (struct pcnet32_dev_t
*dev
, struct pcnet32_init_t
*iblock
)
453 struct pcnet32_ringtx_t
*ringtx
= (struct pcnet32_ringtx_t
*) 0x51000;
455 iblock
->tdra
= (unsigned) ringtx
;
458 struct pcnet32_ringrx_t
*ringrx
= (struct pcnet32_ringrx_t
*) 0x59000;
460 iblock
->rdra
= (unsigned) ringrx
;
462 unsigned short index
= 0;
463 for (index
= 0; index
< pcnet32_ring_xlen
[PCNET32_BUF_ENC_RX
]; index
++) {
464 ringrx
[index
].rmd0
.rbadr
= (unsigned) kmalloc (sizeof (unsigned char) * PCNET32_RING_RX_BUF_LEN
);
465 ringrx
[index
].rmd1
.bcnt
= -PCNET32_RING_RX_BUF_LEN
;
466 ringrx
[index
].rmd1
.own
= ~0;
467 //ringrx[index].rmd3.res = 0;
468 ringrx
[index
].rmd1
.ones
= ~0;
476 struct pcnet32_dev_t
*dev
= pcnet32_dev
;
478 int status
= pcnet32_read_csr (dev
, PCNET32_CSR_STATUS
);
480 /* disable device interrupts */
482 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, status
& ~PCNET32_STATUS_IENA
);
484 if (status
& PCNET32_INT_ERR
)
485 kprintf ("pcnet32 -> device error\n");
487 if (status
& PCNET32_INT_RERR
)
488 kprintf ("pcnet32 -> read error\n");
490 if (status
& PCNET32_INT_WERR
)
491 kprintf ("pcnet32 -> write error\n");
493 if (status
& PCNET32_INT_RINT
) {
494 kprintf ("pcnet32 -> pcnet32_int_rx ()\n");
495 pcnet32_int_rx (dev
);
498 kprintf ("pcnet32 -> interrupt (0x%x)\n", status
);
500 //outw (dev->addr_io + PCNET32_IO_RDP, 0x7940);
502 /* enable device interrupts */
503 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_IENA
);
506 unsigned pcnet32_int_rx (struct pcnet32_dev_t
*dev
)
508 struct pcnet32_ringrx_t
*ringrx
= (struct pcnet32_ringrx_t
*) 0x59000;
510 unsigned short index
= 0;
511 for (index
= 0; index
< pcnet32_ring_xlen
[PCNET32_BUF_ENC_RX
]; index
++) {
513 kprintf ("own: %d\n", ringrx
[index
].rmd1
.own
);
515 kprintf ("buf (%d): '%s'\n", ringrx
[index
].rmd2
.mcnt
, ringrx
[index
].rmd0
.rbadr
);
517 kprintf ("zeros (%d): 0x%x\n", ringrx
[index
].rmd2
.zeros
, ringrx
[index
].rmd2
.zeros
);
518 kprintf ("ones: %d / 0x%x\n", ringrx
[index
].rmd1
.ones
, ringrx
[index
].rmd1
.ones
);
519 kprintf ("err: %d / 0x%x\n", ringrx
[index
].rmd1
.err
, ringrx
[index
].rmd1
.err
);
520 kprintf ("bcnt: %d / 0x%x\n", ringrx
[index
].rmd1
.bcnt
, ringrx
[index
].rmd1
.bcnt
);
527 bool pcnet32_acthandler (unsigned act
, char *block
, unsigned block_len
)
532 return init_pcnet32 ();
537 unsigned ring
= pcnet32_read_csr (pcnet32_dev
, 24) | (pcnet32_read_csr (pcnet32_dev
, 25) << 16);
538 printf ("rxring: 0x%x\n", ring
);
540 ring
= pcnet32_read_csr (pcnet32_dev
, 30) | (pcnet32_read_csr (pcnet32_dev
, 31) << 16);
541 printf ("txring: 0x%x\n", ring
);
543 ring
= pcnet32_read_csr (pcnet32_dev
, 76);
544 printf ("rlen: 0x%x\n", ring
);
546 ring
= pcnet32_read_csr (pcnet32_dev
, 78);
547 printf ("tlen: 0x%x\n", ring
);
549 ring
= (pcnet32_read_csr (pcnet32_dev
, 2) << 16) | pcnet32_read_csr (pcnet32_dev
, 1);
550 printf ("init: 0x%x / 0x%x\n", ring
, init_block
);