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 0x0004
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 #define __PACKED__ __attribute__ ((__packed__))
98 /* init block structure */
99 struct pcnet32_init_t
{
100 unsigned short mode
; /* copied into csr15 */
101 unsigned short res1
:4; /* reserved */
102 unsigned char rlen
:4; /* number of receive descriptor ring entries */
103 unsigned short res2
:4; /* reserved */
104 unsigned short tlen
:4; /* number of transmit descriptor ring entries */
105 unsigned char padr
[6]; /* mac address */
106 unsigned short res3
; /* reserved */
107 unsigned ladrf1
; /* logical address filter 0..31 */
108 unsigned ladrf2
; /* logical address filter 32..63 */
109 unsigned rdra
; /* address of receive descriptor ring */
110 unsigned tdra
; /* address of receive descriptor ring */
114 /** Transmit Message Descriptor */
115 struct pcnet32_ringtx_t
119 unsigned tbadr
; /**< transmit buffer address */
123 unsigned bcnt
:12; /**< buffer byte count (two's complement) */
124 unsigned ones
:4; /**< must be 1111b */
125 unsigned res
:7; /**< reserved */
126 unsigned bpe
:1; /**< bus parity error */
127 unsigned enp
:1; /**< end of packet */
128 unsigned stp
:1; /**< start of packet */
129 unsigned def
:1; /**< deferred */
130 unsigned one
:1; /**< exactly one retry was needed to transmit a frame */
131 unsigned ltint
:1; /**< suppress interrupts after successful transmission */
132 unsigned nofcs
:1; /**< when set, the state of DXMTFCS is ignored and
133 transmitter FCS generation is activated. */
134 unsigned err
:1; /**< error occured */
135 unsigned own
:1; /**< 0=owned by guest driver, 1=owned by controller */
139 unsigned trc
:4; /**< transmit retry count */
140 unsigned res
:12; /**< reserved */
141 unsigned tdr
:10; /**< ??? */
142 unsigned rtry
:1; /**< retry error */
143 unsigned lcar
:1; /**< loss of carrier */
144 unsigned lcol
:1; /**< late collision */
145 unsigned exdef
:1; /**< excessive deferral */
146 unsigned uflo
:1; /**< underflow error */
147 unsigned buff
:1; /**< out of buffers (ENP not found) */
151 unsigned res
; /**< reserved for user defined space */
155 /** Receive Message Descriptor */
156 struct pcnet32_ringrx_t
{
159 unsigned rbadr
; /**< receive buffer address */
163 unsigned bcnt
:12; /**< buffer byte count (two's complement) */
164 unsigned ones
:4; /**< must be 1111b */
165 unsigned res
:4; /**< reserved */
166 unsigned bam
:1; /**< broadcast address match */
167 unsigned lafm
:1; /**< logical filter address match */
168 unsigned pam
:1; /**< physcial address match */
169 unsigned bpe
:1; /**< bus parity error */
170 unsigned enp
:1; /**< end of packet */
171 unsigned stp
:1; /**< start of packet */
172 unsigned buff
:1; /**< buffer error */
173 unsigned crc
:1; /**< crc error on incoming frame */
174 unsigned oflo
:1; /**< overflow error (lost all or part of incoming frame) */
175 unsigned fram
:1; /**< frame error */
176 unsigned err
:1; /**< error occured */
177 unsigned own
:1; /**< 0=owned by guest driver, 1=owned by controller */
181 unsigned mcnt
:12; /**< message byte count */
182 unsigned zeros
:4; /**< 0000b */
183 unsigned rpc
:8; /**< receive frame tag */
184 unsigned rcc
:8; /**< receive frame tag + reserved */
188 unsigned res
; /**< reserved for user defined space */
192 /* pcnet32 device structure */
193 struct pcnet32_dev_t
{
196 unsigned short addr_io
;
200 struct pcnet32_dev_t
*pcnet32_dev
;
201 static netdev_t
*ifdev
;
205 unsigned char pcnet32_read8 (struct pcnet32_dev_t
*dev
, unsigned short port
)
207 return inb (dev
->addr_io
+ port
);
210 unsigned short pcnet32_read16 (struct pcnet32_dev_t
*dev
, unsigned short port
)
212 return inw (dev
->addr_io
+ port
);
215 unsigned pcnet32_read32 (struct pcnet32_dev_t
*dev
, unsigned short port
)
217 return inl (dev
->addr_io
+ port
);
220 void pcnet32_write32 (struct pcnet32_dev_t
*dev
, unsigned short port
, unsigned val
)
222 outl (dev
->addr_io
+ port
, val
);
225 /* Register access */
226 unsigned pcnet32_read_csr (struct pcnet32_dev_t
*dev
, unsigned short reg
)
228 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
229 return pcnet32_read32 (dev
, PCNET32_IO_RDP
);
232 void pcnet32_write_csr (struct pcnet32_dev_t
*dev
, unsigned short reg
, unsigned short val
)
234 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
235 pcnet32_write32 (dev
, PCNET32_IO_RDP
, val
);
238 void pcnet32_write_bcr (struct pcnet32_dev_t
*dev
, unsigned short reg
, unsigned short val
)
240 pcnet32_write32 (dev
, PCNET32_IO_RAP
, reg
);
241 pcnet32_write32 (dev
, PCNET32_IO_BDP
, val
);
246 bool pcnet32_acthandler (unsigned act
, char *block
, unsigned block_len
);
247 unsigned pcnet32_ring_create (struct pcnet32_dev_t
*dev
, struct pcnet32_init_t
*iblock
);
248 unsigned pcnet32_start (struct pcnet32_dev_t
*dev
);
250 unsigned pcnet32_int_rx (struct pcnet32_dev_t
*dev
);
251 unsigned pcnet32_tx (char *buf
, unsigned len
);
253 /* READ/WRITE func */
254 unsigned pcnet32_read (char *buf
, unsigned len
)
256 return pcnet32_acthandler (DEV_ACT_READ
, buf
, len
);
259 unsigned pcnet32_write (char *buf
, unsigned len
)
261 return pcnet32_acthandler (DEV_ACT_WRITE
, buf
, len
);
264 /* detect pcnet32 device in PC */
265 pcidev_t
*pcnet32_detect ()
267 /* First detect network card - is connected to PCI bus ?*/
268 pcidev_t
*pcidev
= pcidev_find (AMD_VENDORID
, PCNET_DEVICEID
);
277 unsigned init_pcnet32 ()
281 pcidev_t
*pcidev
= pcnet32_detect ();
286 struct pcnet32_dev_t
*dev
= (struct pcnet32_dev_t
*) kmalloc (sizeof (struct pcnet32_dev_t
));
292 dev
->irq
= pcidev
->u
.h0
.interrupt_line
;
293 dev
->addr_io
= pcidev
->u
.h0
.base_registers
[0];
295 // get mac address from ethernet
296 for (i
= 0; i
< 6; i
++)
297 dev
->addr_mac
[i
] = pcnet32_read8 (dev
, i
);
299 irq_install_handler (dev
->irq
, pcnet32_int
);
300 DPRINT ("pcnet32 irq: %d\n", dev
->irq
);
304 return pcnet32_start (dev
);
308 unsigned pcnet32_start (struct pcnet32_dev_t
*dev
)
310 struct pcnet32_init_t
*iblock
= (struct pcnet32_init_t
*) 0x50000; // TODO: page aligned address
315 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_STOP
);
317 int ret
= pcnet32_ring_create (dev
, iblock
);
319 //pcnet32_write_csr (dev, 58, ~0);
321 pcnet32_read32 (dev
, PCNET32_IO_RESET
);
322 pcnet32_write32 (dev
, PCNET32_IO_RESET
, 0);
324 iblock
->mode
= 0x0; // 0x8000 promiskuitni rezim
326 iblock
->rlen
= PCNET32_BUF_ENC_RX
;
328 iblock
->tlen
= PCNET32_BUF_ENC_TX
;
330 memcpy (iblock
->padr
, dev
->addr_mac
, 6);
332 iblock
->ladrf1
= (unsigned) ~0;
333 iblock
->ladrf2
= (unsigned) ~0;
335 DPRINT ("init block: %d\n", sizeof (struct pcnet32_init_t
));
336 DPRINT ("rxring: 0x%x / txring: 0x%x\n", iblock
->rdra
, iblock
->tdra
);
338 /* set to 32bit mode */
339 pcnet32_write32 (dev
, PCNET32_IO_RDP
, 0);
340 pcnet32_write_bcr (dev
, 20, 0x0002);
342 init_block
= (unsigned) iblock
;
344 pcnet32_write_csr (dev
, 1, init_block
);
345 pcnet32_write_csr (dev
, 2, ((unsigned) init_block
>> 16));
347 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_INIT
);
349 while (!(pcnet32_read_csr (dev
, PCNET32_CSR_STATUS
) & PCNET32_STATUS_IDON
));
351 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_START
| PCNET32_STATUS_IENA
);
353 ifdev
= netdev_create (dev
->addr_mac
, &pcnet32_read
, &pcnet32_write
);
361 unsigned pcnet32_ring_create (struct pcnet32_dev_t
*dev
, struct pcnet32_init_t
*iblock
)
364 struct pcnet32_ringtx_t
*ringtx
= (struct pcnet32_ringtx_t
*) 0x51000;
366 iblock
->tdra
= (unsigned) ringtx
;
369 struct pcnet32_ringrx_t
*ringrx
= (struct pcnet32_ringrx_t
*) 0x59000;
371 iblock
->rdra
= (unsigned) ringrx
;
373 unsigned short index
= 0;
374 for (index
= 0; index
< pcnet32_ring_xlen
[PCNET32_BUF_ENC_RX
]; index
++) {
375 ringrx
[index
].rmd0
.rbadr
= (unsigned) kmalloc (sizeof (unsigned char) * PCNET32_RING_RX_BUF_LEN
);
376 ringrx
[index
].rmd1
.bcnt
= 2048;
377 ringrx
[index
].rmd1
.own
= ~0;
378 ringrx
[index
].rmd3
.res
= 0;
379 ringrx
[index
].rmd1
.ones
= ~0;
388 struct pcnet32_dev_t
*dev
= pcnet32_dev
;
390 int status
= pcnet32_read_csr (dev
, PCNET32_CSR_STATUS
);
392 /* disable device interrupts */
394 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, status
& ~PCNET32_STATUS_IENA
);
396 if (status
& PCNET32_INT_ERR
) {
397 kprintf ("pcnet32 -> device error\n");
399 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_STOP
);
405 if (status
& PCNET32_INT_RERR
)
406 kprintf ("pcnet32 -> read error\n");
408 if (status
& PCNET32_INT_WERR
)
409 kprintf ("pcnet32 -> write error\n");
411 if (status
& PCNET32_INT_RINT
) {
412 //kprintf ("pcnet32 -> pcnet32_int_rx ()\n");
413 pcnet32_int_rx (dev
);
416 //kprintf ("pcnet32 -> interrupt (0x%x)\n", status);
418 /* enable device interrupts */
419 pcnet32_write_csr (dev
, PCNET32_CSR_STATUS
, PCNET32_STATUS_IENA
);
422 unsigned pcnet32_int_rx (struct pcnet32_dev_t
*dev
)
424 struct pcnet32_ringrx_t
*ringrx
= (struct pcnet32_ringrx_t
*) 0x59000;
426 unsigned short index
= 0;
427 for (index
= 0; index
< pcnet32_ring_xlen
[PCNET32_BUF_ENC_RX
]; index
++) {
429 if (ringrx
[index
].rmd1
.own
)
432 /* this is needed for again use, because pcnet32 change it to ~1 */
433 ringrx
[index
].rmd1
.own
= ~0;
435 char *buf
= (char *) ringrx
[index
].rmd0
.rbadr
;
438 //kprintf ("zeros (%d): 0x%x\n", ringrx[index].rmd2.zeros, ringrx[index].rmd2.zeros);
439 //kprintf ("ones: %d / 0x%x\n", ringrx[index].rmd1.ones, ringrx[index].rmd1.ones);
440 //kprintf ("err: %d / 0x%x\n", ringrx[index].rmd1.err, ringrx[index].rmd1.err);
441 //kprintf ("oflo: %d / 0x%x\n", ringrx[index].rmd1.oflo, ringrx[index].rmd1.oflo);
442 //kprintf ("buff: %d / 0x%x\n", ringrx[index].rmd1.buff, ringrx[index].rmd1.buff);
443 //kprintf ("bcnt: %d / 0x%x\n", ringrx[index].rmd1.bcnt, ringrx[index].rmd1.bcnt);
445 netdev_rx_add_queue (ifdev
, buf
, ringrx
[index
].rmd2
.mcnt
);
451 unsigned pcnet32_tx (char *buf
, unsigned len
)
454 struct pcnet32_ringtx_t
*ringtx
= (struct pcnet32_ringtx_t
*) 0x51000;
456 unsigned short index
= 0;
457 for (index
= 0; index
< pcnet32_ring_xlen
[PCNET32_BUF_ENC_TX
]; index
++) {
458 if (ringtx
[index
].tmd1
.own
== ~0)
459 DPRINT ("pcnet32 -> bad txring.own bit!\n");
461 ringtx
[index
].tmd0
.tbadr
= (unsigned) buf
;
462 ringtx
[index
].tmd1
.bcnt
= -len
;
463 ringtx
[index
].tmd1
.own
= ~0;
464 ringtx
[index
].tmd3
.res
= 0;
465 ringtx
[index
].tmd1
.ones
= ~0;
466 ringtx
[index
].tmd1
.stp
= ~0;
467 ringtx
[index
].tmd1
.enp
= ~0;
471 bool pcnet32_acthandler (unsigned act
, char *block
, unsigned block_len
)
476 return init_pcnet32 ();
481 /* see pcnet32_int_rx interrupt */
488 pcnet32_tx (block
, block_len
);