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, ®_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 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, ®_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 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