|
|
1.1 root 1: /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver
2: * Copyright (C) 2004 Advanced Micro Devices
3: * Copyright (C) 2005 Liu Tao <[email protected]> [etherboot port]
4: *
5: * Copyright 2001,2002 Jeff Garzik <[email protected]> [ 8139cp.c,tg3.c ]
6: * Copyright (C) 2001, 2002 David S. Miller ([email protected])[ tg3.c]
7: * Copyright 1996-1999 Thomas Bogendoerfer [ pcnet32.c ]
8: * Derived from the lance driver written 1993,1994,1995 by Donald Becker.
9: * Copyright 1993 United States Government as represented by the
10: * Director, National Security Agency.[ pcnet32.c ]
11: * Carsten Langgaard, [email protected] [ pcnet32.c ]
12: * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
13: *
14: *
15: * This program is free software; you can redistribute it and/or modify
16: * it under the terms of the GNU General Public License as published by
17: * the Free Software Foundation; either version 2 of the License, or
18: * (at your option) any later version.
19: *
20: * This program is distributed in the hope that it will be useful,
21: * but WITHOUT ANY WARRANTY; without even the implied warranty of
22: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23: * GNU General Public License for more details.
24: *
25: * You should have received a copy of the GNU General Public License
26: * along with this program; if not, write to the Free Software
27: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28: * USA
29: */
30:
31: FILE_LICENCE ( GPL2_OR_LATER );
32:
33: #include "etherboot.h"
34: #include "nic.h"
35: #include "mii.h"
36: #include <ipxe/pci.h>
37: #include <ipxe/ethernet.h>
38: #include "string.h"
39: #include "stdint.h"
40: #include "amd8111e.h"
41:
42:
43: /* driver definitions */
44: #define NUM_TX_SLOTS 2
45: #define NUM_RX_SLOTS 4
46: #define TX_SLOTS_MASK 1
47: #define RX_SLOTS_MASK 3
48:
49: #define TX_BUF_LEN 1536
50: #define RX_BUF_LEN 1536
51:
52: #define TX_PKT_LEN_MAX (ETH_FRAME_LEN - ETH_HLEN)
53: #define RX_PKT_LEN_MIN 60
54: #define RX_PKT_LEN_MAX ETH_FRAME_LEN
55:
56: #define TX_TIMEOUT 3000
57: #define TX_PROCESS_TIME 10
58: #define TX_RETRY (TX_TIMEOUT / TX_PROCESS_TIME)
59:
60: #define PHY_RW_RETRY 10
61:
62:
63: struct amd8111e_tx_desc {
64: u16 buf_len;
65: u16 tx_flags;
66: u16 tag_ctrl_info;
67: u16 tag_ctrl_cmd;
68: u32 buf_phy_addr;
69: u32 reserved;
70: };
71:
72: struct amd8111e_rx_desc {
73: u32 reserved;
74: u16 msg_len;
75: u16 tag_ctrl_info;
76: u16 buf_len;
77: u16 rx_flags;
78: u32 buf_phy_addr;
79: };
80:
81: struct eth_frame {
82: u8 dst_addr[ETH_ALEN];
83: u8 src_addr[ETH_ALEN];
84: u16 type;
85: u8 data[ETH_FRAME_LEN - ETH_HLEN];
86: } __attribute__((packed));
87:
88: struct amd8111e_priv {
89: struct amd8111e_tx_desc tx_ring[NUM_TX_SLOTS];
90: struct amd8111e_rx_desc rx_ring[NUM_RX_SLOTS];
91: unsigned char tx_buf[NUM_TX_SLOTS][TX_BUF_LEN];
92: unsigned char rx_buf[NUM_RX_SLOTS][RX_BUF_LEN];
93: unsigned long tx_idx, rx_idx;
94: int tx_consistent;
95:
96: char opened;
97: char link;
98: char speed;
99: char duplex;
100: int ext_phy_addr;
101: u32 ext_phy_id;
102:
103: struct pci_device *pdev;
104: struct nic *nic;
105: void *mmio;
106: };
107:
108: static struct amd8111e_priv amd8111e;
109:
110:
111: /********************************************************
112: * locale functions *
113: ********************************************************/
114: static void amd8111e_init_hw_default(struct amd8111e_priv *lp);
115: static int amd8111e_start(struct amd8111e_priv *lp);
116: static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val);
117: #if 0
118: static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val);
119: #endif
120: static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp);
121: static void amd8111e_disable_interrupt(struct amd8111e_priv *lp);
122: static void amd8111e_enable_interrupt(struct amd8111e_priv *lp);
123: static void amd8111e_force_interrupt(struct amd8111e_priv *lp);
124: static int amd8111e_get_mac_address(struct amd8111e_priv *lp);
125: static int amd8111e_init_rx_ring(struct amd8111e_priv *lp);
126: static int amd8111e_init_tx_ring(struct amd8111e_priv *lp);
127: static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index);
128: static void amd8111e_wait_link(struct amd8111e_priv *lp);
129: static void amd8111e_poll_link(struct amd8111e_priv *lp);
130: static void amd8111e_restart(struct amd8111e_priv *lp);
131:
132:
133: /*
134: * This function clears necessary the device registers.
135: */
136: static void amd8111e_init_hw_default(struct amd8111e_priv *lp)
137: {
138: unsigned int reg_val;
139: void *mmio = lp->mmio;
140:
141: /* stop the chip */
142: writel(RUN, mmio + CMD0);
143:
144: /* Clear RCV_RING_BASE_ADDR */
145: writel(0, mmio + RCV_RING_BASE_ADDR0);
146:
147: /* Clear XMT_RING_BASE_ADDR */
148: writel(0, mmio + XMT_RING_BASE_ADDR0);
149: writel(0, mmio + XMT_RING_BASE_ADDR1);
150: writel(0, mmio + XMT_RING_BASE_ADDR2);
151: writel(0, mmio + XMT_RING_BASE_ADDR3);
152:
153: /* Clear CMD0 */
154: writel(CMD0_CLEAR, mmio + CMD0);
155:
156: /* Clear CMD2 */
157: writel(CMD2_CLEAR, mmio + CMD2);
158:
159: /* Clear CMD7 */
160: writel(CMD7_CLEAR, mmio + CMD7);
161:
162: /* Clear DLY_INT_A and DLY_INT_B */
163: writel(0x0, mmio + DLY_INT_A);
164: writel(0x0, mmio + DLY_INT_B);
165:
166: /* Clear FLOW_CONTROL */
167: writel(0x0, mmio + FLOW_CONTROL);
168:
169: /* Clear INT0 write 1 to clear register */
170: reg_val = readl(mmio + INT0);
171: writel(reg_val, mmio + INT0);
172:
173: /* Clear STVAL */
174: writel(0x0, mmio + STVAL);
175:
176: /* Clear INTEN0 */
177: writel(INTEN0_CLEAR, mmio + INTEN0);
178:
179: /* Clear LADRF */
180: writel(0x0, mmio + LADRF);
181:
182: /* Set SRAM_SIZE & SRAM_BOUNDARY registers */
183: writel(0x80010, mmio + SRAM_SIZE);
184:
185: /* Clear RCV_RING0_LEN */
186: writel(0x0, mmio + RCV_RING_LEN0);
187:
188: /* Clear XMT_RING0/1/2/3_LEN */
189: writel(0x0, mmio + XMT_RING_LEN0);
190: writel(0x0, mmio + XMT_RING_LEN1);
191: writel(0x0, mmio + XMT_RING_LEN2);
192: writel(0x0, mmio + XMT_RING_LEN3);
193:
194: /* Clear XMT_RING_LIMIT */
195: writel(0x0, mmio + XMT_RING_LIMIT);
196:
197: /* Clear MIB */
198: writew(MIB_CLEAR, mmio + MIB_ADDR);
199:
200: /* Clear LARF */
201: writel( 0, mmio + LADRF);
202: writel( 0, mmio + LADRF + 4);
203:
204: /* SRAM_SIZE register */
205: reg_val = readl(mmio + SRAM_SIZE);
206:
207: /* Set default value to CTRL1 Register */
208: writel(CTRL1_DEFAULT, mmio + CTRL1);
209:
210: /* To avoid PCI posting bug */
211: readl(mmio + CMD2);
212: }
213:
214: /*
215: * This function initializes the device registers and starts the device.
216: */
217: static int amd8111e_start(struct amd8111e_priv *lp)
218: {
219: struct nic *nic = lp->nic;
220: void *mmio = lp->mmio;
221: int i, reg_val;
222:
223: /* stop the chip */
224: writel(RUN, mmio + CMD0);
225:
226: /* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */
227: writew(0x8100 | lp->ext_phy_addr, mmio + AUTOPOLL0);
228:
229: /* enable the port manager and set auto negotiation always */
230: writel(VAL1 | EN_PMGR, mmio + CMD3 );
231: writel(XPHYANE | XPHYRST, mmio + CTRL2);
232:
233: /* set control registers */
234: reg_val = readl(mmio + CTRL1);
235: reg_val &= ~XMTSP_MASK;
236: writel(reg_val | XMTSP_128 | CACHE_ALIGN, mmio + CTRL1);
237:
238: /* initialize tx and rx ring base addresses */
239: amd8111e_init_tx_ring(lp);
240: amd8111e_init_rx_ring(lp);
241: writel(virt_to_bus(lp->tx_ring), mmio + XMT_RING_BASE_ADDR0);
242: writel(virt_to_bus(lp->rx_ring), mmio + RCV_RING_BASE_ADDR0);
243: writew(NUM_TX_SLOTS, mmio + XMT_RING_LEN0);
244: writew(NUM_RX_SLOTS, mmio + RCV_RING_LEN0);
245:
246: /* set default IPG to 96 */
247: writew(DEFAULT_IPG, mmio + IPG);
248: writew(DEFAULT_IPG - IFS1_DELTA, mmio + IFS1);
249:
250: /* AutoPAD transmit, Retransmit on Underflow */
251: writel(VAL0 | APAD_XMT | REX_RTRY | REX_UFLO, mmio + CMD2);
252:
253: /* JUMBO disabled */
254: writel(JUMBO, mmio + CMD3);
255:
256: /* Setting the MAC address to the device */
257: for(i = 0; i < ETH_ALEN; i++)
258: writeb(nic->node_addr[i], mmio + PADR + i);
259:
260: /* set RUN bit to start the chip, interrupt not enabled */
261: writel(VAL2 | RDMD0 | VAL0 | RUN, mmio + CMD0);
262:
263: /* To avoid PCI posting bug */
264: readl(mmio + CMD0);
265: return 0;
266: }
267:
268: /*
269: This function will read the PHY registers.
270: */
271: static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val)
272: {
273: void *mmio = lp->mmio;
274: unsigned int reg_val;
275: unsigned int retry = PHY_RW_RETRY;
276:
277: reg_val = readl(mmio + PHY_ACCESS);
278: while (reg_val & PHY_CMD_ACTIVE)
279: reg_val = readl(mmio + PHY_ACCESS);
280:
281: writel(PHY_RD_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16),
282: mmio + PHY_ACCESS);
283: do {
284: reg_val = readl(mmio + PHY_ACCESS);
285: udelay(30); /* It takes 30 us to read/write data */
286: } while (--retry && (reg_val & PHY_CMD_ACTIVE));
287:
288: if (reg_val & PHY_RD_ERR) {
289: *val = 0;
290: return -1;
291: }
292:
293: *val = reg_val & 0xffff;
294: return 0;
295: }
296:
297: /*
298: This function will write into PHY registers.
299: */
300: #if 0
301: static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val)
302: {
303: void *mmio = lp->mmio;
304: unsigned int reg_val;
305: unsigned int retry = PHY_RW_RETRY;
306:
307: reg_val = readl(mmio + PHY_ACCESS);
308: while (reg_val & PHY_CMD_ACTIVE)
309: reg_val = readl(mmio + PHY_ACCESS);
310:
311: writel(PHY_WR_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16) | val,
312: mmio + PHY_ACCESS);
313: do {
314: reg_val = readl(mmio + PHY_ACCESS);
315: udelay(30); /* It takes 30 us to read/write the data */
316: } while (--retry && (reg_val & PHY_CMD_ACTIVE));
317:
318: if(reg_val & PHY_RD_ERR)
319: return -1;
320:
321: return 0;
322: }
323: #endif
324:
325: static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp)
326: {
327: int i;
328:
329: lp->ext_phy_id = 0;
330: lp->ext_phy_addr = 1;
331:
332: for (i = 0x1e; i >= 0; i--) {
333: u32 id1, id2;
334:
335: if (amd8111e_read_phy(lp, i, MII_PHYSID1, &id1))
336: continue;
337: if (amd8111e_read_phy(lp, i, MII_PHYSID2, &id2))
338: continue;
339: lp->ext_phy_id = (id1 << 16) | id2;
340: lp->ext_phy_addr = i;
341: break;
342: }
343:
344: if (lp->ext_phy_id)
345: printf("Found MII PHY ID 0x%08x at address 0x%02x\n",
346: (unsigned int) lp->ext_phy_id, lp->ext_phy_addr);
347: else
348: printf("Couldn't detect MII PHY, assuming address 0x01\n");
349: }
350:
351: static void amd8111e_disable_interrupt(struct amd8111e_priv *lp)
352: {
353: void *mmio = lp->mmio;
354: unsigned int int0;
355:
356: writel(INTREN, mmio + CMD0);
357: writel(INTEN0_CLEAR, mmio + INTEN0);
358: int0 = readl(mmio + INT0);
359: writel(int0, mmio + INT0);
360: readl(mmio + INT0);
361: }
362:
363: static void amd8111e_enable_interrupt(struct amd8111e_priv *lp)
364: {
365: void *mmio = lp->mmio;
366:
367: writel(VAL3 | LCINTEN | VAL1 | TINTEN0 | VAL0 | RINTEN0, mmio + INTEN0);
368: writel(VAL0 | INTREN, mmio + CMD0);
369: readl(mmio + CMD0);
370: }
371:
372: static void amd8111e_force_interrupt(struct amd8111e_priv *lp)
373: {
374: void *mmio = lp->mmio;
375:
376: writel(VAL0 | UINTCMD, mmio + CMD0);
377: readl(mmio + CMD0);
378: }
379:
380: static int amd8111e_get_mac_address(struct amd8111e_priv *lp)
381: {
382: struct nic *nic = lp->nic;
383: void *mmio = lp->mmio;
384: int i;
385:
386: /* BIOS should have set mac address to PADR register,
387: * so we read PADR to get it.
388: */
389: for (i = 0; i < ETH_ALEN; i++)
390: nic->node_addr[i] = readb(mmio + PADR + i);
391:
392: DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) );
393:
394: return 0;
395: }
396:
397: static int amd8111e_init_rx_ring(struct amd8111e_priv *lp)
398: {
399: int i;
400:
401: lp->rx_idx = 0;
402:
403: /* Initilaizing receive descriptors */
404: for (i = 0; i < NUM_RX_SLOTS; i++) {
405: lp->rx_ring[i].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[i]));
406: lp->rx_ring[i].buf_len = cpu_to_le16(RX_BUF_LEN);
407: wmb();
408: lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT);
409: }
410:
411: return 0;
412: }
413:
414: static int amd8111e_init_tx_ring(struct amd8111e_priv *lp)
415: {
416: int i;
417:
418: lp->tx_idx = 0;
419: lp->tx_consistent = 1;
420:
421: /* Initializing transmit descriptors */
422: for (i = 0; i < NUM_TX_SLOTS; i++) {
423: lp->tx_ring[i].tx_flags = 0;
424: lp->tx_ring[i].buf_phy_addr = 0;
425: lp->tx_ring[i].buf_len = 0;
426: }
427:
428: return 0;
429: }
430:
431: static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index)
432: {
433: volatile u16 status;
434: int retry = TX_RETRY;
435:
436: status = le16_to_cpu(lp->tx_ring[index].tx_flags);
437: while (--retry && (status & OWN_BIT)) {
438: mdelay(TX_PROCESS_TIME);
439: status = le16_to_cpu(lp->tx_ring[index].tx_flags);
440: }
441: if (status & OWN_BIT) {
442: printf("Error: tx slot %d timeout, stat = 0x%x\n", index, status);
443: amd8111e_restart(lp);
444: return -1;
445: }
446:
447: return 0;
448: }
449:
450: static void amd8111e_wait_link(struct amd8111e_priv *lp)
451: {
452: unsigned int status;
453: u32 reg_val;
454:
455: do {
456: /* read phy to update STAT0 register */
457: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val);
458: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val);
459: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val);
460: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val);
461: status = readl(lp->mmio + STAT0);
462: } while (!(status & AUTONEG_COMPLETE) || !(status & LINK_STATS));
463: }
464:
465: static void amd8111e_poll_link(struct amd8111e_priv *lp)
466: {
467: unsigned int status, speed;
468: u32 reg_val;
469:
470: if (!lp->link) {
471: /* read phy to update STAT0 register */
472: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val);
473: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val);
474: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val);
475: amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val);
476: status = readl(lp->mmio + STAT0);
477:
478: if (status & LINK_STATS) {
479: lp->link = 1;
480: speed = (status & SPEED_MASK) >> 7;
481: if (speed == PHY_SPEED_100)
482: lp->speed = 1;
483: else
484: lp->speed = 0;
485: if (status & FULL_DPLX)
486: lp->duplex = 1;
487: else
488: lp->duplex = 0;
489:
490: printf("Link is up: %s Mbps %s duplex\n",
491: lp->speed ? "100" : "10", lp->duplex ? "full" : "half");
492: }
493: } else {
494: status = readl(lp->mmio + STAT0);
495: if (!(status & LINK_STATS)) {
496: lp->link = 0;
497: printf("Link is down\n");
498: }
499: }
500: }
501:
502: static void amd8111e_restart(struct amd8111e_priv *lp)
503: {
504: printf("\nStarting nic...\n");
505: amd8111e_disable_interrupt(lp);
506: amd8111e_init_hw_default(lp);
507: amd8111e_probe_ext_phy(lp);
508: amd8111e_get_mac_address(lp);
509: amd8111e_start(lp);
510:
511: printf("Waiting link up...\n");
512: lp->link = 0;
513: amd8111e_wait_link(lp);
514: amd8111e_poll_link(lp);
515: }
516:
517:
518: /********************************************************
519: * Interface Functions *
520: ********************************************************/
521:
522: static void amd8111e_transmit(struct nic *nic, const char *dst_addr,
523: unsigned int type, unsigned int size, const char *packet)
524: {
525: struct amd8111e_priv *lp = nic->priv_data;
526: struct eth_frame *frame;
527: unsigned int index;
528:
529: /* check packet size */
530: if (size > TX_PKT_LEN_MAX) {
531: printf("amd8111e_transmit(): too large packet, drop\n");
532: return;
533: }
534:
535: /* get tx slot */
536: index = lp->tx_idx;
537: if (amd8111e_wait_tx_ring(lp, index))
538: return;
539:
540: /* fill frame */
541: frame = (struct eth_frame *)lp->tx_buf[index];
542: memset(frame->data, 0, TX_PKT_LEN_MAX);
543: memcpy(frame->dst_addr, dst_addr, ETH_ALEN);
544: memcpy(frame->src_addr, nic->node_addr, ETH_ALEN);
545: frame->type = htons(type);
546: memcpy(frame->data, packet, size);
547:
548: /* start xmit */
549: lp->tx_ring[index].buf_len = cpu_to_le16(ETH_HLEN + size);
550: lp->tx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(frame));
551: wmb();
552: lp->tx_ring[index].tx_flags =
553: cpu_to_le16(OWN_BIT | STP_BIT | ENP_BIT | ADD_FCS_BIT | LTINT_BIT);
554: writel(VAL1 | TDMD0, lp->mmio + CMD0);
555: readl(lp->mmio + CMD0);
556:
557: /* update slot pointer */
558: lp->tx_idx = (lp->tx_idx + 1) & TX_SLOTS_MASK;
559: }
560:
561: static int amd8111e_poll(struct nic *nic, int retrieve)
562: {
563: /* return true if there's an ethernet packet ready to read */
564: /* nic->packet should contain data on return */
565: /* nic->packetlen should contain length of data */
566:
567: struct amd8111e_priv *lp = nic->priv_data;
568: u16 status, pkt_len;
569: unsigned int index, pkt_ok;
570:
571: amd8111e_poll_link(lp);
572:
573: index = lp->rx_idx;
574: status = le16_to_cpu(lp->rx_ring[index].rx_flags);
575: pkt_len = le16_to_cpu(lp->rx_ring[index].msg_len) - 4; /* remove 4bytes FCS */
576:
577: if (status & OWN_BIT)
578: return 0;
579:
580: if (status & ERR_BIT)
581: pkt_ok = 0;
582: else if (!(status & STP_BIT))
583: pkt_ok = 0;
584: else if (!(status & ENP_BIT))
585: pkt_ok = 0;
586: else if (pkt_len < RX_PKT_LEN_MIN)
587: pkt_ok = 0;
588: else if (pkt_len > RX_PKT_LEN_MAX)
589: pkt_ok = 0;
590: else
591: pkt_ok = 1;
592:
593: if (pkt_ok) {
594: if (!retrieve)
595: return 1;
596: nic->packetlen = pkt_len;
597: memcpy(nic->packet, lp->rx_buf[index], nic->packetlen);
598: }
599:
600: lp->rx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[index]));
601: lp->rx_ring[index].buf_len = cpu_to_le16(RX_BUF_LEN);
602: wmb();
603: lp->rx_ring[index].rx_flags = cpu_to_le16(OWN_BIT);
604: writel(VAL2 | RDMD0, lp->mmio + CMD0);
605: readl(lp->mmio + CMD0);
606:
607: lp->rx_idx = (lp->rx_idx + 1) & RX_SLOTS_MASK;
608: return pkt_ok;
609: }
610:
611: static void amd8111e_disable(struct nic *nic)
612: {
613: struct amd8111e_priv *lp = nic->priv_data;
614:
615: /* disable interrupt */
616: amd8111e_disable_interrupt(lp);
617:
618: /* stop chip */
619: amd8111e_init_hw_default(lp);
620:
621: /* unmap mmio */
622: iounmap(lp->mmio);
623:
624: /* update status */
625: lp->opened = 0;
626: }
627:
628: static void amd8111e_irq(struct nic *nic, irq_action_t action)
629: {
630: struct amd8111e_priv *lp = nic->priv_data;
631:
632: switch (action) {
633: case DISABLE:
634: amd8111e_disable_interrupt(lp);
635: break;
636: case ENABLE:
637: amd8111e_enable_interrupt(lp);
638: break;
639: case FORCE:
640: amd8111e_force_interrupt(lp);
641: break;
642: }
643: }
644:
645: static struct nic_operations amd8111e_operations = {
646: .connect = dummy_connect,
647: .poll = amd8111e_poll,
648: .transmit = amd8111e_transmit,
649: .irq = amd8111e_irq,
650: };
651:
652: static int amd8111e_probe(struct nic *nic, struct pci_device *pdev)
653: {
654: struct amd8111e_priv *lp = &amd8111e;
655: unsigned long mmio_start, mmio_len;
656:
657: nic->ioaddr = pdev->ioaddr;
658: nic->irqno = pdev->irq;
659:
660: mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
661: mmio_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0);
662:
663: memset(lp, 0, sizeof(*lp));
664: lp->pdev = pdev;
665: lp->nic = nic;
666: lp->mmio = ioremap(mmio_start, mmio_len);
667: lp->opened = 1;
668: adjust_pci_device(pdev);
669:
670: nic->priv_data = lp;
671:
672: amd8111e_restart(lp);
673:
674: nic->nic_op = &amd8111e_operations;
675: return 1;
676: }
677:
678: static struct pci_device_id amd8111e_nics[] = {
679: PCI_ROM(0x1022, 0x7462, "amd8111e", "AMD8111E", 0),
680: };
681:
682: PCI_DRIVER ( amd8111e_driver, amd8111e_nics, PCI_NO_CLASS );
683:
684: DRIVER ( "AMD8111E", nic_driver, pci_driver, amd8111e_driver,
685: amd8111e_probe, amd8111e_disable );
686:
687: /*
688: * Local variables:
689: * c-basic-offset: 8
690: * c-indent-level: 8
691: * tab-width: 8
692: * End:
693: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.