00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 FILE_LICENCE ( GPL2_OR_LATER );
00032
00033 #include "etherboot.h"
00034 #include "nic.h"
00035 #include "mii.h"
00036 #include <gpxe/pci.h>
00037 #include <gpxe/ethernet.h>
00038 #include "string.h"
00039 #include "stdint.h"
00040 #include "amd8111e.h"
00041
00042
00043
00044 #define NUM_TX_SLOTS 2
00045 #define NUM_RX_SLOTS 4
00046 #define TX_SLOTS_MASK 1
00047 #define RX_SLOTS_MASK 3
00048
00049 #define TX_BUF_LEN 1536
00050 #define RX_BUF_LEN 1536
00051
00052 #define TX_PKT_LEN_MAX (ETH_FRAME_LEN - ETH_HLEN)
00053 #define RX_PKT_LEN_MIN 60
00054 #define RX_PKT_LEN_MAX ETH_FRAME_LEN
00055
00056 #define TX_TIMEOUT 3000
00057 #define TX_PROCESS_TIME 10
00058 #define TX_RETRY (TX_TIMEOUT / TX_PROCESS_TIME)
00059
00060 #define PHY_RW_RETRY 10
00061
00062
00063 struct amd8111e_tx_desc {
00064 u16 buf_len;
00065 u16 tx_flags;
00066 u16 tag_ctrl_info;
00067 u16 tag_ctrl_cmd;
00068 u32 buf_phy_addr;
00069 u32 reserved;
00070 };
00071
00072 struct amd8111e_rx_desc {
00073 u32 reserved;
00074 u16 msg_len;
00075 u16 tag_ctrl_info;
00076 u16 buf_len;
00077 u16 rx_flags;
00078 u32 buf_phy_addr;
00079 };
00080
00081 struct eth_frame {
00082 u8 dst_addr[ETH_ALEN];
00083 u8 src_addr[ETH_ALEN];
00084 u16 type;
00085 u8 data[ETH_FRAME_LEN - ETH_HLEN];
00086 } __attribute__((packed));
00087
00088 struct amd8111e_priv {
00089 struct amd8111e_tx_desc tx_ring[NUM_TX_SLOTS];
00090 struct amd8111e_rx_desc rx_ring[NUM_RX_SLOTS];
00091 unsigned char tx_buf[NUM_TX_SLOTS][TX_BUF_LEN];
00092 unsigned char rx_buf[NUM_RX_SLOTS][RX_BUF_LEN];
00093 unsigned long tx_idx, rx_idx;
00094 int tx_consistent;
00095
00096 char opened;
00097 char link;
00098 char speed;
00099 char duplex;
00100 int ext_phy_addr;
00101 u32 ext_phy_id;
00102
00103 struct pci_device *pdev;
00104 struct nic *nic;
00105 void *mmio;
00106 };
00107
00108 static struct amd8111e_priv amd8111e;
00109
00110
00111
00112
00113
00114 static void amd8111e_init_hw_default(struct amd8111e_priv *lp);
00115 static int amd8111e_start(struct amd8111e_priv *lp);
00116 static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val);
00117 #if 0
00118 static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val);
00119 #endif
00120 static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp);
00121 static void amd8111e_disable_interrupt(struct amd8111e_priv *lp);
00122 static void amd8111e_enable_interrupt(struct amd8111e_priv *lp);
00123 static void amd8111e_force_interrupt(struct amd8111e_priv *lp);
00124 static int amd8111e_get_mac_address(struct amd8111e_priv *lp);
00125 static int amd8111e_init_rx_ring(struct amd8111e_priv *lp);
00126 static int amd8111e_init_tx_ring(struct amd8111e_priv *lp);
00127 static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index);
00128 static void amd8111e_wait_link(struct amd8111e_priv *lp);
00129 static void amd8111e_poll_link(struct amd8111e_priv *lp);
00130 static void amd8111e_restart(struct amd8111e_priv *lp);
00131
00132
00133
00134
00135
00136 static void amd8111e_init_hw_default(struct amd8111e_priv *lp)
00137 {
00138 unsigned int reg_val;
00139 void *mmio = lp->mmio;
00140
00141
00142 writel(RUN, mmio + CMD0);
00143
00144
00145 writel(0, mmio + RCV_RING_BASE_ADDR0);
00146
00147
00148 writel(0, mmio + XMT_RING_BASE_ADDR0);
00149 writel(0, mmio + XMT_RING_BASE_ADDR1);
00150 writel(0, mmio + XMT_RING_BASE_ADDR2);
00151 writel(0, mmio + XMT_RING_BASE_ADDR3);
00152
00153
00154 writel(CMD0_CLEAR, mmio + CMD0);
00155
00156
00157 writel(CMD2_CLEAR, mmio + CMD2);
00158
00159
00160 writel(CMD7_CLEAR, mmio + CMD7);
00161
00162
00163 writel(0x0, mmio + DLY_INT_A);
00164 writel(0x0, mmio + DLY_INT_B);
00165
00166
00167 writel(0x0, mmio + FLOW_CONTROL);
00168
00169
00170 reg_val = readl(mmio + INT0);
00171 writel(reg_val, mmio + INT0);
00172
00173
00174 writel(0x0, mmio + STVAL);
00175
00176
00177 writel(INTEN0_CLEAR, mmio + INTEN0);
00178
00179
00180 writel(0x0, mmio + LADRF);
00181
00182
00183 writel(0x80010, mmio + SRAM_SIZE);
00184
00185
00186 writel(0x0, mmio + RCV_RING_LEN0);
00187
00188
00189 writel(0x0, mmio + XMT_RING_LEN0);
00190 writel(0x0, mmio + XMT_RING_LEN1);
00191 writel(0x0, mmio + XMT_RING_LEN2);
00192 writel(0x0, mmio + XMT_RING_LEN3);
00193
00194
00195 writel(0x0, mmio + XMT_RING_LIMIT);
00196
00197
00198 writew(MIB_CLEAR, mmio + MIB_ADDR);
00199
00200
00201 writel( 0, mmio + LADRF);
00202 writel( 0, mmio + LADRF + 4);
00203
00204
00205 reg_val = readl(mmio + SRAM_SIZE);
00206
00207
00208 writel(CTRL1_DEFAULT, mmio + CTRL1);
00209
00210
00211 readl(mmio + CMD2);
00212 }
00213
00214
00215
00216
00217 static int amd8111e_start(struct amd8111e_priv *lp)
00218 {
00219 struct nic *nic = lp->nic;
00220 void *mmio = lp->mmio;
00221 int i, reg_val;
00222
00223
00224 writel(RUN, mmio + CMD0);
00225
00226
00227 writew(0x8100 | lp->ext_phy_addr, mmio + AUTOPOLL0);
00228
00229
00230 writel(VAL1 | EN_PMGR, mmio + CMD3 );
00231 writel(XPHYANE | XPHYRST, mmio + CTRL2);
00232
00233
00234 reg_val = readl(mmio + CTRL1);
00235 reg_val &= ~XMTSP_MASK;
00236 writel(reg_val | XMTSP_128 | CACHE_ALIGN, mmio + CTRL1);
00237
00238
00239 amd8111e_init_tx_ring(lp);
00240 amd8111e_init_rx_ring(lp);
00241 writel(virt_to_bus(lp->tx_ring), mmio + XMT_RING_BASE_ADDR0);
00242 writel(virt_to_bus(lp->rx_ring), mmio + RCV_RING_BASE_ADDR0);
00243 writew(NUM_TX_SLOTS, mmio + XMT_RING_LEN0);
00244 writew(NUM_RX_SLOTS, mmio + RCV_RING_LEN0);
00245
00246
00247 writew(DEFAULT_IPG, mmio + IPG);
00248 writew(DEFAULT_IPG - IFS1_DELTA, mmio + IFS1);
00249
00250
00251 writel(VAL0 | APAD_XMT | REX_RTRY | REX_UFLO, mmio + CMD2);
00252
00253
00254 writel(JUMBO, mmio + CMD3);
00255
00256
00257 for(i = 0; i < ETH_ALEN; i++)
00258 writeb(nic->node_addr[i], mmio + PADR + i);
00259
00260
00261 writel(VAL2 | RDMD0 | VAL0 | RUN, mmio + CMD0);
00262
00263
00264 readl(mmio + CMD0);
00265 return 0;
00266 }
00267
00268
00269
00270
00271 static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val)
00272 {
00273 void *mmio = lp->mmio;
00274 unsigned int reg_val;
00275 unsigned int retry = PHY_RW_RETRY;
00276
00277 reg_val = readl(mmio + PHY_ACCESS);
00278 while (reg_val & PHY_CMD_ACTIVE)
00279 reg_val = readl(mmio + PHY_ACCESS);
00280
00281 writel(PHY_RD_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16),
00282 mmio + PHY_ACCESS);
00283 do {
00284 reg_val = readl(mmio + PHY_ACCESS);
00285 udelay(30);
00286 } while (--retry && (reg_val & PHY_CMD_ACTIVE));
00287
00288 if (reg_val & PHY_RD_ERR) {
00289 *val = 0;
00290 return -1;
00291 }
00292
00293 *val = reg_val & 0xffff;
00294 return 0;
00295 }
00296
00297
00298
00299
00300 #if 0
00301 static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_addr, int reg, u32 val)
00302 {
00303 void *mmio = lp->mmio;
00304 unsigned int reg_val;
00305 unsigned int retry = PHY_RW_RETRY;
00306
00307 reg_val = readl(mmio + PHY_ACCESS);
00308 while (reg_val & PHY_CMD_ACTIVE)
00309 reg_val = readl(mmio + PHY_ACCESS);
00310
00311 writel(PHY_WR_CMD | ((phy_addr & 0x1f) << 21) | ((reg & 0x1f) << 16) | val,
00312 mmio + PHY_ACCESS);
00313 do {
00314 reg_val = readl(mmio + PHY_ACCESS);
00315 udelay(30);
00316 } while (--retry && (reg_val & PHY_CMD_ACTIVE));
00317
00318 if(reg_val & PHY_RD_ERR)
00319 return -1;
00320
00321 return 0;
00322 }
00323 #endif
00324
00325 static void amd8111e_probe_ext_phy(struct amd8111e_priv *lp)
00326 {
00327 int i;
00328
00329 lp->ext_phy_id = 0;
00330 lp->ext_phy_addr = 1;
00331
00332 for (i = 0x1e; i >= 0; i--) {
00333 u32 id1, id2;
00334
00335 if (amd8111e_read_phy(lp, i, MII_PHYSID1, &id1))
00336 continue;
00337 if (amd8111e_read_phy(lp, i, MII_PHYSID2, &id2))
00338 continue;
00339 lp->ext_phy_id = (id1 << 16) | id2;
00340 lp->ext_phy_addr = i;
00341 break;
00342 }
00343
00344 if (lp->ext_phy_id)
00345 printf("Found MII PHY ID 0x%08x at address 0x%02x\n",
00346 (unsigned int) lp->ext_phy_id, lp->ext_phy_addr);
00347 else
00348 printf("Couldn't detect MII PHY, assuming address 0x01\n");
00349 }
00350
00351 static void amd8111e_disable_interrupt(struct amd8111e_priv *lp)
00352 {
00353 void *mmio = lp->mmio;
00354 unsigned int int0;
00355
00356 writel(INTREN, mmio + CMD0);
00357 writel(INTEN0_CLEAR, mmio + INTEN0);
00358 int0 = readl(mmio + INT0);
00359 writel(int0, mmio + INT0);
00360 readl(mmio + INT0);
00361 }
00362
00363 static void amd8111e_enable_interrupt(struct amd8111e_priv *lp)
00364 {
00365 void *mmio = lp->mmio;
00366
00367 writel(VAL3 | LCINTEN | VAL1 | TINTEN0 | VAL0 | RINTEN0, mmio + INTEN0);
00368 writel(VAL0 | INTREN, mmio + CMD0);
00369 readl(mmio + CMD0);
00370 }
00371
00372 static void amd8111e_force_interrupt(struct amd8111e_priv *lp)
00373 {
00374 void *mmio = lp->mmio;
00375
00376 writel(VAL0 | UINTCMD, mmio + CMD0);
00377 readl(mmio + CMD0);
00378 }
00379
00380 static int amd8111e_get_mac_address(struct amd8111e_priv *lp)
00381 {
00382 struct nic *nic = lp->nic;
00383 void *mmio = lp->mmio;
00384 int i;
00385
00386
00387
00388
00389 for (i = 0; i < ETH_ALEN; i++)
00390 nic->node_addr[i] = readb(mmio + PADR + i);
00391
00392 DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) );
00393
00394 return 0;
00395 }
00396
00397 static int amd8111e_init_rx_ring(struct amd8111e_priv *lp)
00398 {
00399 int i;
00400
00401 lp->rx_idx = 0;
00402
00403
00404 for (i = 0; i < NUM_RX_SLOTS; i++) {
00405 lp->rx_ring[i].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[i]));
00406 lp->rx_ring[i].buf_len = cpu_to_le16(RX_BUF_LEN);
00407 wmb();
00408 lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT);
00409 }
00410
00411 return 0;
00412 }
00413
00414 static int amd8111e_init_tx_ring(struct amd8111e_priv *lp)
00415 {
00416 int i;
00417
00418 lp->tx_idx = 0;
00419 lp->tx_consistent = 1;
00420
00421
00422 for (i = 0; i < NUM_TX_SLOTS; i++) {
00423 lp->tx_ring[i].tx_flags = 0;
00424 lp->tx_ring[i].buf_phy_addr = 0;
00425 lp->tx_ring[i].buf_len = 0;
00426 }
00427
00428 return 0;
00429 }
00430
00431 static int amd8111e_wait_tx_ring(struct amd8111e_priv *lp, unsigned int index)
00432 {
00433 volatile u16 status;
00434 int retry = TX_RETRY;
00435
00436 status = le16_to_cpu(lp->tx_ring[index].tx_flags);
00437 while (--retry && (status & OWN_BIT)) {
00438 mdelay(TX_PROCESS_TIME);
00439 status = le16_to_cpu(lp->tx_ring[index].tx_flags);
00440 }
00441 if (status & OWN_BIT) {
00442 printf("Error: tx slot %d timeout, stat = 0x%x\n", index, status);
00443 amd8111e_restart(lp);
00444 return -1;
00445 }
00446
00447 return 0;
00448 }
00449
00450 static void amd8111e_wait_link(struct amd8111e_priv *lp)
00451 {
00452 unsigned int status;
00453 u32 reg_val;
00454
00455 do {
00456
00457 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val);
00458 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val);
00459 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val);
00460 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val);
00461 status = readl(lp->mmio + STAT0);
00462 } while (!(status & AUTONEG_COMPLETE) || !(status & LINK_STATS));
00463 }
00464
00465 static void amd8111e_poll_link(struct amd8111e_priv *lp)
00466 {
00467 unsigned int status, speed;
00468 u32 reg_val;
00469
00470 if (!lp->link) {
00471
00472 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMCR, ®_val);
00473 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_BMSR, ®_val);
00474 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_ADVERTISE, ®_val);
00475 amd8111e_read_phy(lp, lp->ext_phy_addr, MII_LPA, ®_val);
00476 status = readl(lp->mmio + STAT0);
00477
00478 if (status & LINK_STATS) {
00479 lp->link = 1;
00480 speed = (status & SPEED_MASK) >> 7;
00481 if (speed == PHY_SPEED_100)
00482 lp->speed = 1;
00483 else
00484 lp->speed = 0;
00485 if (status & FULL_DPLX)
00486 lp->duplex = 1;
00487 else
00488 lp->duplex = 0;
00489
00490 printf("Link is up: %s Mbps %s duplex\n",
00491 lp->speed ? "100" : "10", lp->duplex ? "full" : "half");
00492 }
00493 } else {
00494 status = readl(lp->mmio + STAT0);
00495 if (!(status & LINK_STATS)) {
00496 lp->link = 0;
00497 printf("Link is down\n");
00498 }
00499 }
00500 }
00501
00502 static void amd8111e_restart(struct amd8111e_priv *lp)
00503 {
00504 printf("\nStarting nic...\n");
00505 amd8111e_disable_interrupt(lp);
00506 amd8111e_init_hw_default(lp);
00507 amd8111e_probe_ext_phy(lp);
00508 amd8111e_get_mac_address(lp);
00509 amd8111e_start(lp);
00510
00511 printf("Waiting link up...\n");
00512 lp->link = 0;
00513 amd8111e_wait_link(lp);
00514 amd8111e_poll_link(lp);
00515 }
00516
00517
00518
00519
00520
00521
00522 static void amd8111e_transmit(struct nic *nic, const char *dst_addr,
00523 unsigned int type, unsigned int size, const char *packet)
00524 {
00525 struct amd8111e_priv *lp = nic->priv_data;
00526 struct eth_frame *frame;
00527 unsigned int index;
00528
00529
00530 if (size > TX_PKT_LEN_MAX) {
00531 printf("amd8111e_transmit(): too large packet, drop\n");
00532 return;
00533 }
00534
00535
00536 index = lp->tx_idx;
00537 if (amd8111e_wait_tx_ring(lp, index))
00538 return;
00539
00540
00541 frame = (struct eth_frame *)lp->tx_buf[index];
00542 memset(frame->data, 0, TX_PKT_LEN_MAX);
00543 memcpy(frame->dst_addr, dst_addr, ETH_ALEN);
00544 memcpy(frame->src_addr, nic->node_addr, ETH_ALEN);
00545 frame->type = htons(type);
00546 memcpy(frame->data, packet, size);
00547
00548
00549 lp->tx_ring[index].buf_len = cpu_to_le16(ETH_HLEN + size);
00550 lp->tx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(frame));
00551 wmb();
00552 lp->tx_ring[index].tx_flags =
00553 cpu_to_le16(OWN_BIT | STP_BIT | ENP_BIT | ADD_FCS_BIT | LTINT_BIT);
00554 writel(VAL1 | TDMD0, lp->mmio + CMD0);
00555 readl(lp->mmio + CMD0);
00556
00557
00558 lp->tx_idx = (lp->tx_idx + 1) & TX_SLOTS_MASK;
00559 }
00560
00561 static int amd8111e_poll(struct nic *nic, int retrieve)
00562 {
00563
00564
00565
00566
00567 struct amd8111e_priv *lp = nic->priv_data;
00568 u16 status, pkt_len;
00569 unsigned int index, pkt_ok;
00570
00571 amd8111e_poll_link(lp);
00572
00573 index = lp->rx_idx;
00574 status = le16_to_cpu(lp->rx_ring[index].rx_flags);
00575 pkt_len = le16_to_cpu(lp->rx_ring[index].msg_len) - 4;
00576
00577 if (status & OWN_BIT)
00578 return 0;
00579
00580 if (status & ERR_BIT)
00581 pkt_ok = 0;
00582 else if (!(status & STP_BIT))
00583 pkt_ok = 0;
00584 else if (!(status & ENP_BIT))
00585 pkt_ok = 0;
00586 else if (pkt_len < RX_PKT_LEN_MIN)
00587 pkt_ok = 0;
00588 else if (pkt_len > RX_PKT_LEN_MAX)
00589 pkt_ok = 0;
00590 else
00591 pkt_ok = 1;
00592
00593 if (pkt_ok) {
00594 if (!retrieve)
00595 return 1;
00596 nic->packetlen = pkt_len;
00597 memcpy(nic->packet, lp->rx_buf[index], nic->packetlen);
00598 }
00599
00600 lp->rx_ring[index].buf_phy_addr = cpu_to_le32(virt_to_bus(lp->rx_buf[index]));
00601 lp->rx_ring[index].buf_len = cpu_to_le16(RX_BUF_LEN);
00602 wmb();
00603 lp->rx_ring[index].rx_flags = cpu_to_le16(OWN_BIT);
00604 writel(VAL2 | RDMD0, lp->mmio + CMD0);
00605 readl(lp->mmio + CMD0);
00606
00607 lp->rx_idx = (lp->rx_idx + 1) & RX_SLOTS_MASK;
00608 return pkt_ok;
00609 }
00610
00611 static void amd8111e_disable(struct nic *nic)
00612 {
00613 struct amd8111e_priv *lp = nic->priv_data;
00614
00615
00616 amd8111e_disable_interrupt(lp);
00617
00618
00619 amd8111e_init_hw_default(lp);
00620
00621
00622 iounmap(lp->mmio);
00623
00624
00625 lp->opened = 0;
00626 }
00627
00628 static void amd8111e_irq(struct nic *nic, irq_action_t action)
00629 {
00630 struct amd8111e_priv *lp = nic->priv_data;
00631
00632 switch (action) {
00633 case DISABLE:
00634 amd8111e_disable_interrupt(lp);
00635 break;
00636 case ENABLE:
00637 amd8111e_enable_interrupt(lp);
00638 break;
00639 case FORCE:
00640 amd8111e_force_interrupt(lp);
00641 break;
00642 }
00643 }
00644
00645 static struct nic_operations amd8111e_operations = {
00646 .connect = dummy_connect,
00647 .poll = amd8111e_poll,
00648 .transmit = amd8111e_transmit,
00649 .irq = amd8111e_irq,
00650 };
00651
00652 static int amd8111e_probe(struct nic *nic, struct pci_device *pdev)
00653 {
00654 struct amd8111e_priv *lp = &amd8111e;
00655 unsigned long mmio_start, mmio_len;
00656
00657 nic->ioaddr = pdev->ioaddr;
00658 nic->irqno = pdev->irq;
00659
00660 mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
00661 mmio_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0);
00662
00663 memset(lp, 0, sizeof(*lp));
00664 lp->pdev = pdev;
00665 lp->nic = nic;
00666 lp->mmio = ioremap(mmio_start, mmio_len);
00667 lp->opened = 1;
00668 adjust_pci_device(pdev);
00669
00670 nic->priv_data = lp;
00671
00672 amd8111e_restart(lp);
00673
00674 nic->nic_op = &amd8111e_operations;
00675 return 1;
00676 }
00677
00678 static struct pci_device_id amd8111e_nics[] = {
00679 PCI_ROM(0x1022, 0x7462, "amd8111e", "AMD8111E", 0),
00680 };
00681
00682 PCI_DRIVER ( amd8111e_driver, amd8111e_nics, PCI_NO_CLASS );
00683
00684 DRIVER ( "AMD8111E", nic_driver, pci_driver, amd8111e_driver,
00685 amd8111e_probe, amd8111e_disable );
00686
00687
00688
00689
00690
00691
00692
00693