Warning, cross-references for /kernel/drivers/net/e1000.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "drivers/pci/pci.h"
0021 #include "drivers/net/ethernet.h"
0022 #include "arch/i386.h"
0023 #include "arch/i386-percpu.h"
0024 #include "util/printf.h"
0025 #include "smp/smp.h"
0026 #include "smp/apic.h"
0027 #include "mem/physical.h"
0028 #include "mem/virtual.h"
0029 #include "kernel.h"
0030 #include "sched/vcpu.h"
0031
0032 #define EEPROM_MICROWIRE
0033
0034
0035
0036 typedef struct {
0037 uint16 word_size, delay_usec, address_bits, opcode_bits;
0038 bool need_acquire;
0039 } nvm_info_t;
0040
0041 nvm_info_t i82543_nvm = {
0042 .word_size = 64, .delay_usec = 50, .address_bits = 6, .opcode_bits = 3,
0043 .need_acquire = FALSE
0044 };
0045
0046 nvm_info_t *nvm = &i82543_nvm;
0047
0048 #ifdef DEBUG_E1000
0049 #define DLOG(fmt,...) DLOG_PREFIX("e1000",fmt,##__VA_ARGS__)
0050 #else
0051 #define DLOG(fmt,...) ;
0052 #endif
0053
0054 #define RDESC_COUNT 8
0055 #define RDESC_COUNT_MOD_MASK (RDESC_COUNT - 1)
0056 #define RBUF_SIZE 2048
0057 #define RBUF_SIZE_MASK 0
0058
0059 #define TDESC_COUNT 8
0060 #define TDESC_COUNT_MOD_MASK (RDESC_COUNT - 1)
0061 #define TBUF_SIZE 2048
0062 #define TBUF_SIZE_MASK 0
0063 #define TCTL_CT_MASK 0x100
0064 #define TCTL_COLD_MASK 0x40000
0065 #define TIPG_MASK (10 | (10 << 10) | (10 << 20))
0066
0067
0068 static struct { uint16 vendor, device; } compatible_ids[] = {
0069 { 0x8086, 0x1004 },
0070 { 0x8086, 0x1008 },
0071 { 0x8086, 0x100E },
0072 { 0xFFFF, 0xFFFF }
0073 };
0074
0075 static uint8 hwaddr[ETH_ADDR_LEN];
0076 static uint device_index, mem_addr, irq_line, irq_pin, e1000_phys;
0077 static volatile uint32 *mmio_base;
0078 #define E1000_MMIO_PAGES 0x10
0079
0080
0081
0082
0083
0084 #define REG(x) (mmio_base[x])
0085
0086 #define CTRL (REG (0x00))
0087 #define CTRL_FD (0x1)
0088 #define CTRL_LRST (0x8)
0089 #define CTRL_ASDE (0x20)
0090 #define CTRL_SLU (0x40)
0091 #define CTRL_ILOS (0x80)
0092 #define CTRL_SPDSEL (0x300)
0093 #define CTRL_SPD1000 (0x200)
0094 #define CTRL_FRCSPD (0x800)
0095 #define CTRL_FRCDPLX (0x1000)
0096 #define CTRL_RST (1<<26)
0097 #define CTRL_RFCE (1<<27)
0098 #define CTRL_TFCE (1<<28)
0099 #define CTRL_PHYRST (1<<31)
0100 #define STATUS (REG (0x02))
0101 #define STATUS_FD (0x1)
0102 #define EECD (REG (0x04))
0103 #define EECD_SK (0x1)
0104 #define EECD_CS (0x2)
0105 #define EECD_DI (0x4)
0106 #define EECD_DO (0x8)
0107 #define EECD_REQ (0x40)
0108 #define EECD_GNT (0x80)
0109 #define EERD (REG (0x05))
0110 #define CTRLEXT (REG (0x06))
0111 #define CTRLEXT_EERST (1<<13)
0112 #define MDIC (REG (0x08))
0113 #define ICR (REG (0x30))
0114 #define ICR_RXT (0x80)
0115 #define ICR_RXO (0x40)
0116 #define ICR_TXQE (0x02)
0117 #define IMS (REG (0x34))
0118 #define IMS_RXT (0x80)
0119 #define IMS_RXO (0x40)
0120 #define IMS_TXQE (0x02)
0121 #define RCTL (REG (0x40))
0122 #define RCTL_EN (0x02)
0123 #define RCTL_BAM (1<<15)
0124 #define RCTL_BSIZE (0x30000)
0125 #define RCTL_BSEX (1<<25)
0126 #define TXCW (REG (0x5E))
0127 #define TXCW_ANE (1<<31)
0128 #define TCTL (REG (0x100))
0129 #define TCTL_EN (0x02)
0130 #define TCTL_PSP (0x08)
0131 #define TCTL_CT (0xFF0)
0132 #define TCTL_COLD (0x3FF000)
0133 #define TIPG (REG (0x104))
0134 #define RDBAL (REG (0xA00))
0135 #define RDBAH (REG (0xA01))
0136 #define RDLEN (REG (0xA02))
0137 #define RDH (REG (0xA04))
0138 #define RDT (REG (0xA06))
0139 #define TDBAL (REG (0xE00))
0140 #define TDBAH (REG (0xE01))
0141 #define TDLEN (REG (0xE02))
0142 #define TDH (REG (0xE04))
0143 #define TDT (REG (0xE06))
0144 #define RAL (REG (0x1500))
0145 #define RAH (REG (0x1501))
0146 #define TPT (REG (0x1035))
0147
0148 #define WRITE_FLUSH (void) STATUS
0149
0150
0151
0152
0153 struct e1000_rdesc {
0154 uint64 address;
0155 uint16 length;
0156 uint16 checksum;
0157 uint8 status;
0158 uint8 errors;
0159 uint16 special;
0160 } PACKED;
0161 #define RDESC_STATUS_DD 0x01
0162 #define RDESC_STATUS_EOP 0x02
0163
0164
0165
0166
0167 struct e1000_tdesc {
0168 uint64 address;
0169 uint16 length;
0170 uint8 cso;
0171 uint8 cmd;
0172 uint8 sta:4;
0173 uint8 rsv:4;
0174 uint8 css;
0175 uint16 special;
0176 } PACKED;
0177 #define TDESC_STA_DD 0x01
0178 #define TDESC_CMD_EOP 0x01
0179 #define TDESC_CMD_IFCS 0x02
0180 #define TDESC_CMD_RS 0x08
0181
0182
0183
0184 static struct e1000_interface {
0185 struct e1000_rdesc rdescs[RDESC_COUNT] ALIGNED(0x10);
0186 struct e1000_tdesc tdescs[TDESC_COUNT] ALIGNED(0x10);
0187 uint8 rbufs[RDESC_COUNT][RBUF_SIZE];
0188 uint8 tbufs[TDESC_COUNT][TBUF_SIZE];
0189 uint rx_idx;
0190 uint tx_cnt;
0191 } *e1000;
0192
0193
0194 #define V2P(ty,p) ((ty)((((uint) (p)) - ((uint) e1000))+e1000_phys))
0195
0196 #define P2V(ty,p) ((ty)((((uint) (p)) - e1000_phys)+((uint) e1000)))
0197
0198 static ethernet_device e1000_ethdev;
0199 static pci_device e1000_pci_device;
0200
0201
0202
0203 extern bool
0204 e1000_get_hwaddr (uint8 a[ETH_ADDR_LEN])
0205 {
0206 int i;
0207 for (i=0; i<ETH_ADDR_LEN; i++)
0208 a[i] = hwaddr[i];
0209 return TRUE;
0210 }
0211
0212 extern sint
0213 e1000_transmit (uint8* buffer, sint len)
0214 {
0215 struct e1000_tdesc *td;
0216 uint32 tdt = TDT;
0217 DLOG ("TX: (%p, %d) TDH=%d TDT=%d", buffer, len, TDH, tdt);
0218 DLOG ("TX: %.02X %.02X %.02X %.02X %.02X %.02X %.02X %.02X",
0219 buffer[0], buffer[1], buffer[2], buffer[3],
0220 buffer[4], buffer[5], buffer[6], buffer[7]);
0221 DLOG ("TX: %.02X %.02X %.02X %.02X %.02X %.02X %.02X %.02X",
0222 buffer[8], buffer[9], buffer[10], buffer[11],
0223 buffer[12], buffer[13], buffer[14], buffer[15]);
0224
0225 if (len > TBUF_SIZE)
0226 return 0;
0227
0228 if (e1000->tx_cnt >= TDESC_COUNT - 1)
0229 return 0;
0230
0231
0232 memcpy (e1000->tbufs[tdt], buffer, len);
0233 e1000->tdescs[tdt].length = len;
0234 e1000->tdescs[tdt].cmd = TDESC_CMD_IFCS | TDESC_CMD_RS | TDESC_CMD_EOP;
0235 td = &e1000->tdescs[tdt];
0236
0237
0238 tdt++;
0239 if (tdt >= TDESC_COUNT)
0240 tdt = 0;
0241 TDT = tdt;
0242
0243 e1000->tx_cnt++;
0244
0245 return len;
0246 }
0247
0248 u32 e1000_packet_count = 0;
0249 u64 e1000_packet_bytes = 0;
0250
0251 extern void
0252 e1000_rx_poll (void)
0253 {
0254 uint32 entry, rdt;
0255 uint8 *ptr;
0256
0257 DLOG ("RX: %d %d %d %d %d %d %d %d",
0258 e1000->rdescs[0].status & RDESC_STATUS_DD,
0259 e1000->rdescs[1].status & RDESC_STATUS_DD,
0260 e1000->rdescs[2].status & RDESC_STATUS_DD,
0261 e1000->rdescs[3].status & RDESC_STATUS_DD,
0262 e1000->rdescs[4].status & RDESC_STATUS_DD,
0263 e1000->rdescs[5].status & RDESC_STATUS_DD,
0264 e1000->rdescs[6].status & RDESC_STATUS_DD,
0265 e1000->rdescs[7].status & RDESC_STATUS_DD);
0266
0267 entry = e1000->rx_idx & RDESC_COUNT_MOD_MASK;
0268 while (e1000->rdescs[entry].status & RDESC_STATUS_DD) {
0269 if (e1000->rdescs[entry].status & RDESC_STATUS_EOP) {
0270 uint16 len;
0271
0272 ptr = e1000->rbufs[entry];
0273 len = e1000->rdescs[entry].length;
0274 DLOG ("RX: full packet@%p len=%d", ptr, len);
0275 e1000_packet_count++;
0276 e1000_packet_bytes += len;
0277 if (e1000_ethdev.recv_func)
0278 e1000_ethdev.recv_func (&e1000_ethdev, ptr, len);
0279 else
0280 DLOG ("recv_func is null");
0281 } else {
0282
0283 DLOG ("RX: error. status=%p", e1000->rdescs[entry].status);
0284 }
0285
0286
0287 e1000->rdescs[entry].status = 0;
0288
0289
0290 rdt = RDT;
0291 rdt++;
0292 if (rdt >= RDESC_COUNT)
0293 rdt = 0;
0294 RDT = rdt;
0295
0296
0297 entry = (++e1000->rx_idx) & RDESC_COUNT_MOD_MASK;
0298 }
0299 }
0300
0301 static void
0302 handle_tx (uint32 icr)
0303 {
0304 uint i;
0305 DLOG ("TX: tx_cnt=%d", e1000->tx_cnt);
0306
0307
0308 for (i=0; i<TDESC_COUNT; i++) {
0309 if (e1000->tdescs[i].cmd && (e1000->tdescs[i].sta & TDESC_STA_DD)) {
0310 e1000->tdescs[i].cmd = 0;
0311 e1000->tdescs[i].sta = 0;
0312 e1000->tx_cnt--;
0313 }
0314 }
0315 }
0316
0317 extern void
0318 e1000_poll (void)
0319 {
0320 e1000_rx_poll ();
0321 handle_tx (ICR_TXQE);
0322 }
0323
0324 #ifdef E1000_DEBUG
0325 static uint16
0326 mdi_read (uint8 phy_reg)
0327 {
0328 uint32 mdic =
0329 ((phy_reg & 0x1F) << 16) |
0330 (1 << 21) |
0331 (1 << 27);
0332 DLOG ("mdi_read sending %p", mdic);
0333 MDIC = mdic;
0334 while (!((mdic=MDIC) & 0x50000000LL))
0335 asm volatile ("pause");
0336 DLOG ("mdi_read MDIC=%p", mdic);
0337 if (mdic & 0x40000000LL)
0338
0339 return 0;
0340 else
0341 return mdic & 0xFFFF;
0342 }
0343
0344 static bool
0345 mdi_write (uint8 phy_reg, uint16 val)
0346 {
0347 uint32 mdic =
0348 ((phy_reg & 0x1F) << 16) |
0349 (1 << 21) |
0350 (1 << 26) |
0351 (val & 0xFFFF);
0352 DLOG ("mdi_write sending %p", mdic);
0353 MDIC = mdic;
0354 while (!((mdic=MDIC) & 0x50000000LL))
0355 asm volatile ("pause");
0356 DLOG ("mdi_write MDIC=%p", mdic);
0357 if (mdic & 0x40000000LL)
0358
0359 return FALSE;
0360 else
0361 return TRUE;
0362 }
0363 #endif
0364
0365 static uint32 e1000_bh_stack[1024] ALIGNED (0x1000);
0366 static task_id e1000_bh_id = 0;
0367 static void
0368 e1000_bh_thread (void)
0369 {
0370 for (;;) {
0371
0372
0373 uint32 icr = ICR;
0374 DLOG ("IRQ: ICR=%p CTRL=%p CTRLE=%p STA=%p", icr, CTRL, CTRLEXT, STATUS);
0375
0376
0377
0378
0379 DLOG ("TPT=%p", TPT);
0380
0381 if (icr & ICR_RXT)
0382 e1000_rx_poll ();
0383 if (icr & ICR_TXQE)
0384 handle_tx (icr);
0385
0386 #if 0
0387 unlock_kernel ();
0388 sti ();
0389 tsc_delay_usec (3000);
0390 cli ();
0391 lock_kernel ();
0392 #endif
0393
0394 iovcpu_job_completion ();
0395 }
0396 }
0397
0398 extern DEF_PER_CPU (vcpu *, vcpu_current);
0399 static uint32
0400 e1000_irq_handler (uint8 vec)
0401 {
0402 if (e1000_bh_id) {
0403 extern vcpu *vcpu_lookup (int);
0404
0405 iovcpu_job_wakeup (e1000_bh_id, vcpu_lookup (2)->T);
0406 }
0407
0408 return 0;
0409 }
0410
0411 #define udelay tsc_delay_usec
0412
0413 static bool
0414 eeprom_acquire (void)
0415 {
0416 uint32 eecd = EECD;
0417 uint32 timeout = 1000;
0418
0419 DLOG ("eeprom_acquire EECD=%p", eecd);
0420 EECD = eecd | EECD_REQ;
0421 for (; timeout > 0; timeout--) {
0422 eecd = EECD;
0423 if (eecd & EECD_GNT)
0424 break;
0425 udelay (5);
0426 }
0427
0428 if (timeout == 0) {
0429 DLOG ("unable to acquire EEPROM");
0430 eecd &= ~EECD_REQ;
0431 EECD = eecd;
0432 return FALSE;
0433 }
0434 return TRUE;
0435 }
0436
0437 static void
0438 eeprom_release (void)
0439 {
0440 uint32 eecd = EECD;
0441
0442 eecd &= ~EECD_REQ;
0443 EECD = eecd;
0444 }
0445
0446 static void
0447 eeprom_raise_clock (uint32 *eecd)
0448 {
0449 *eecd = *eecd | EECD_SK;
0450 EECD = *eecd;
0451 WRITE_FLUSH;
0452 udelay(nvm->delay_usec);
0453 }
0454
0455 static void
0456 eeprom_lower_clock (uint32 *eecd)
0457 {
0458 *eecd = *eecd & ~EECD_SK;
0459 EECD = *eecd;
0460 WRITE_FLUSH;
0461 udelay(nvm->delay_usec);
0462 }
0463
0464 static void
0465 eeprom_send_bits (uint16 data, uint16 count)
0466 {
0467 uint32 eecd = EECD, mask;
0468
0469 mask = 1 << (count - 1);
0470
0471
0472 eecd &= ~EECD_DO;
0473
0474 do {
0475
0476 if (data & mask)
0477 eecd |= EECD_DI;
0478 else
0479 eecd &= ~EECD_DI;
0480
0481
0482 EECD = eecd;
0483 WRITE_FLUSH;
0484
0485 udelay (nvm->delay_usec);
0486
0487 eeprom_raise_clock (&eecd);
0488 eeprom_lower_clock (&eecd);
0489
0490 mask >>= 1;
0491 } while (mask);
0492
0493 eecd &= ~EECD_DI;
0494 EECD = eecd;
0495 }
0496
0497 static uint16
0498 eeprom_recv_bits (uint16 count)
0499 {
0500 uint32 eecd, i;
0501 uint16 data;
0502
0503 eecd = EECD;
0504 eecd &= ~(EECD_DO | EECD_DI);
0505 data = 0;
0506
0507 for (i=0; i<count; i++) {
0508 data <<= 1;
0509 eeprom_raise_clock (&eecd);
0510 eecd = EECD;
0511
0512 eecd &= ~EECD_DI;
0513
0514 if (eecd & EECD_DO)
0515 data |= 1;
0516
0517 eeprom_lower_clock (&eecd);
0518 }
0519
0520 return data;
0521 }
0522
0523 static void
0524 eeprom_standby (void)
0525 {
0526 uint32 eecd = EECD;
0527
0528 eecd &= ~(EECD_CS | EECD_SK);
0529 EECD = eecd;
0530 WRITE_FLUSH;
0531 udelay (nvm->delay_usec);
0532
0533 eeprom_raise_clock (&eecd);
0534
0535 eecd |= EECD_CS;
0536 EECD = eecd;
0537 WRITE_FLUSH;
0538 udelay (nvm->delay_usec);
0539
0540 eeprom_lower_clock (&eecd);
0541 }
0542
0543 static uint16
0544 eeprom_read (uint32 address)
0545 {
0546 uint32 eecd;
0547 uint16 data;
0548
0549
0550 if (nvm->need_acquire && !eeprom_acquire ())
0551 return 0;
0552
0553 eecd = EECD;
0554
0555 DLOG ("eeprom_read EECD=%p", eecd);
0556
0557
0558
0559
0560 eecd &= ~(EECD_DI | EECD_SK);
0561 EECD = eecd;
0562 udelay (1);
0563
0564 eecd |= EECD_CS;
0565 EECD = eecd;
0566 udelay (1);
0567
0568
0569
0570 #define NVM_READ_OPCODE 6
0571 eeprom_send_bits (NVM_READ_OPCODE, nvm->opcode_bits);
0572 eeprom_send_bits (address, nvm->address_bits);
0573
0574 data = eeprom_recv_bits (16);
0575
0576 DLOG ("eeprom said 0x%.04X", data);
0577
0578 eeprom_standby ();
0579
0580
0581
0582 if (nvm->need_acquire)
0583 eeprom_release ();
0584
0585 return data;
0586 }
0587
0588 #ifdef LOOPBACK_MODE
0589 static void
0590 set_loopback_mode (void)
0591 {
0592 uint32 ctrl;
0593
0594 mdi_write (16, 0x0808);
0595 mdi_write (0, 0x9140);
0596 mdi_write (0, 0x8140);
0597 mdi_write (0, 0x4140);
0598 ctrl = CTRL;
0599 ctrl &= ~CTRL_SPDSEL;
0600 ctrl |= CTRL_FRCSPD | CTRL_FRCDPLX | CTRL_SPD1000 | CTRL_FD;
0601 if (!(STATUS & STATUS_FD))
0602 ctrl |= CTRL_ILOS | CTRL_SLU;
0603 CTRL = ctrl;
0604 }
0605 #endif
0606
0607 static void
0608 reset (void)
0609 {
0610 uint i;
0611
0612 #if 0
0613
0614 DLOG ("PHY PCTRL=0x%.4X", mdi_read (0));
0615 mdi_write (0, 0x9200);
0616 tsc_delay_usec (1000);
0617 DLOG ("PHY PCTRL=0x%.4X", mdi_read (0));
0618 #else
0619
0620 CTRL |= CTRL_PHYRST;
0621 udelay (3);
0622 CTRL &= ~CTRL_PHYRST;
0623 #endif
0624
0625 udelay (5000);
0626
0627
0628 CTRL |= CTRL_RST;
0629 while (CTRL & CTRL_RST) tsc_delay_usec (1);
0630
0631
0632 CTRLEXT |= CTRLEXT_EERST;
0633 WRITE_FLUSH;
0634 udelay (2000);
0635
0636
0637 RAL =
0638 (hwaddr[0] << 0x00) |
0639 (hwaddr[1] << 0x08) |
0640 (hwaddr[2] << 0x10) |
0641 (hwaddr[3] << 0x18);
0642 RAH = 0x80000000L |
0643 (hwaddr[4] << 0x00) |
0644 (hwaddr[5] << 0x08);
0645
0646 DLOG ("RAL=%p RAH=%p", RAL, RAH);
0647
0648
0649 RCTL &= ~RCTL_BSIZE;
0650 RCTL |= RBUF_SIZE_MASK;
0651 RCTL &= ~RCTL_BSEX;
0652
0653
0654 for (i=0; i<RDESC_COUNT; i++) {
0655 e1000->rdescs[i].address = V2P (uint64, e1000->rbufs[i]);
0656 e1000->rdescs[i].status = 0;
0657 }
0658
0659
0660 RDBAL = V2P (uint32, e1000->rdescs);
0661 RDBAH = 0;
0662 RDLEN = RDESC_COUNT * sizeof (struct e1000_rdesc);
0663
0664
0665 RDH = 0;
0666 RDT = RDESC_COUNT - 1;
0667
0668 e1000->rx_idx = 0;
0669
0670 DLOG ("RDBAL=%p RDLEN=%p RDH=%d RDT=%d",
0671 V2P (uint32, e1000->rdescs), RDESC_COUNT * sizeof (struct e1000_rdesc),
0672 RDH, RDT);
0673
0674
0675 for (i=0; i<TDESC_COUNT; i++) {
0676 e1000->tdescs[i].address = V2P (uint64, e1000->tbufs[i]);
0677 e1000->tdescs[i].sta = 0;
0678 }
0679
0680
0681 TDBAL = V2P (uint32, e1000->tdescs);
0682 TDBAH = 0;
0683 TDLEN = TDESC_COUNT * sizeof (struct e1000_tdesc);
0684
0685
0686 TDH = 0;
0687 TDT = 0;
0688
0689 e1000->tx_cnt = 0;
0690
0691 DLOG ("TDBAL=%p TDLEN=%p TDH=%d TDT=%d",
0692 V2P (uint32, e1000->tdescs), TDESC_COUNT * sizeof (struct e1000_tdesc),
0693 TDH, TDT);
0694
0695
0696 IMS |= IMS_RXT;
0697
0698
0699 IMS |= IMS_TXQE;
0700
0701
0702 RCTL |= (RCTL_EN | RCTL_BAM);
0703
0704
0705 TCTL |= (TCTL_EN | TCTL_PSP | TCTL_COLD_MASK);
0706 TIPG = TIPG_MASK;
0707
0708 while (! (TCTL & TCTL_EN)) asm volatile ("pause");
0709
0710 #ifndef LOOPBACK_MODE
0711
0712 CTRL &= ~CTRL_LRST;
0713
0714 tsc_delay_usec (10000);
0715
0716
0717
0718
0719
0720 CTRL |= CTRL_SLU | CTRL_ASDE;
0721 #else
0722 set_loopback_mode ();
0723 #endif
0724
0725
0726
0727
0728
0729
0730
0731
0732 (void) TPT;
0733 }
0734
0735 extern bool
0736 e1000_init (void)
0737 {
0738 uint i, frame_count;
0739 pci_irq_t irq;
0740
0741 if (mp_ISA_PC) {
0742 DLOG ("Requires PCI support");
0743 goto abort;
0744 }
0745
0746 for (i=0; compatible_ids[i].vendor != 0xFFFF; i++)
0747 if (pci_find_device (compatible_ids[i].vendor, compatible_ids[i].device,
0748 0xFF, 0xFF, 0, &device_index))
0749 break;
0750 else
0751 device_index = ~0;
0752
0753 if (device_index == (uint)(~0)) {
0754 DLOG ("Unable to detect compatible device.");
0755 goto abort;
0756 }
0757
0758 DLOG ("Found device_index=%d", device_index);
0759
0760 if (!pci_get_device (device_index, &e1000_pci_device)) {
0761 DLOG ("Unable to get PCI device from PCI subsystem");
0762 return FALSE;
0763 }
0764
0765 if (!pci_decode_bar (device_index, 0, &mem_addr, NULL, NULL)) {
0766 DLOG ("Invalid PCI configuration or BAR0 not found");
0767 goto abort;
0768 }
0769
0770 DLOG ("Using PCI bus=%x dev=%x func=%x",
0771 e1000_pci_device.bus,
0772 e1000_pci_device.slot,
0773 e1000_pci_device.func);
0774
0775 if (mem_addr == 0) {
0776 DLOG ("Unable to detect memory mapped IO region");
0777 goto abort;
0778 }
0779
0780
0781 mmio_base = map_contiguous_virtual_pages (mem_addr | 3, E1000_MMIO_PAGES);
0782
0783 if (mmio_base == NULL) {
0784 DLOG ("Unable to map page to phys=%p", mem_addr);
0785 goto abort;
0786 }
0787
0788 DLOG ("Using memory mapped IO at phys=%p virt=%p", mem_addr, mmio_base);
0789
0790
0791
0792 frame_count = sizeof (struct e1000_interface) >> 12;
0793 if (sizeof (struct e1000_interface) & 0xFFF)
0794 frame_count++;
0795
0796
0797 e1000_phys = alloc_phys_frames (frame_count);
0798
0799 if (e1000_phys == -1) {
0800 DLOG ("Unable to allocate physical memory");
0801 goto abort_mmap;
0802 }
0803
0804
0805 e1000 = (struct e1000_interface *)
0806 map_contiguous_virtual_pages (e1000_phys | 3, frame_count);
0807
0808 if (e1000 == NULL) {
0809 DLOG ("Unable to allocate virtual memory");
0810 goto abort_phys;
0811 }
0812
0813
0814 memset (e1000, 0, sizeof (struct e1000_interface));
0815
0816 DLOG ("DMA region at virt=%p phys=%p count=%d", e1000, e1000_phys, frame_count);
0817
0818 if (!pci_get_interrupt (device_index, &irq_line, &irq_pin)) {
0819 DLOG ("Unable to get IRQ");
0820 goto abort_virt;
0821 }
0822
0823 if (pci_irq_find (e1000_pci_device.bus, e1000_pci_device.slot,
0824 irq_pin, &irq)) {
0825
0826 DLOG ("Found PCI routing entry irq.gsi=0x%x", irq.gsi);
0827 if (!pci_irq_map_handler (&irq, e1000_irq_handler, 0x01,
0828 IOAPIC_DESTINATION_LOGICAL,
0829 IOAPIC_DELIVERY_FIXED))
0830 goto abort_virt;
0831 irq_line = irq.gsi;
0832 }
0833
0834 DLOG ("Using IRQ line=%.02X pin=%X", irq_line, irq_pin);
0835
0836 #ifdef EEPROM_MICROWIRE
0837 *((uint16 *) &hwaddr[0]) = eeprom_read (0);
0838 *((uint16 *) &hwaddr[2]) = eeprom_read (1);
0839 *((uint16 *) &hwaddr[4]) = eeprom_read (2);
0840
0841 DLOG ("ICW1=0x%.04X", eeprom_read (0xA));
0842 #else
0843
0844 EERD = 0x0001;
0845 while (!(EERD & 0x10))
0846 asm volatile ("pause");
0847 hwaddr[0] = (EERD >> 16) & 0xFF;
0848 hwaddr[1] = (EERD >> 24) & 0xFF;
0849 EERD = 0x0101;
0850 while (!(EERD & 0x10))
0851 asm volatile ("pause");
0852 hwaddr[2] = (EERD >> 16) & 0xFF;
0853 hwaddr[3] = (EERD >> 24) & 0xFF;
0854 EERD = 0x0201;
0855 while (!(EERD & 0x10))
0856 asm volatile ("pause");
0857 hwaddr[4] = (EERD >> 16) & 0xFF;
0858 hwaddr[5] = (EERD >> 24) & 0xFF;
0859 #endif
0860
0861 DLOG ("hwaddr=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
0862 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
0863
0864 reset ();
0865
0866
0867 e1000_ethdev.recv_func = NULL;
0868 e1000_ethdev.send_func = e1000_transmit;
0869 e1000_ethdev.get_hwaddr_func = e1000_get_hwaddr;
0870 e1000_ethdev.poll_func = e1000_poll;
0871
0872 if (!net_register_device (&e1000_ethdev)) {
0873 DLOG ("registration failed");
0874 goto abort_virt;
0875 }
0876
0877 e1000_bh_id = create_kernel_thread_args ((u32) e1000_bh_thread,
0878 (u32) &e1000_bh_stack[1023],
0879 FALSE, 0);
0880 set_iovcpu (e1000_bh_id, IOVCPU_CLASS_NET);
0881
0882 return TRUE;
0883
0884 abort_virt:
0885 unmap_virtual_pages (e1000, frame_count);
0886 abort_phys:
0887 free_phys_frames (e1000_phys, frame_count);
0888 abort_mmap:
0889 unmap_virtual_pages ((void *)mmio_base, E1000_MMIO_PAGES);
0890 abort:
0891 return FALSE;
0892 }
0893
0894 #include "module/header.h"
0895
0896 static const struct module_ops mod_ops = {
0897 .init = e1000_init
0898 };
0899
0900 DEF_MODULE (net___e1000, "e1000 network driver", &mod_ops, {"net___ethernet", "pci"});
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911