#include "etherboot.h"#include "nic.h"#include "mii.h"#include <gpxe/pci.h>#include <gpxe/ethernet.h>#include "string.h"#include "stdint.h"#include "amd8111e.h"Go to the source code of this file.
Data Structures | |
| struct | amd8111e_tx_desc |
| struct | amd8111e_rx_desc |
| struct | eth_frame |
| struct | amd8111e_priv |
Defines | |
| #define | NUM_TX_SLOTS 2 |
| #define | NUM_RX_SLOTS 4 |
| #define | TX_SLOTS_MASK 1 |
| #define | RX_SLOTS_MASK 3 |
| #define | TX_BUF_LEN 1536 |
| #define | RX_BUF_LEN 1536 |
| #define | TX_PKT_LEN_MAX (ETH_FRAME_LEN - ETH_HLEN) |
| #define | RX_PKT_LEN_MIN 60 |
| #define | RX_PKT_LEN_MAX ETH_FRAME_LEN |
| #define | TX_TIMEOUT 3000 |
| #define | TX_PROCESS_TIME 10 |
| #define | TX_RETRY (TX_TIMEOUT / TX_PROCESS_TIME) |
| #define | PHY_RW_RETRY 10 |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static void | amd8111e_init_hw_default (struct amd8111e_priv *lp) |
| static int | amd8111e_start (struct amd8111e_priv *lp) |
| static int | amd8111e_read_phy (struct amd8111e_priv *lp, int phy_addr, int reg, u32 *val) |
| static void | amd8111e_probe_ext_phy (struct amd8111e_priv *lp) |
| static void | amd8111e_disable_interrupt (struct amd8111e_priv *lp) |
| static void | amd8111e_enable_interrupt (struct amd8111e_priv *lp) |
| static void | amd8111e_force_interrupt (struct amd8111e_priv *lp) |
| static int | amd8111e_get_mac_address (struct amd8111e_priv *lp) |
| static int | amd8111e_init_rx_ring (struct amd8111e_priv *lp) |
| static int | amd8111e_init_tx_ring (struct amd8111e_priv *lp) |
| static int | amd8111e_wait_tx_ring (struct amd8111e_priv *lp, unsigned int index) |
| static void | amd8111e_wait_link (struct amd8111e_priv *lp) |
| static void | amd8111e_poll_link (struct amd8111e_priv *lp) |
| static void | amd8111e_restart (struct amd8111e_priv *lp) |
| static void | amd8111e_transmit (struct nic *nic, const char *dst_addr, unsigned int type, unsigned int size, const char *packet) |
| static int | amd8111e_poll (struct nic *nic, int retrieve) |
| static void | amd8111e_disable (struct nic *nic) |
| static void | amd8111e_irq (struct nic *nic, irq_action_t action) |
| static int | amd8111e_probe (struct nic *nic, struct pci_device *pdev) |
| PCI_DRIVER (amd8111e_driver, amd8111e_nics, PCI_NO_CLASS) | |
| DRIVER ("AMD8111E", nic_driver, pci_driver, amd8111e_driver, amd8111e_probe, amd8111e_disable) | |
Variables | |
| static struct amd8111e_priv | amd8111e |
| static struct nic_operations | amd8111e_operations |
| static struct pci_device_id | amd8111e_nics [] |
| #define NUM_TX_SLOTS 2 |
Definition at line 44 of file amd8111e.c.
Referenced by amd8111e_init_tx_ring(), and amd8111e_start().
| #define NUM_RX_SLOTS 4 |
Definition at line 45 of file amd8111e.c.
Referenced by amd8111e_init_rx_ring(), and amd8111e_start().
| #define TX_SLOTS_MASK 1 |
| #define RX_SLOTS_MASK 3 |
| #define TX_BUF_LEN 1536 |
Definition at line 49 of file amd8111e.c.
| #define RX_BUF_LEN 1536 |
Definition at line 50 of file amd8111e.c.
Referenced by amd8111e_init_rx_ring(), amd8111e_poll(), rtl_open(), and rtl_poll().
| #define TX_PKT_LEN_MAX (ETH_FRAME_LEN - ETH_HLEN) |
| #define RX_PKT_LEN_MIN 60 |
| #define RX_PKT_LEN_MAX ETH_FRAME_LEN |
| #define TX_TIMEOUT 3000 |
Definition at line 56 of file amd8111e.c.
Referenced by sis900_transmit(), velocity_transmit(), and w89c840_transmit().
| #define TX_PROCESS_TIME 10 |
| #define TX_RETRY (TX_TIMEOUT / TX_PROCESS_TIME) |
| #define PHY_RW_RETRY 10 |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static void amd8111e_init_hw_default | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 136 of file amd8111e.c.
References CMD0, CMD0_CLEAR, CMD2, CMD2_CLEAR, CMD7, CMD7_CLEAR, CTRL1, CTRL1_DEFAULT, DLY_INT_A, DLY_INT_B, FLOW_CONTROL, INT0, INTEN0, INTEN0_CLEAR, LADRF, MIB_ADDR, MIB_CLEAR, amd8111e_priv::mmio, RCV_RING_BASE_ADDR0, RCV_RING_LEN0, readl, RUN, SRAM_SIZE, STVAL, writel, writew, XMT_RING_BASE_ADDR0, XMT_RING_BASE_ADDR1, XMT_RING_BASE_ADDR2, XMT_RING_BASE_ADDR3, XMT_RING_LEN0, XMT_RING_LEN1, XMT_RING_LEN2, XMT_RING_LEN3, and XMT_RING_LIMIT.
Referenced by amd8111e_disable(), and amd8111e_restart().
00137 { 00138 unsigned int reg_val; 00139 void *mmio = lp->mmio; 00140 00141 /* stop the chip */ 00142 writel(RUN, mmio + CMD0); 00143 00144 /* Clear RCV_RING_BASE_ADDR */ 00145 writel(0, mmio + RCV_RING_BASE_ADDR0); 00146 00147 /* Clear XMT_RING_BASE_ADDR */ 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 /* Clear CMD0 */ 00154 writel(CMD0_CLEAR, mmio + CMD0); 00155 00156 /* Clear CMD2 */ 00157 writel(CMD2_CLEAR, mmio + CMD2); 00158 00159 /* Clear CMD7 */ 00160 writel(CMD7_CLEAR, mmio + CMD7); 00161 00162 /* Clear DLY_INT_A and DLY_INT_B */ 00163 writel(0x0, mmio + DLY_INT_A); 00164 writel(0x0, mmio + DLY_INT_B); 00165 00166 /* Clear FLOW_CONTROL */ 00167 writel(0x0, mmio + FLOW_CONTROL); 00168 00169 /* Clear INT0 write 1 to clear register */ 00170 reg_val = readl(mmio + INT0); 00171 writel(reg_val, mmio + INT0); 00172 00173 /* Clear STVAL */ 00174 writel(0x0, mmio + STVAL); 00175 00176 /* Clear INTEN0 */ 00177 writel(INTEN0_CLEAR, mmio + INTEN0); 00178 00179 /* Clear LADRF */ 00180 writel(0x0, mmio + LADRF); 00181 00182 /* Set SRAM_SIZE & SRAM_BOUNDARY registers */ 00183 writel(0x80010, mmio + SRAM_SIZE); 00184 00185 /* Clear RCV_RING0_LEN */ 00186 writel(0x0, mmio + RCV_RING_LEN0); 00187 00188 /* Clear XMT_RING0/1/2/3_LEN */ 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 /* Clear XMT_RING_LIMIT */ 00195 writel(0x0, mmio + XMT_RING_LIMIT); 00196 00197 /* Clear MIB */ 00198 writew(MIB_CLEAR, mmio + MIB_ADDR); 00199 00200 /* Clear LARF */ 00201 writel( 0, mmio + LADRF); 00202 writel( 0, mmio + LADRF + 4); 00203 00204 /* SRAM_SIZE register */ 00205 reg_val = readl(mmio + SRAM_SIZE); 00206 00207 /* Set default value to CTRL1 Register */ 00208 writel(CTRL1_DEFAULT, mmio + CTRL1); 00209 00210 /* To avoid PCI posting bug */ 00211 readl(mmio + CMD2); 00212 }
| static int amd8111e_start | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 217 of file amd8111e.c.
References amd8111e_init_rx_ring(), amd8111e_init_tx_ring(), APAD_XMT, AUTOPOLL0, CACHE_ALIGN, CMD0, CMD2, CMD3, CTRL1, CTRL2, DEFAULT_IPG, EN_PMGR, ETH_ALEN, amd8111e_priv::ext_phy_addr, IFS1, IFS1_DELTA, IPG, JUMBO, amd8111e_priv::mmio, amd8111e_priv::nic, nic::node_addr, NUM_RX_SLOTS, NUM_TX_SLOTS, PADR, RCV_RING_BASE_ADDR0, RCV_RING_LEN0, RDMD0, readl, REX_RTRY, REX_UFLO, RUN, amd8111e_priv::rx_ring, amd8111e_priv::tx_ring, VAL0, VAL1, VAL2, virt_to_bus(), writeb, writel, writew, XMT_RING_BASE_ADDR0, XMT_RING_LEN0, XMTSP_128, XMTSP_MASK, XPHYANE, and XPHYRST.
Referenced by amd8111e_restart().
00218 { 00219 struct nic *nic = lp->nic; 00220 void *mmio = lp->mmio; 00221 int i, reg_val; 00222 00223 /* stop the chip */ 00224 writel(RUN, mmio + CMD0); 00225 00226 /* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */ 00227 writew(0x8100 | lp->ext_phy_addr, mmio + AUTOPOLL0); 00228 00229 /* enable the port manager and set auto negotiation always */ 00230 writel(VAL1 | EN_PMGR, mmio + CMD3 ); 00231 writel(XPHYANE | XPHYRST, mmio + CTRL2); 00232 00233 /* set control registers */ 00234 reg_val = readl(mmio + CTRL1); 00235 reg_val &= ~XMTSP_MASK; 00236 writel(reg_val | XMTSP_128 | CACHE_ALIGN, mmio + CTRL1); 00237 00238 /* initialize tx and rx ring base addresses */ 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 /* set default IPG to 96 */ 00247 writew(DEFAULT_IPG, mmio + IPG); 00248 writew(DEFAULT_IPG - IFS1_DELTA, mmio + IFS1); 00249 00250 /* AutoPAD transmit, Retransmit on Underflow */ 00251 writel(VAL0 | APAD_XMT | REX_RTRY | REX_UFLO, mmio + CMD2); 00252 00253 /* JUMBO disabled */ 00254 writel(JUMBO, mmio + CMD3); 00255 00256 /* Setting the MAC address to the device */ 00257 for(i = 0; i < ETH_ALEN; i++) 00258 writeb(nic->node_addr[i], mmio + PADR + i); 00259 00260 /* set RUN bit to start the chip, interrupt not enabled */ 00261 writel(VAL2 | RDMD0 | VAL0 | RUN, mmio + CMD0); 00262 00263 /* To avoid PCI posting bug */ 00264 readl(mmio + CMD0); 00265 return 0; 00266 }
| static int amd8111e_read_phy | ( | struct amd8111e_priv * | lp, | |
| int | phy_addr, | |||
| int | reg, | |||
| u32 * | val | |||
| ) | [static] |
Definition at line 271 of file amd8111e.c.
References amd8111e_priv::mmio, PHY_ACCESS, PHY_CMD_ACTIVE, PHY_RD_CMD, PHY_RD_ERR, PHY_RW_RETRY, readl, udelay(), and writel.
Referenced by amd8111e_poll_link(), amd8111e_probe_ext_phy(), and amd8111e_wait_link().
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); /* It takes 30 us to read/write data */ 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 }
| static void amd8111e_probe_ext_phy | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 325 of file amd8111e.c.
References amd8111e_read_phy(), amd8111e_priv::ext_phy_addr, amd8111e_priv::ext_phy_id, MII_PHYSID1, MII_PHYSID2, printf(), and u32.
Referenced by amd8111e_restart().
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 }
| static void amd8111e_disable_interrupt | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 351 of file amd8111e.c.
References CMD0, INT0, INTEN0, INTEN0_CLEAR, INTREN, amd8111e_priv::mmio, readl, and writel.
Referenced by amd8111e_disable(), amd8111e_irq(), and amd8111e_restart().
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 }
| static void amd8111e_enable_interrupt | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 363 of file amd8111e.c.
References CMD0, INTEN0, INTREN, LCINTEN, amd8111e_priv::mmio, readl, RINTEN0, TINTEN0, VAL0, VAL1, VAL3, and writel.
Referenced by amd8111e_irq().
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 }
| static void amd8111e_force_interrupt | ( | struct amd8111e_priv * | lp | ) | [static] |
| static int amd8111e_get_mac_address | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 380 of file amd8111e.c.
References DBG, ETH_ALEN, eth_ntoa(), amd8111e_priv::mmio, amd8111e_priv::nic, nic::node_addr, PADR, and readb.
Referenced by amd8111e_restart().
00381 { 00382 struct nic *nic = lp->nic; 00383 void *mmio = lp->mmio; 00384 int i; 00385 00386 /* BIOS should have set mac address to PADR register, 00387 * so we read PADR to get it. 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 }
| static int amd8111e_init_rx_ring | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 397 of file amd8111e.c.
References amd8111e_rx_desc::buf_len, amd8111e_rx_desc::buf_phy_addr, cpu_to_le16, cpu_to_le32, NUM_RX_SLOTS, OWN_BIT, amd8111e_priv::rx_buf, RX_BUF_LEN, amd8111e_rx_desc::rx_flags, amd8111e_priv::rx_idx, amd8111e_priv::rx_ring, virt_to_bus(), and wmb.
Referenced by amd8111e_start().
00398 { 00399 int i; 00400 00401 lp->rx_idx = 0; 00402 00403 /* Initilaizing receive descriptors */ 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 }
| static int amd8111e_init_tx_ring | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 414 of file amd8111e.c.
References amd8111e_tx_desc::buf_len, amd8111e_tx_desc::buf_phy_addr, NUM_TX_SLOTS, amd8111e_priv::tx_consistent, amd8111e_tx_desc::tx_flags, amd8111e_priv::tx_idx, and amd8111e_priv::tx_ring.
Referenced by amd8111e_start().
00415 { 00416 int i; 00417 00418 lp->tx_idx = 0; 00419 lp->tx_consistent = 1; 00420 00421 /* Initializing transmit descriptors */ 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 }
| static int amd8111e_wait_tx_ring | ( | struct amd8111e_priv * | lp, | |
| unsigned int | index | |||
| ) | [static] |
Definition at line 431 of file amd8111e.c.
References amd8111e_restart(), le16_to_cpu, mdelay(), OWN_BIT, printf(), amd8111e_tx_desc::tx_flags, TX_PROCESS_TIME, TX_RETRY, amd8111e_priv::tx_ring, and u16.
Referenced by amd8111e_transmit().
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 }
| static void amd8111e_wait_link | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 450 of file amd8111e.c.
References amd8111e_read_phy(), AUTONEG_COMPLETE, amd8111e_priv::ext_phy_addr, LINK_STATS, MII_ADVERTISE, MII_BMCR, MII_BMSR, MII_LPA, amd8111e_priv::mmio, readl, STAT0, and u32.
Referenced by amd8111e_restart().
00451 { 00452 unsigned int status; 00453 u32 reg_val; 00454 00455 do { 00456 /* read phy to update STAT0 register */ 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 }
| static void amd8111e_poll_link | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 465 of file amd8111e.c.
References amd8111e_read_phy(), amd8111e_priv::duplex, amd8111e_priv::ext_phy_addr, FULL_DPLX, amd8111e_priv::link, LINK_STATS, MII_ADVERTISE, MII_BMCR, MII_BMSR, MII_LPA, amd8111e_priv::mmio, PHY_SPEED_100, printf(), readl, amd8111e_priv::speed, SPEED_MASK, STAT0, and u32.
Referenced by amd8111e_poll(), and amd8111e_restart().
00466 { 00467 unsigned int status, speed; 00468 u32 reg_val; 00469 00470 if (!lp->link) { 00471 /* read phy to update STAT0 register */ 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 }
| static void amd8111e_restart | ( | struct amd8111e_priv * | lp | ) | [static] |
Definition at line 502 of file amd8111e.c.
References amd8111e_disable_interrupt(), amd8111e_get_mac_address(), amd8111e_init_hw_default(), amd8111e_poll_link(), amd8111e_probe_ext_phy(), amd8111e_start(), amd8111e_wait_link(), amd8111e_priv::link, and printf().
Referenced by amd8111e_probe(), and amd8111e_wait_tx_ring().
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 }
| static void amd8111e_transmit | ( | struct nic * | nic, | |
| const char * | dst_addr, | |||
| unsigned int | type, | |||
| unsigned int | size, | |||
| const char * | packet | |||
| ) | [static] |
Definition at line 522 of file amd8111e.c.
References ADD_FCS_BIT, amd8111e_wait_tx_ring(), amd8111e_tx_desc::buf_len, amd8111e_tx_desc::buf_phy_addr, CMD0, cpu_to_le16, cpu_to_le32, eth_frame::data, eth_frame::dst_addr, ENP_BIT, ETH_ALEN, ETH_HLEN, htons, index, LTINT_BIT, memcpy, memset(), amd8111e_priv::mmio, nic::node_addr, OWN_BIT, printf(), nic::priv_data, readl, eth_frame::src_addr, STP_BIT, TDMD0, amd8111e_priv::tx_buf, amd8111e_tx_desc::tx_flags, amd8111e_priv::tx_idx, TX_PKT_LEN_MAX, amd8111e_priv::tx_ring, TX_SLOTS_MASK, eth_frame::type, VAL1, virt_to_bus(), wmb, and writel.
00524 { 00525 struct amd8111e_priv *lp = nic->priv_data; 00526 struct eth_frame *frame; 00527 unsigned int index; 00528 00529 /* check packet size */ 00530 if (size > TX_PKT_LEN_MAX) { 00531 printf("amd8111e_transmit(): too large packet, drop\n"); 00532 return; 00533 } 00534 00535 /* get tx slot */ 00536 index = lp->tx_idx; 00537 if (amd8111e_wait_tx_ring(lp, index)) 00538 return; 00539 00540 /* fill frame */ 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 /* start xmit */ 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 /* update slot pointer */ 00558 lp->tx_idx = (lp->tx_idx + 1) & TX_SLOTS_MASK; 00559 }
| static int amd8111e_poll | ( | struct nic * | nic, | |
| int | retrieve | |||
| ) | [static] |
Definition at line 561 of file amd8111e.c.
References amd8111e_poll_link(), amd8111e_rx_desc::buf_len, amd8111e_rx_desc::buf_phy_addr, CMD0, cpu_to_le16, cpu_to_le32, ENP_BIT, ERR_BIT, index, le16_to_cpu, memcpy, amd8111e_priv::mmio, amd8111e_rx_desc::msg_len, OWN_BIT, nic::packet, nic::packetlen, nic::priv_data, RDMD0, readl, amd8111e_priv::rx_buf, RX_BUF_LEN, amd8111e_rx_desc::rx_flags, amd8111e_priv::rx_idx, RX_PKT_LEN_MAX, RX_PKT_LEN_MIN, amd8111e_priv::rx_ring, RX_SLOTS_MASK, STP_BIT, u16, VAL2, virt_to_bus(), wmb, and writel.
00562 { 00563 /* return true if there's an ethernet packet ready to read */ 00564 /* nic->packet should contain data on return */ 00565 /* nic->packetlen should contain length of data */ 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; /* remove 4bytes FCS */ 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 }
| static void amd8111e_disable | ( | struct nic * | nic | ) | [static] |
Definition at line 611 of file amd8111e.c.
References amd8111e_disable_interrupt(), amd8111e_init_hw_default(), iounmap(), amd8111e_priv::mmio, amd8111e_priv::opened, and nic::priv_data.
00612 { 00613 struct amd8111e_priv *lp = nic->priv_data; 00614 00615 /* disable interrupt */ 00616 amd8111e_disable_interrupt(lp); 00617 00618 /* stop chip */ 00619 amd8111e_init_hw_default(lp); 00620 00621 /* unmap mmio */ 00622 iounmap(lp->mmio); 00623 00624 /* update status */ 00625 lp->opened = 0; 00626 }
| static void amd8111e_irq | ( | struct nic * | nic, | |
| irq_action_t | action | |||
| ) | [static] |
Definition at line 628 of file amd8111e.c.
References amd8111e_disable_interrupt(), amd8111e_enable_interrupt(), amd8111e_force_interrupt(), DISABLE, ENABLE, FORCE, and nic::priv_data.
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 }
| static int amd8111e_probe | ( | struct nic * | nic, | |
| struct pci_device * | pdev | |||
| ) | [static] |
Definition at line 652 of file amd8111e.c.
References adjust_pci_device(), amd8111e, amd8111e_restart(), pci_device::ioaddr, nic::ioaddr, ioremap(), pci_device::irq, nic::irqno, memset(), amd8111e_priv::mmio, amd8111e_priv::nic, nic::nic_op, amd8111e_priv::opened, pci_bar_size(), pci_bar_start(), PCI_BASE_ADDRESS_0, amd8111e_priv::pdev, and nic::priv_data.
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 }
| PCI_DRIVER | ( | amd8111e_driver | , | |
| amd8111e_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "AMD8111E" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| amd8111e_driver | , | |||
| amd8111e_probe | , | |||
| amd8111e_disable | ||||
| ) |
struct amd8111e_priv amd8111e [static] |
struct nic_operations amd8111e_operations [static] |
Initial value:
{
.connect = dummy_connect,
.poll = amd8111e_poll,
.transmit = amd8111e_transmit,
.irq = amd8111e_irq,
}
Definition at line 645 of file amd8111e.c.
struct pci_device_id amd8111e_nics[] [static] |
Initial value:
{
PCI_ROM(0x1022, 0x7462, "amd8111e", "AMD8111E", 0),
}
Definition at line 678 of file amd8111e.c.
1.5.7.1