|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2007, 2011 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12: /*
13: * e1000 Gigabit Ethernet Driver for SLOF
14: *
15: * Reference:
16: * PCI/PCI-X Family of Gigabit Ethernet Controllers
17: * Software Developer's Manual Rev. 3.3, Intel, December 2006
18: */
19:
20: #include <stdint.h>
21: #include <string.h>
22: #include <byteorder.h>
23: #include "e1k.h"
24:
25:
26: /*
27: * local defines
28: ******************************************************************************
29: */
30: #define E1K_NUM_RX_DESC 128 // do not change
31: #define E1K_NUM_TX_DESC 128 // do not change
32: #define E1K_BUF_SIZE 2096 // do not change
33:
34: #define NUM_MAC_ADDR 16 // number of mac address register pairs
35: #define EEPROM_MAC_OFFS 0 // position of mac address in eeprom
36:
37: /*
38: * local types
39: ******************************************************************************
40: */
41: typedef struct {
42: uint32_t m_dev_u32;
43: uint64_t m_devmsk_u64;
44: char *m_name;
45: } e1k_dev_t;
46:
47: /*
48: * e1k common data structures
49: */
50:
51: /*
52: * transmit buffer descriptor
53: */
54: typedef struct {
55: uint64_t m_buffer_u64;
56: uint16_t m_len_u16;
57: uint8_t m_cso_u08;
58: uint8_t m_cmd_u08;
59: uint8_t m_sta_u08;
60: uint8_t m_css_u08;
61: uint16_t m_spe_u16;
62: } __attribute__ ((packed)) e1k_tx_desc_st;
63:
64:
65: /*
66: * receive buffer descriptor
67: */
68: typedef struct {
69: uint64_t m_buffer_u64;
70: uint16_t m_len_u16;
71: uint16_t m_csm_u16;
72: uint8_t m_sta_u08;
73: uint8_t m_err_u08;
74: uint16_t m_spe_u16;
75: } __attribute__ ((packed)) e1k_rx_desc_st;
76:
77: /*
78: * e1k device structure
79: */
80: typedef struct {
81: /*
82: * device identification mask
83: */
84: uint64_t m_device_u64;
85:
86: /*
87: * memory mapped base address of NIC
88: */
89: uint64_t m_baseaddr_u64;
90:
91: /*
92: * transmit & receive rings
93: * must be 16 byte aligned
94: */
95: e1k_tx_desc_st m_tx_ring_pst[E1K_NUM_TX_DESC];
96: e1k_rx_desc_st m_rx_ring_pst[E1K_NUM_RX_DESC];
97:
98: /*
99: * transmit & receive buffers
100: * must be 16 byte aligned
101: */
102: uint8_t m_tx_buffer_pu08[E1K_NUM_TX_DESC][E1K_BUF_SIZE];
103: uint8_t m_rx_buffer_pu08[E1K_NUM_RX_DESC][E1K_BUF_SIZE];
104:
105: /*
106: * next receive descriptor index
107: */
108: uint32_t m_rx_next_u32;
109:
110: /*
111: * command register storage
112: */
113: uint16_t m_com_r_u16;
114:
115: /*
116: * padding to make the size of the structure a multiple of 16 byte
117: */
118: uint16_t m_pad16_u16;
119: uint64_t m_pad64_u32;
120:
121: /*
122: * PCI related data
123: */
124: uint64_t pcicfg_puid;
125: uint8_t pcicfg_bus;
126: uint8_t pcicfg_devfn;
127: } __attribute__ ((packed)) e1k_st;
128:
129: /*
130: * local constants
131: ******************************************************************************
132: */
133: #define E1K_82540 ((uint64_t) 0x1)
134: #define E1K_82541 ((uint64_t) 0x2)
135: #define E1K_82544 ((uint64_t) 0x4)
136: #define E1K_82545 ((uint64_t) 0x8)
137: #define E1K_82546 ((uint64_t) 0x10)
138: #define E1K_82547 ((uint64_t) 0x20)
139:
140: #define IS_82541 ((m_e1k.m_device_u64 & E1K_82541) != 0)
141: #define IS_82546 ((m_e1k.m_device_u64 & E1K_82546) != 0)
142: #define IS_82547 ((m_e1k.m_device_u64 & E1K_82547) != 0)
143:
144: static const e1k_dev_t e1k_dev[] = {
145: { 0x1019, E1K_82547, "82547EI/GI Copper" },
146: { 0x101A, E1K_82547, "82547EI Mobile" },
147: { 0x1010, E1K_82546, "52546EB Copper, Dual Port" },
148: { 0x1012, E1K_82546, "82546EB Fiber, Dual Port" },
149: /* { 0x101D, E1K_82546, "82546EB Copper, Quad Port" }, */
150: { 0x1079, E1K_82546, "82546GB Copper, Dual Port" },
151: { 0x107A, E1K_82546, "82546GB Fiber, Dual Port" },
152: { 0x107B, E1K_82546, "82546GB SerDes, Dual Port" },
153: { 0x100F, E1K_82545, "82545EM Copper" },
154: { 0x1011, E1K_82545, "82545EM Fiber" },
155: { 0x1026, E1K_82545, "82545GM Copper" },
156: { 0x1027, E1K_82545, "82545GM Fiber" },
157: { 0x1028, E1K_82545, "82545GM SerDes" },
158: { 0x1107, E1K_82544, "82544EI Copper" },
159: { 0x1112, E1K_82544, "82544GC Copper" },
160: { 0x1013, E1K_82541, "82541EI Copper" },
161: { 0x1018, E1K_82541, "82541EI Mobile" },
162: { 0x1076, E1K_82541, "82541GI Copper" },
163: { 0x1077, E1K_82541, "82541GI Mobile" },
164: { 0x1078, E1K_82541, "82541ER Copper" },
165: { 0x107C, E1K_82541, "82541PI" },
166: { 0x1015, E1K_82540, "82540EM Mobile" },
167: { 0x1016, E1K_82540, "82540EP Mobile" },
168: { 0x1017, E1K_82540, "82540EP Desktop" },
169: { 0x100E, E1K_82540, "82540EM Desktop" },
170: { 0 , 0 }
171: };
172:
173: /*
174: * local variables
175: ******************************************************************************
176: */
177: static e1k_st m_e1k __attribute__ ((aligned(16)));
178: static long dma_offset;
179:
180: /*
181: * global functions
182: ******************************************************************************
183: */
184: int
185: check_driver(pci_config_t *pci_conf);
186:
187:
188: /*
189: * snk module interface
190: ******************************************************************************
191: */
192: static int e1k_init(void);
193: static int e1k_term(void);
194: static int e1k_xmit(char *f_buffer_pc, int f_len_i);
195: static int e1k_receive(char *f_buffer_pc, int f_len_i);
196: static int e1k_ioctl(int request, void* data);
197:
198: snk_module_t snk_module_interface = {
199: .version = 1,
200: .type = MOD_TYPE_NETWORK,
201: .running = 0,
202: .init = e1k_init,
203: .term = e1k_term,
204: .write = e1k_xmit,
205: .read = e1k_receive,
206: .ioctl = e1k_ioctl
207: };
208:
209:
210: /**
211: * Translate virtual to "physical" address, ie. an address
212: * which can be used for DMA transfers.
213: */
214: static uint64_t
215: virt2dma(void *addr)
216: {
217: return (uint64_t)addr + dma_offset;
218: }
219:
220: static void *
221: dma2virt(uint64_t addr)
222: {
223: return (void *)(addr - dma_offset);
224: }
225:
226:
227: /*
228: * local inline functions for e1k register access
229: ******************************************************************************
230: */
231: static uint32_t
232: e1k_rd32(uint16_t f_offs_u16)
233: { // caution: shall only be used after initialization!
234: return bswap_32(rd32(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16));
235: }
236:
237: /* not used so far
238: static uint16_t
239: e1k_rd16(uint16_t f_offs_u16)
240: { // caution: shall only be used after initialization!
241: return bswap_16(rd16(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16));
242: }*/
243:
244: /* not used so far
245: static uint8_t
246: e1k_rd08(uint16_t f_offs_u16)
247: { // caution: shall only be used after initialization!
248: return rd08(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16);
249: }*/
250:
251: static void
252: e1k_wr32(uint16_t f_offs_u16, uint32_t f_val_u32)
253: { // caution: shall only be used after initialization!
254: wr32(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, bswap_32(f_val_u32));
255: }
256:
257: /* not used so far
258: static void
259: e1k_wr16(uint16_t f_offs_u16, uint16_t f_val_u16)
260: { // caution: shall only be used after initialization!
261: wr16(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, bswap_16(f_val_u16));
262: }*/
263:
264: /* not used so far
265: static void
266: e1k_wr08(uint16_t f_offs_u16, uint8_t f_val_u08)
267: { // caution: shall only be used after initialization!
268: wr08(m_e1k.m_baseaddr_u64 + (uint64_t) f_offs_u16, f_val_u08);
269: }*/
270:
271: static void
272: e1k_setb32(uint16_t f_offs_u16, uint32_t f_mask_u32)
273: {
274: uint32_t v;
275:
276: v = e1k_rd32(f_offs_u16);
277: v |= f_mask_u32;
278: e1k_wr32(f_offs_u16, v);
279: }
280:
281: /* not used so far
282: static void
283: e1k_setb16(uint16_t f_offs_u16, uint16_t f_mask_u16)
284: {
285: uint16_t v;
286: v = e1k_rd16(f_offs_u16);
287: v |= f_mask_u16;
288: e1k_wr16(f_offs_u16, v);
289: }*/
290:
291: /* not used so far
292: static void
293: e1k_setb08(uint16_t f_offs_u16, uint8_t f_mask_u08)
294: {
295: uint8_t v;
296: v = e1k_rd08(f_offs_u16);
297: v |= f_mask_u08;
298: e1k_wr08(f_offs_u16, v);
299: }*/
300:
301: static void
302: e1k_clrb32(uint16_t f_offs_u16, uint32_t f_mask_u32)
303: {
304: uint32_t v;
305:
306: v = e1k_rd32(f_offs_u16);
307: v &= ~f_mask_u32;
308: e1k_wr32(f_offs_u16, v);
309: }
310:
311: /* not used so far
312: static void
313: e1k_clrb16(uint16_t f_offs_u16, uint16_t f_mask_u16)
314: {
315: uint16_t v;
316:
317: v = e1k_rd16(f_offs_u16);
318: v &= ~f_mask_u16;
319: e1k_wr16(f_offs_u16, v);
320: }*/
321:
322: /* not used so far
323: static void
324: e1k_clrb08(uint16_t f_offs_u16, uint8_t f_mask_u08)
325: {
326: uint8_t v;
327: v = e1k_rd08(f_offs_u16);
328: v &= ~f_mask_u08;
329: e1k_wr08(f_offs_u16, v);
330: }*/
331:
332: static int32_t
333: e1k_eep_rd16(uint8_t f_offs_u08, uint16_t *f_data_pu16)
334: {
335: uint32_t i;
336: uint32_t v;
337: int32_t done_shft;
338: int32_t addr_shft;
339:
340: if(IS_82541 || IS_82547) {
341: addr_shft = 2;
342: done_shft = 1;
343: } else {
344: addr_shft = 8;
345: done_shft = 4;
346: }
347:
348: /*
349: * initiate eeprom read
350: */
351: e1k_wr32(EERD, ((uint32_t) f_offs_u08 << addr_shft) | // address
352: BIT32(0)); // start read
353:
354: /*
355: * wait for read done bit to be set
356: */
357: i = 1000;
358: v = e1k_rd32(EERD);
359: while ((--i) &&
360: ((v & BIT32(done_shft)) == 0)) {
361: ms_delay(1);
362: v = e1k_rd32(EERD);
363: }
364:
365: /*
366: * return on error
367: */
368: if ((v & BIT32(done_shft)) == 0) {
369: return -1;
370: }
371:
372: /*
373: * return data
374: */
375: *f_data_pu16 = (uint16_t) ((v >> 16) & 0xffff);
376:
377: return 0;
378: }
379:
380: /*
381: * ring initialization
382: */
383: static void
384: e1k_init_receiver(void)
385: {
386: uint32_t i;
387: uint64_t addr;
388:
389: /*
390: * disable receiver for initialization
391: */
392: e1k_wr32(RCTL, 0);
393:
394: /*
395: * clear receive desciptors and setup buffer pointers
396: */
397: for (i = 0; i < E1K_NUM_RX_DESC; i++) {
398: memset((uint8_t *) &m_e1k.m_rx_ring_pst[i], 0,
399: sizeof(e1k_rx_desc_st));
400: mb();
401:
402: m_e1k.m_rx_ring_pst[i].m_buffer_u64 =
403: bswap_64(virt2dma(&m_e1k.m_rx_buffer_pu08[i][0]));
404: }
405:
406: /*
407: * initialize previously received index
408: */
409: m_e1k.m_rx_next_u32 = 0;
410:
411: /*
412: * setup the base address and the length of the rx descriptor ring
413: */
414: addr = virt2dma(&m_e1k.m_rx_ring_pst[0]);
415: e1k_wr32(RDBAH, (uint32_t) ((uint64_t) addr >> 32));
416: e1k_wr32(RDBAL, (uint32_t) ((uint64_t) addr & 0xffffffff));
417: e1k_wr32(RDLEN, E1K_NUM_RX_DESC * sizeof(e1k_rx_desc_st));
418:
419: /*
420: * setup the rx head and tail descriptor indices
421: */
422: e1k_wr32(RDH, 0);
423: e1k_wr32(RDT, E1K_NUM_RX_DESC - 1);
424:
425: /*
426: * setup the receive delay timer register
427: */
428: e1k_wr32(RDTR, 0);
429:
430: /*
431: * setup the receive control register
432: */
433: e1k_wr32(RCTL, BIT32( 1) | // enable receiver
434: BIT32( 4) | // enable multicast reception
435: BIT32(15)); // broadcast accept mode
436: // packet size 2048
437: // no buffer extension
438: }
439:
440: static void
441: e1k_init_transmitter(void)
442: {
443: uint32_t i;
444: uint64_t addr;
445:
446: /*
447: * clear transmit desciptors and setup buffer pointers
448: */
449: for (i = 0; i < E1K_NUM_TX_DESC; i++) {
450: memset((uint8_t *) &m_e1k.m_tx_ring_pst[i], 0,
451: sizeof(e1k_tx_desc_st));
452: mb();
453:
454: m_e1k.m_tx_ring_pst[i].m_buffer_u64 =
455: bswap_64(virt2dma(&m_e1k.m_tx_buffer_pu08[i][0]));
456: }
457:
458: /*
459: * setup the base address and the length of the tx descriptor ring
460: */
461: addr = virt2dma(&m_e1k.m_tx_ring_pst[0]);
462: e1k_wr32(TDBAH, (uint32_t) ((uint64_t) addr >> 32));
463: e1k_wr32(TDBAL, (uint32_t) ((uint64_t) addr & 0xffffffff));
464: e1k_wr32(TDLEN, E1K_NUM_TX_DESC * sizeof(e1k_tx_desc_st));
465:
466: /*
467: * setup the rx head and tail descriptor indices
468: */
469: e1k_wr32(TDH, 0);
470: e1k_wr32(TDT, 0);
471:
472: /*
473: * initialize the transmit control register
474: */
475: e1k_wr32(TCTL, BIT32(1) | // enable transmitter
476: BIT32(3) | // pad short packets
477: ((uint32_t) 0x0f << 4) | // collision threshhold
478: ((uint32_t) 0x40 << 12)); // collision distance
479: }
480:
481: static int32_t
482: e1k_mac_init(uint8_t *f_mac_pu08)
483: {
484: uint32_t l_ah_u32;
485: uint32_t l_al_u32;
486: uint32_t i;
487: uint32_t v;
488:
489: /*
490: * Use MAC address from device tree if possible
491: */
492: for (i = 0, v = 0; i < 6; i++) {
493: v += (uint32_t) f_mac_pu08[i];
494: }
495:
496: if (v != 0) {
497: /*
498: * use passed mac address for transmission to nic
499: */
500: l_al_u32 = ((uint32_t) f_mac_pu08[3] << 24);
501: l_al_u32 |= ((uint32_t) f_mac_pu08[2] << 16);
502: l_al_u32 |= ((uint32_t) f_mac_pu08[1] << 8);
503: l_al_u32 |= ((uint32_t) f_mac_pu08[0] << 0);
504: l_ah_u32 = ((uint32_t) f_mac_pu08[5] << 8);
505: l_ah_u32 |= ((uint32_t) f_mac_pu08[4] << 0);
506: } else {
507: /*
508: * read mac address from eeprom
509: */
510: uint16_t w[3]; // 3 16 bit words from eeprom
511:
512: for (i = 0; i < 3; i++) {
513: if (e1k_eep_rd16(EEPROM_MAC_OFFS + i, &w[i]) != 0) {
514: printk("Failed to read MAC address from EEPROM!\n");
515: return -1;
516: }
517: }
518:
519: /*
520: * invert the least significant bit for 82546 dual port
521: * if the second device is in use (remember word is byteswapped)
522: */
523: if ((IS_82546) &&
524: ((e1k_rd32(STATUS) & BIT32(2)) != 0)) {
525: w[2] ^= (uint16_t) 0x100;
526: }
527:
528: /*
529: * store mac address for transmission to nic
530: */
531: l_ah_u32 = ((uint32_t) w[2] << 0);
532: l_al_u32 = ((uint32_t) w[1] << 16);
533: l_al_u32 |= ((uint32_t) w[0] << 0);
534:
535: /*
536: * return mac address
537: * mac address in eeprom is stored byteswapped
538: */
539: f_mac_pu08[1] = (uint8_t) ((w[0] >> 8) & 0xff);
540: f_mac_pu08[0] = (uint8_t) ((w[0] >> 0) & 0xff);
541: f_mac_pu08[3] = (uint8_t) ((w[1] >> 8) & 0xff);
542: f_mac_pu08[2] = (uint8_t) ((w[1] >> 0) & 0xff);
543: f_mac_pu08[5] = (uint8_t) ((w[2] >> 8) & 0xff);
544: f_mac_pu08[4] = (uint8_t) ((w[2] >> 0) & 0xff);
545: }
546:
547: /*
548: * insert mac address in receive address register
549: * and set AV bit
550: */
551: e1k_wr32(RAL0, l_al_u32);
552: e1k_wr32(RAH0, l_ah_u32 | BIT32(31));
553:
554: /*
555: * clear remaining receive address registers
556: */
557: for (i = 1; i < NUM_MAC_ADDR; i++) {
558: e1k_wr32(RAL0 + i * sizeof(uint64_t), 0);
559: e1k_wr32(RAH0 + i * sizeof(uint64_t), 0);
560: }
561:
562: return 0;
563: }
564:
565:
566: /*
567: * interface
568: ******************************************************************************
569: */
570:
571: /*
572: * e1k_receive
573: */
574: static int
575: e1k_receive(char *f_buffer_pc, int f_len_i)
576: {
577: uint32_t l_rdh_u32 = e1k_rd32(RDH); // this includes needed dummy read
578: e1k_rx_desc_st *rx;
579: int l_ret_i;
580:
581: #ifdef E1K_DEBUG
582: #ifdef E1K_SHOW_RCV_DATA
583: int i;
584: #endif
585: #endif
586:
587: /*
588: * check whether new packets have arrived
589: */
590: if (m_e1k.m_rx_next_u32 == l_rdh_u32) {
591: return 0;
592: }
593:
594: /*
595: * get a pointer to the next rx descriptor for ease of use
596: */
597: rx = &m_e1k.m_rx_ring_pst[m_e1k.m_rx_next_u32];
598:
599: /*
600: * check whether the descriptor done bit is set
601: */
602: if ((rx->m_sta_u08 & 0x1) == 0) {
603: return 0;
604: }
605:
606: /*
607: * get the length of the packet, throw away checksum
608: */
609: l_ret_i = (int) bswap_16(rx->m_len_u16) - (int) 4;
610:
611: /*
612: * copy the data
613: */
614: memcpy((uint8_t *) f_buffer_pc, dma2virt(bswap_64(rx->m_buffer_u64)),
615: (size_t) l_ret_i);
616:
617: #ifdef E1K_DEBUG
618: #if defined(E1K_SHOW_RCV) || defined(E1K_SHOW_RCV_DATA)
619: printk("e1k: %d bytes received\n", l_ret_i);
620: #endif
621:
622: #ifdef E1K_SHOW_RCV_DATA
623: for (i = 0; i < l_ret_i; i++) {
624:
625: if ((i & 0x1f) == 0) {
626: printk("\n ");
627: }
628:
629: printk("%02X ", f_buffer_pc[i]);
630: }
631:
632: printk("\n\n");
633: #endif
634: #endif
635:
636: /*
637: * clear descriptor for reusage, but leave buffer pointer untouched
638: */
639: memset((uint8_t *) &rx->m_len_u16, 0,
640: sizeof(e1k_rx_desc_st) - sizeof(uint64_t));
641: mb();
642:
643: /*
644: * write new tail pointer
645: */
646: e1k_wr32(RDT, m_e1k.m_rx_next_u32);
647:
648: /*
649: * update next receive index
650: */
651: m_e1k.m_rx_next_u32 = (m_e1k.m_rx_next_u32 + 1) & (E1K_NUM_RX_DESC - 1);
652:
653: return l_ret_i;
654: }
655:
656: static int
657: e1k_xmit(char *f_buffer_pc, int f_len_i)
658: {
659: uint32_t l_tdh_u32 = e1k_rd32(TDH);
660: uint32_t l_tdt_u32 = e1k_rd32(TDT);
661: uint32_t l_pre_u32 = (l_tdh_u32 + (E1K_NUM_TX_DESC - 1)) &
662: (E1K_NUM_TX_DESC - 1);
663: e1k_tx_desc_st *tx;
664: #if defined(E1K_DEBUG) && defined(E1K_SHOW_XMIT_DATA)
665: int i;
666: #endif
667:
668: /*
669: * check for available buffers
670: */
671: if (l_pre_u32 == l_tdt_u32) {
672: return 0;
673: }
674:
675: /*
676: * get a pointer to the next tx descriptor for ease of use
677: */
678: tx = &m_e1k.m_tx_ring_pst[l_tdt_u32];
679:
680: /*
681: * copy the data
682: */
683: memcpy(dma2virt(bswap_64(tx->m_buffer_u64)), (uint8_t *) f_buffer_pc,
684: (size_t) f_len_i);
685:
686: /*
687: * insert length & command flags
688: */
689: tx->m_len_u16 = bswap_16((uint16_t) f_len_i);
690: tx->m_cmd_u08 = (BIT08(0) | // EOP
691: BIT08(1)); // IFCS
692: tx->m_sta_u08 = 0;
693: mb();
694:
695: /*
696: * update tail index
697: */
698: l_tdt_u32 = (l_tdt_u32 + 1) & (E1K_NUM_TX_DESC - 1);
699: e1k_wr32(TDT, l_tdt_u32);
700:
701: #ifdef E1K_DEBUG
702: #if defined(E1K_SHOW_XMIT) || defined(E1K_SHOW_XMIT_DATA)
703: printk("e1k: %d bytes transmitted\n", bswap_16(tx->m_len_u16));
704: #endif
705:
706: #ifdef E1K_SHOW_XMIT_DATA
707: for (i = 0; i < bswap_16(tx->m_len_u16); i++) {
708:
709: if ((i & 0x1f) == 0) {
710: printk("\n ");
711: }
712:
713: f_buffer_pc = dma2virt(bswap_64(tx->m_buffer_u64));
714: printk("%02X ", f_buffer_pc[i]);
715: }
716:
717: printk("\n\n");
718: #endif
719: #endif
720:
721: return f_len_i;
722: }
723:
724: int
725: check_driver(pci_config_t *pci_conf)
726: {
727: uint64_t i;
728:
729: /*
730: * checks whether the driver is handling this device
731: * by verifying vendor & device id
732: * vendor id 0x8086 == Intel
733: */
734: if (pci_conf->vendor_id != 0x8086) {
735: #ifdef E1K_DEBUG
736: printk("e1k: netdevice with vendor id %04X not supported\n",
737: pci_conf->vendor_id);
738: #endif
739: return -1;
740: }
741:
742: for (i = 0; e1k_dev[i].m_dev_u32 != 0; i++) {
743: if (e1k_dev[i].m_dev_u32 == (uint32_t) pci_conf->device_id) {
744: break;
745: }
746: }
747:
748: if (e1k_dev[i].m_dev_u32 == 0) {
749: #ifdef E1K_DEBUG
750: printk("e1k: netdevice with device id %04X not supported\n",
751: pci_conf->device_id);
752: #endif
753: return -1;
754: }
755:
756: /*
757: * initialize static variables
758: */
759: m_e1k.m_device_u64 = e1k_dev[i].m_devmsk_u64;
760: m_e1k.m_baseaddr_u64 = 0;
761: m_e1k.pcicfg_puid = pci_conf->puid;
762: m_e1k.pcicfg_bus = pci_conf->bus;
763: m_e1k.pcicfg_devfn = pci_conf->devfn;
764:
765: // success
766: #ifdef E1K_DEBUG
767: printk("e1k: found device %s\n", e1k_dev[i].m_name);
768: #endif
769:
770: return 0;
771: }
772:
773: static int
774: e1k_init(void)
775: {
776: uint32_t i;
777: uint32_t v;
778: char *mac_addr = snk_module_interface.mac_addr;
779:
780: if (snk_module_interface.running != 0) {
781: return 0;
782: }
783:
784: #ifdef E1K_DEBUG
785: printk("\ne1k: initializing\n");
786: #endif
787:
788: dma_offset = snk_kernel_interface->dma_map_in(&m_e1k, sizeof(m_e1k), 0);
789: #ifdef E1K_DEBUG
790: printk("e1k: dma offset: %lx - %lx = %lx\n", dma_offset, (long)&m_e1k,
791: dma_offset - (long)&m_e1k);
792: #endif
793: dma_offset = dma_offset - (long)&m_e1k;
794:
795: /*
796: * setup register & memory base addresses of NIC
797: */
798: m_e1k.m_baseaddr_u64 = (uint64_t) ((uint32_t) ~0xf & (uint32_t)
799: snk_kernel_interface->pci_config_read(m_e1k.pcicfg_puid,
800: 4,
801: m_e1k.pcicfg_bus,
802: m_e1k.pcicfg_devfn,
803: PCI_BAR1_R));
804: #ifdef E1K_DEBUG
805: printk("e1k: base address register = 0x%lx\n", m_e1k.m_baseaddr_u64);
806: #endif
807:
808: snk_kernel_interface->translate_addr(((void *) &m_e1k.m_baseaddr_u64));
809:
810: #ifdef E1K_DEBUG
811: printk("e1k: PCI-Puid = 0x%llX\n", m_e1k.pcicfg_puid);
812: printk("e1k: PCI-Bus = 0x%X\n", m_e1k.pcicfg_bus);
813: printk("e1k: PCI-DevFn = 0x%X\n", m_e1k.pcicfg_devfn);
814: printk("e1k: device's register base address = 0x%lx\n",
815: m_e1k.m_baseaddr_u64);
816: #endif
817:
818: /*
819: * e1k hardware initialization
820: */
821:
822: /*
823: * save pci command register
824: */
825: m_e1k.m_com_r_u16 = (uint16_t)
826: snk_kernel_interface->pci_config_read(m_e1k.pcicfg_puid,
827: 2,
828: m_e1k.pcicfg_bus,
829: m_e1k.pcicfg_devfn,
830: PCI_COM_R);
831:
832: /*
833: * bus mastering does not need to be enabled, it is already set
834: // enable bus master & memory space in command reg
835: i = (BIT32(10) | BIT32(2) | BIT32(1));
836: snk_kernel_interface->pci_config_write(m_e1k.pcicfg_puid,
837: 2,
838: m_e1k.pcicfg_bus,
839: m_e1k.pcicfg_devfn,
840: PCI_COM_R,
841: (int) i);
842: */
843:
844: /*
845: * at first disable all interrupts
846: */
847: e1k_wr32(IMC, (uint32_t) ~0);
848:
849: /*
850: * check for link up
851: */
852: #ifdef E1K_DEBUG
853: printk("e1k: checking link status..\n");
854: #endif
855:
856: i = 50;
857: v = e1k_rd32(STATUS);
858: while ((--i) &&
859: ((v & BIT32(1)) == 0)) {
860: ms_delay(100);
861: v = e1k_rd32(STATUS);
862: }
863:
864: if ((v & BIT32(1)) == 0) {
865: #ifdef E1K_DEBUG
866: printk("e1k: link is down.\n");
867: printk(" terminating.\n");
868: #endif
869:
870: return -1;
871: }
872:
873: #ifdef E1K_DEBUG
874: printk("e1k: link is up\n");
875:
876: switch ((v >> 6) & 0x3) {
877: case 0: {
878: printk(" 10 Mb/s\n");
879: } break;
880: case 1: {
881: printk(" 100 Mb/s\n");
882: } break;
883: case 2:
884: case 3: {
885: printk(" 1000 Mb/s\n");
886: } break;
887: }
888:
889: if ((v & BIT32(0)) == 0) {
890: printk(" half-duplex\n");
891: } else {
892: printk(" full-duplex\n");
893: }
894: #endif
895:
896: /*
897: * initialize mac address
898: */
899: #ifdef E1K_DEBUG
900: printk("e1k: initializing mac address.. ");
901: #endif
902: if (e1k_mac_init((uint8_t *)mac_addr) != 0) {
903: #ifdef E1K_DEBUG
904: printk("failed.\n");
905: printk(" terminating.\n");
906: #endif
907:
908: return -1;
909: }
910:
911: #ifdef E1K_DEBUG
912: printk("done.\n");
913: printk(" mac address = %02X:%02X:%02X:%02X:%02X:%02X\n",
914: mac_addr[0], mac_addr[1], mac_addr[2],
915: mac_addr[3], mac_addr[4], mac_addr[5]);
916: #endif
917:
918: /*
919: * initialize transmitter
920: */
921: #ifdef E1K_DEBUG
922: printk("e1k: initializing transmitter.. ");
923: #endif
924: e1k_init_transmitter();
925: #ifdef E1K_DEBUG
926: printk("done.\n");
927: #endif
928:
929: /*
930: * initialize receiver
931: */
932: #ifdef E1K_DEBUG
933: printk("e1k: initializing receiver.. ");
934: #endif
935: e1k_init_receiver();
936: #ifdef E1K_DEBUG
937: printk("done.\n");
938: printk("e1k: initialization complete\n");
939: #endif
940:
941: snk_module_interface.running = 1;
942:
943: return 0;
944: }
945:
946: static int
947: e1k_reset(void)
948: {
949: /*
950: * reset the PHY
951: */
952: e1k_setb32(CTRL, BIT32(31));
953: ms_delay(10);
954:
955: /*
956: * reset the MAC
957: */
958: e1k_setb32(CTRL, BIT32(26));
959: ms_delay(10);
960:
961: return 0;
962: }
963:
964: static int
965: e1k_term(void)
966: {
967: if (snk_module_interface.running == 0) {
968: return 0;
969: }
970:
971: #ifdef E1K_DEBUG
972: printk("e1k: shutdown.. ");
973: #endif
974:
975: /*
976: * disable receiver & transmitter
977: */
978: e1k_wr32(RCTL, 0);
979: e1k_wr32(TCTL, 0);
980: ms_delay(10);
981:
982: /*
983: * reset the ring indices
984: */
985: e1k_wr32(RDH, 0);
986: e1k_wr32(RDT, 0);
987: e1k_wr32(TDH, 0);
988: e1k_wr32(TDT, 0);
989:
990: /*
991: * disable receive address
992: */
993: e1k_clrb32(RAH0, BIT32(31));
994:
995: /*
996: * reset the mac/phy
997: */
998: e1k_reset();
999:
1000: /*
1001: * reset pci command register
1002: */
1003: snk_kernel_interface->pci_config_write(m_e1k.pcicfg_puid,
1004: 2,
1005: m_e1k.pcicfg_bus,
1006: m_e1k.pcicfg_devfn,
1007: PCI_COM_R,
1008: (int) m_e1k.m_com_r_u16);
1009:
1010: /*
1011: * Disable DMA translation
1012: */
1013: snk_kernel_interface->dma_map_out(&m_e1k, virt2dma(&m_e1k),
1014: sizeof(m_e1k));
1015:
1016: #ifdef E1K_DEBUG
1017: printk("done.\n");
1018: #endif
1019:
1020: snk_module_interface.running = 0;
1021: return 0;
1022: }
1023:
1024: static int
1025: e1k_ioctl(int request, void* data)
1026: {
1027: return 0;
1028: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.