1/* Advanced  Micro Devices Inc. AMD8111E Linux Network Driver
2 * Copyright (C) 2004 Advanced Micro Devices
3 * Copyright (C) 2005 Liu Tao <liutao1980@gmail.com> [etherboot port]
4 *
5 * Copyright 2001,2002 Jeff Garzik <jgarzik@mandrakesoft.com> [ 8139cp.c,tg3.c ]
6 * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)[ 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, carstenl@mips.com [ 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
31FILE_LICENCE ( GPL2_OR_LATER );
32
33#include "etherboot.h"
34#include "nic.h"
35#include "mii.h"
36#include <gpxe/pci.h>
37#include <gpxe/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
63struct 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
72struct 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
81struct 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
88struct 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
108static struct amd8111e_priv amd8111e;
109
110
111/********************************************************
112 * 		locale functions			*
113 ********************************************************/
114static void amd8111e_init_hw_default(struct amd8111e_priv *lp);
115static int amd8111e_start(struct amd8111e_priv *lp);
116static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val);
117#if 0
118static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val);
119#endif
120static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp);
121static void amd8111e_disable_interrupt(struct amd8111e_priv *lp);
122static void amd8111e_enable_interrupt(struct amd8111e_priv *lp);
123static void amd8111e_force_interrupt(struct amd8111e_priv *lp);
124static int amd8111e_get_mac_address(struct amd8111e_priv *lp);
125static int amd8111e_init_rx_ring(struct amd8111e_priv *lp);
126static int amd8111e_init_tx_ring(struct amd8111e_priv *lp);
127static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index);
128static void amd8111e_wait_link(struct amd8111e_priv *lp);
129static void amd8111e_poll_link(struct amd8111e_priv *lp);
130static void amd8111e_restart(struct amd8111e_priv *lp);
131
132
133/*
134 * This function clears necessary the device registers.
135 */
136static 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 */
217static 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/*
269This function will read the PHY registers.
270*/
271static 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/*
298This function will write into PHY registers.
299*/
300#if 0
301static 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
325static 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
351static 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
363static 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
372static 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
380static 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
397static 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
414static 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
431static 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
450static 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, &reg_val);
458		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, &reg_val);
459		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, &reg_val);
460		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, &reg_val);
461		status = readl(lp->mmio + STAT0);
462	} while (!(status & AUTONEG_COMPLETE) || !(status & LINK_STATS));
463}
464
465static 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, &reg_val);
473		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, &reg_val);
474		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, &reg_val);
475		amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, &reg_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
502static 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
522static 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
561static 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
611static 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
628static 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
645static struct nic_operations amd8111e_operations = {
646	.connect	= dummy_connect,
647	.poll		= amd8111e_poll,
648	.transmit	= amd8111e_transmit,
649	.irq		= amd8111e_irq,
650};
651
652static 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
678static struct pci_device_id amd8111e_nics[] = {
679	PCI_ROM(0x1022, 0x7462, "amd8111e",	"AMD8111E", 0),
680};
681
682PCI_DRIVER ( amd8111e_driver, amd8111e_nics, PCI_NO_CLASS );
683
684DRIVER ( "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 */
694