CS350 COS
COS
Loading...
Searching...
No Matches
e1000.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <sys/semaphore.h>
#include <sys/pci.h>
#include <sys/irq.h>
#include <sys/mbuf.h>
#include <sys/nic.h>
#include <machine/pmap.h>
Include dependency graph for e1000.c:

Go to the source code of this file.

Data Structures

struct  E1000Device
 
struct  E1000RXDesc
 
struct  E1000TXDesc
 
struct  E1000Dev
 

Macros

#define E1000_REG_CTRL   0x0000
 
#define E1000_REG_STATUS   0x0008
 
#define E1000_REG_EECD   0x0010
 
#define E1000_REG_EERD   0x0014
 
#define E1000_REG_ICR   0x00C0
 
#define E1000_REG_ICS   0x00C8
 
#define E1000_REG_IMS   0x00D0
 
#define E1000_REG_IMC   0x00D8
 
#define E1000_REG_RCTL   0x0100
 
#define E1000_REG_TCTL   0x0400
 
#define E1000_REG_RDBAL   0x2800
 
#define E1000_REG_RDBAH   0x2804
 
#define E1000_REG_RDLEN   0x2808
 
#define E1000_REG_RDH   0x2810
 
#define E1000_REG_RDT   0x2818
 
#define E1000_REG_RDTR   0x2820
 
#define E1000_REG_TDBAL   0x3800
 
#define E1000_REG_TDBAH   0x3804
 
#define E1000_REG_TDLEN   0x3808
 
#define E1000_REG_TDH   0x3810
 
#define E1000_REG_TDT   0x3818
 
#define E1000_REG_TIDV   0x3820
 
#define E1000_REG_TADV   0x382C
 
#define E1000_REG_MTABASE   0x5200
 
#define NVM_MAC_ADDR   0x0000
 
#define NVM_DEVICE_ID   0x000D
 
#define NVM_VENDOR_ID   0x000E
 
#define CTRL_SLU   (1 << 6)
 
#define RCTL_EN   (1 << 1)
 
#define RCTL_SBP   (1 << 2)
 
#define RCTL_UPE   (1 << 3)
 
#define RCTL_MPE   (1 << 4)
 
#define RCTL_LPE   (1 << 5)
 
#define RCTL_BSIZE_1K   (0x1 << 16)
 
#define RCTL_BSIZE_2K   (0x0 << 16)
 
#define RCTL_BSIZE_4K   ((1 << 25) | (0x3 << 16))
 
#define RCTL_BSIZE_8K   ((1 << 25) | (0x2 << 16))
 
#define RCTL_BSIZE_16K   ((1 << 25) | (0x1 << 16))
 
#define TCTL_EN   (1 << 1)
 
#define TCTL_PSP   (1 << 3)
 
#define ICR_TXDW   (1 << 0)
 
#define ICR_LSC   (1 << 2)
 
#define ICR_RXO   (1 << 6)
 
#define ICR_RXT0   (1 << 7)
 
#define RDESC_STATUS_EOP   (1 << 1)
 
#define RDESC_STATUS_DD   (1 << 0)
 
#define RDESC_ERROR_RDE   (1 << 7) /* Receive Data Error */
 
#define RDESC_ERROR_CE   (1 << 0) /* CRC Error */
 
#define TDESC_CMD_RS   (1 << 3) /* Report Status */
 
#define TDESC_CMD_IC   (1 << 2) /* Insert Checksum */
 
#define TDESC_CMD_IFCS   (1 << 1) /* Insert Ethernet FCS/CRC */
 
#define TDESC_CMD_EOP   (1 << 0) /* End-of-Packet */
 
#define E1000_TX_QLEN   128
 
#define E1000_RX_QLEN   128
 
#define E1000_MAX_MTU   9000
 

Typedefs

typedef struct E1000Device E1000Device
 
typedef struct PACKED E1000RXDesc E1000RXDesc
 
typedef struct PACKED E1000TXDesc E1000TXDesc
 
typedef struct E1000Dev E1000Dev
 

Functions

void E1000_Configure (PCIDevice dev)
 
 DEFINE_SLAB (E1000RXDesc, &rxDescPool)
 
 DEFINE_SLAB (E1000TXDesc, &txDescPool)
 
void * RXPOOL_Alloc ()
 
void RXPOOL_Free (void *buf)
 
void E1000_Init (uint32_t bus, uint32_t slot, uint32_t func)
 
static uint32_t MMIO_Read32 (E1000Dev *dev, uint64_t addr)
 
static void MMIO_Write32 (E1000Dev *dev, uint64_t addr, uint32_t val)
 
static uint16_t E1000_EEPROM_Read (E1000Dev *dev, uint8_t addr)
 
void E1000_TXPoll (E1000Dev *dev)
 
void E1000_RXPoll (E1000Dev *dev)
 
void E1000_Interrupt (void *arg)
 
int E1000_Dequeue (NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
 
int E1000_Enqueue (NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
 
void E1000_RXInit (E1000Dev *dev)
 
void E1000_TXInit (E1000Dev *dev)
 

Variables

static E1000Device deviceList []
 
static bool runOnce = false
 
static Slab rxPool
 
static Slab rxDescPool
 
static Slab txDescPool
 

Data Structure Documentation

◆ E1000Device

struct E1000Device

Definition at line 17 of file e1000.c.

Collaboration diagram for E1000Device:
[legend]
Data Fields
uint32_t device
uint32_t flags
const char * name

◆ E1000RXDesc

struct E1000RXDesc

Definition at line 95 of file e1000.c.

Collaboration diagram for E1000RXDesc:
[legend]
Data Fields
volatile uint64_t addr
volatile uint16_t csum
volatile uint8_t errors
volatile uint16_t len
volatile uint16_t special
volatile uint8_t status

◆ E1000TXDesc

struct E1000TXDesc

Definition at line 110 of file e1000.c.

Collaboration diagram for E1000TXDesc:
[legend]
Data Fields
volatile uint64_t addr
volatile uint8_t cmd
volatile uint8_t cso
volatile uint8_t css
volatile uint16_t len
volatile uint16_t special
volatile uint8_t status

◆ E1000Dev

struct E1000Dev

Definition at line 129 of file e1000.c.

Collaboration diagram for E1000Dev:
[legend]
Data Fields
PCIDevice dev
Semaphore ioSema
IRQHandler irqHandle
Spinlock lock
uint8_t * mmiobase
NIC nic
E1000RXDesc * rxDesc
uint32_t rxTail
E1000TXDesc * txDesc
uint32_t txTail

Macro Definition Documentation

◆ CTRL_SLU

#define CTRL_SLU   (1 << 6)

Definition at line 71 of file e1000.c.

◆ E1000_MAX_MTU

#define E1000_MAX_MTU   9000

Definition at line 145 of file e1000.c.

◆ E1000_REG_CTRL

#define E1000_REG_CTRL   0x0000

Definition at line 37 of file e1000.c.

◆ E1000_REG_EECD

#define E1000_REG_EECD   0x0010

Definition at line 39 of file e1000.c.

◆ E1000_REG_EERD

#define E1000_REG_EERD   0x0014

Definition at line 40 of file e1000.c.

◆ E1000_REG_ICR

#define E1000_REG_ICR   0x00C0

Definition at line 41 of file e1000.c.

◆ E1000_REG_ICS

#define E1000_REG_ICS   0x00C8

Definition at line 42 of file e1000.c.

◆ E1000_REG_IMC

#define E1000_REG_IMC   0x00D8

Definition at line 44 of file e1000.c.

◆ E1000_REG_IMS

#define E1000_REG_IMS   0x00D0

Definition at line 43 of file e1000.c.

◆ E1000_REG_MTABASE

#define E1000_REG_MTABASE   0x5200

Definition at line 63 of file e1000.c.

◆ E1000_REG_RCTL

#define E1000_REG_RCTL   0x0100

Definition at line 45 of file e1000.c.

◆ E1000_REG_RDBAH

#define E1000_REG_RDBAH   0x2804

Definition at line 49 of file e1000.c.

◆ E1000_REG_RDBAL

#define E1000_REG_RDBAL   0x2800

Definition at line 48 of file e1000.c.

◆ E1000_REG_RDH

#define E1000_REG_RDH   0x2810

Definition at line 51 of file e1000.c.

◆ E1000_REG_RDLEN

#define E1000_REG_RDLEN   0x2808

Definition at line 50 of file e1000.c.

◆ E1000_REG_RDT

#define E1000_REG_RDT   0x2818

Definition at line 52 of file e1000.c.

◆ E1000_REG_RDTR

#define E1000_REG_RDTR   0x2820

Definition at line 53 of file e1000.c.

◆ E1000_REG_STATUS

#define E1000_REG_STATUS   0x0008

Definition at line 38 of file e1000.c.

◆ E1000_REG_TADV

#define E1000_REG_TADV   0x382C

Definition at line 61 of file e1000.c.

◆ E1000_REG_TCTL

#define E1000_REG_TCTL   0x0400

Definition at line 46 of file e1000.c.

◆ E1000_REG_TDBAH

#define E1000_REG_TDBAH   0x3804

Definition at line 56 of file e1000.c.

◆ E1000_REG_TDBAL

#define E1000_REG_TDBAL   0x3800

Definition at line 55 of file e1000.c.

◆ E1000_REG_TDH

#define E1000_REG_TDH   0x3810

Definition at line 58 of file e1000.c.

◆ E1000_REG_TDLEN

#define E1000_REG_TDLEN   0x3808

Definition at line 57 of file e1000.c.

◆ E1000_REG_TDT

#define E1000_REG_TDT   0x3818

Definition at line 59 of file e1000.c.

◆ E1000_REG_TIDV

#define E1000_REG_TIDV   0x3820

Definition at line 60 of file e1000.c.

◆ E1000_RX_QLEN

#define E1000_RX_QLEN   128

Definition at line 143 of file e1000.c.

◆ E1000_TX_QLEN

#define E1000_TX_QLEN   128

Definition at line 142 of file e1000.c.

◆ ICR_LSC

#define ICR_LSC   (1 << 2)

Definition at line 91 of file e1000.c.

◆ ICR_RXO

#define ICR_RXO   (1 << 6)

Definition at line 92 of file e1000.c.

◆ ICR_RXT0

#define ICR_RXT0   (1 << 7)

Definition at line 93 of file e1000.c.

◆ ICR_TXDW

#define ICR_TXDW   (1 << 0)

Definition at line 90 of file e1000.c.

◆ NVM_DEVICE_ID

#define NVM_DEVICE_ID   0x000D

Definition at line 67 of file e1000.c.

◆ NVM_MAC_ADDR

#define NVM_MAC_ADDR   0x0000

Definition at line 66 of file e1000.c.

◆ NVM_VENDOR_ID

#define NVM_VENDOR_ID   0x000E

Definition at line 68 of file e1000.c.

◆ RCTL_BSIZE_16K

#define RCTL_BSIZE_16K   ((1 << 25) | (0x1 << 16))

Definition at line 83 of file e1000.c.

◆ RCTL_BSIZE_1K

#define RCTL_BSIZE_1K   (0x1 << 16)

Definition at line 79 of file e1000.c.

◆ RCTL_BSIZE_2K

#define RCTL_BSIZE_2K   (0x0 << 16)

Definition at line 80 of file e1000.c.

◆ RCTL_BSIZE_4K

#define RCTL_BSIZE_4K   ((1 << 25) | (0x3 << 16))

Definition at line 81 of file e1000.c.

◆ RCTL_BSIZE_8K

#define RCTL_BSIZE_8K   ((1 << 25) | (0x2 << 16))

Definition at line 82 of file e1000.c.

◆ RCTL_EN

#define RCTL_EN   (1 << 1)

Definition at line 74 of file e1000.c.

◆ RCTL_LPE

#define RCTL_LPE   (1 << 5)

Definition at line 78 of file e1000.c.

◆ RCTL_MPE

#define RCTL_MPE   (1 << 4)

Definition at line 77 of file e1000.c.

◆ RCTL_SBP

#define RCTL_SBP   (1 << 2)

Definition at line 75 of file e1000.c.

◆ RCTL_UPE

#define RCTL_UPE   (1 << 3)

Definition at line 76 of file e1000.c.

◆ RDESC_ERROR_CE

#define RDESC_ERROR_CE   (1 << 0) /* CRC Error */

Definition at line 108 of file e1000.c.

◆ RDESC_ERROR_RDE

#define RDESC_ERROR_RDE   (1 << 7) /* Receive Data Error */

Definition at line 107 of file e1000.c.

◆ RDESC_STATUS_DD

#define RDESC_STATUS_DD   (1 << 0)

Definition at line 105 of file e1000.c.

◆ RDESC_STATUS_EOP

#define RDESC_STATUS_EOP   (1 << 1)

Definition at line 104 of file e1000.c.

◆ TCTL_EN

#define TCTL_EN   (1 << 1)

Definition at line 86 of file e1000.c.

◆ TCTL_PSP

#define TCTL_PSP   (1 << 3)

Definition at line 87 of file e1000.c.

◆ TDESC_CMD_EOP

#define TDESC_CMD_EOP   (1 << 0) /* End-of-Packet */

Definition at line 123 of file e1000.c.

◆ TDESC_CMD_IC

#define TDESC_CMD_IC   (1 << 2) /* Insert Checksum */

Definition at line 121 of file e1000.c.

◆ TDESC_CMD_IFCS

#define TDESC_CMD_IFCS   (1 << 1) /* Insert Ethernet FCS/CRC */

Definition at line 122 of file e1000.c.

◆ TDESC_CMD_RS

#define TDESC_CMD_RS   (1 << 3) /* Report Status */

Definition at line 120 of file e1000.c.

Typedef Documentation

◆ E1000Dev

typedef struct E1000Dev E1000Dev

◆ E1000Device

typedef struct E1000Device E1000Device

◆ E1000RXDesc

typedef struct PACKED E1000RXDesc E1000RXDesc

◆ E1000TXDesc

typedef struct PACKED E1000TXDesc E1000TXDesc

Function Documentation

◆ DEFINE_SLAB() [1/2]

DEFINE_SLAB ( E1000RXDesc  ,
rxDescPool 
)

◆ DEFINE_SLAB() [2/2]

DEFINE_SLAB ( E1000TXDesc  ,
txDescPool 
)

◆ E1000_Configure()

void E1000_Configure ( PCIDevice  dev)

Definition at line 437 of file e1000.c.

438{
439 E1000Dev *ethDev = (E1000Dev *)PAlloc_AllocPage();
440 PCI_Configure(&dev);
441
442 // Ensure that the NIC structure is the first thing inside E1000Dev
443 ASSERT((void *)ethDev == (void *)&ethDev->nic);
444
445 if (!runOnce) {
446 runOnce = true;
447
448 //E1000_MAX_MTU + 14 + 4, 4096);
449 Slab_Init(&rxPool, "E1000 RX Pool", 4096, 4096);
450 Slab_Init(&rxDescPool, "E1000 RX Descriptors", E1000_RX_QLEN*sizeof(E1000RXDesc), 16);
451 Slab_Init(&txDescPool, "E1000 TX Descriptors", E1000_TX_QLEN*sizeof(E1000TXDesc), 16);
452 }
453
454 // Copy PCIDevice structure
455 memcpy(&ethDev->dev, &dev, sizeof(dev));
456
457 // MMIO
458 int bar;
459 for (bar = 0; bar < PCI_MAX_BARS; bar++) {
460 if (dev.bars[bar].size == 0)
461 continue;
462
463 kprintf("E1000: BAR%d base=%08x size=%08x %s\n",
464 bar, dev.bars[bar].base, dev.bars[bar].size,
465 dev.bars[bar].type == PCIBAR_TYPE_IO ? "IO" : "Mem");
466 }
467
468 ethDev->mmiobase = (uint8_t *)DMPA2VA(dev.bars[0].base);
469
470 // Enable Link
472
473 // Register IRQs
474 kprintf("E1000: IRQ %d\n", dev.irq);
475 ethDev->irqHandle.irq = dev.irq;
476 ethDev->irqHandle.cb = &E1000_Interrupt;
477 ethDev->irqHandle.arg = ethDev;
478 IRQ_Register(dev.irq, &ethDev->irqHandle);
479
480 kprintf("E1000: MAC XX:XX:XX:XX:XX:XX\n");
481 for (int i = 0; i < 3; i++) {
482 E1000_EEPROM_Read(ethDev, NVM_MAC_ADDR + 2*i);
483 }
484
485 // Device lock
486 Spinlock_Init(&ethDev->lock, "E1000 Spinlock", SPINLOCK_TYPE_NORMAL);
487
488 // IO Semaphore
489 Semaphore_Init(&ethDev->ioSema, 0, "E1000 Semaphore");
490 ethDev->nic.tx = &E1000_Enqueue;
491 ethDev->nic.rx = &E1000_Dequeue;
492
493 // Enable interrupts
494 //MMIO_Write32(ethDev, E1000_REG_IMC, ~0);
495 MMIO_Write32(ethDev, E1000_REG_IMS, 0x1F6DC); //ICR_TXDW | ICR_RXO | ICR_RXT0);
496 MMIO_Read32(ethDev, E1000_REG_ICR); // Clear pending interrupts
497
498 E1000_RXInit(ethDev);
499 E1000_TXInit(ethDev);
500
501 ethDev->nic.handle = ethDev;
502 // XXX: Fill in callbacks
503 NIC_AddNIC(&ethDev->nic);
504}
void PCI_Configure(PCIDevice *dev)
Definition: pci.c:249
#define E1000_REG_IMS
Definition: e1000.c:43
#define CTRL_SLU
Definition: e1000.c:71
static Slab rxPool
Definition: e1000.c:149
static void MMIO_Write32(E1000Dev *dev, uint64_t addr, uint32_t val)
Definition: e1000.c:199
static Slab txDescPool
Definition: e1000.c:151
static uint16_t E1000_EEPROM_Read(E1000Dev *dev, uint8_t addr)
Definition: e1000.c:205
IRQHandler irqHandle
Definition: e1000.c:132
#define E1000_RX_QLEN
Definition: e1000.c:143
uint8_t * mmiobase
Definition: e1000.c:133
static uint32_t MMIO_Read32(E1000Dev *dev, uint64_t addr)
Definition: e1000.c:193
#define E1000_REG_ICR
Definition: e1000.c:41
int E1000_Enqueue(NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
Definition: e1000.c:360
PCIDevice dev
Definition: e1000.c:131
NIC nic
Definition: e1000.c:130
static Slab rxDescPool
Definition: e1000.c:150
void E1000_TXInit(E1000Dev *dev)
Definition: e1000.c:409
int E1000_Dequeue(NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
Definition: e1000.c:317
Semaphore ioSema
Definition: e1000.c:139
Spinlock lock
Definition: e1000.c:138
#define E1000_REG_CTRL
Definition: e1000.c:37
void E1000_Interrupt(void *arg)
Definition: e1000.c:271
#define E1000_TX_QLEN
Definition: e1000.c:142
void E1000_RXInit(E1000Dev *dev)
Definition: e1000.c:379
static bool runOnce
Definition: e1000.c:148
#define NVM_MAC_ADDR
Definition: e1000.c:66
void IRQ_Register(int irq, struct IRQHandler *h)
Definition: irq.c:35
#define ASSERT(_x)
Definition: kassert.h:8
int kprintf(const char *fmt,...)
Definition: printf.c:210
void * PAlloc_AllocPage()
Definition: palloc.c:188
void Slab_Init(Slab *slab, const char *name, uintptr_t objsz, uintptr_t align)
void NIC_AddNIC(NIC *nic)
#define PCI_MAX_BARS
Definition: pci.h:24
uint8_t irq
Definition: pci.h:64
#define PCIBAR_TYPE_IO
Definition: pci.h:45
PCIBAR bars[PCI_MAX_BARS]
Definition: pci.h:66
uint32_t base
Definition: pci.h:50
uint32_t size
Definition: pci.h:51
uint32_t type
Definition: pci.h:52
#define DMPA2VA(pa)
Definition: pmap.h:48
void Semaphore_Init(Semaphore *sema, int count, const char *name)
#define SPINLOCK_TYPE_NORMAL
Definition: spinlock.h:12
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
Definition: spinlock.c:43
void * memcpy(void *dst, const void *src, size_t len)
Definition: string.c:177
void * arg
Definition: irq.h:10
int irq
Definition: irq.h:8
void(* cb)(void *)
Definition: irq.h:9
void * handle
Definition: nic.h:12
int(* tx)(NIC *, MBuf *, NICCB, void *)
Definition: nic.h:15
int(* rx)(NIC *, MBuf *, NICCB, void *)
Definition: nic.h:16
unsigned char uint8_t
Definition: types.h:10
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_Dequeue()

int E1000_Dequeue ( NIC nic,
MBuf mbuf,
NICCB  cb,
void *  arg 
)

Definition at line 317 of file e1000.c.

318{
319 E1000Dev *dev = (E1000Dev *)nic;
320
321retry:
323
324 Spinlock_Lock(&dev->lock);
325 if ((dev->rxDesc[dev->rxTail].status & RDESC_STATUS_EOP) &&
326 (dev->rxDesc[dev->rxTail].errors == 0)) {
327 void *data = (void *)DMPA2VA(dev->rxDesc[dev->rxTail].addr);
328 uint16_t len = dev->rxDesc[dev->rxTail].len;
329
330 //Debug_PrintHex(data, len, 0, len);
331 // Use CB instead
332 memcpy((void *)mbuf->vaddr, data, len);
333
334 dev->rxDesc[dev->rxTail].status = 0;
335 dev->rxDesc[dev->rxTail].errors = 0;
336 // XXX: Should write this only once
338 dev->rxTail = (dev->rxTail + 1) % E1000_RX_QLEN;
339 } else {
340 /*
341 * XXX: Need to remove this once I do the copyout inside the interrupt
342 * handler.
343 */
344 /*kprintf("Packet not ready %d %x %x\n",
345 dev->rxTail,
346 dev->rxDesc[dev->rxTail].status,
347 dev->rxDesc[dev->rxTail].errors);*/
348 Spinlock_Unlock(&dev->lock);
349 goto retry;
350 }
351 Spinlock_Unlock(&dev->lock);
352
353 return 0;
354}
E1000RXDesc * rxDesc
Definition: e1000.c:134
volatile uint64_t addr
Definition: e1000.c:96
volatile uint8_t status
Definition: e1000.c:99
volatile uint8_t errors
Definition: e1000.c:100
#define RDESC_STATUS_EOP
Definition: e1000.c:104
volatile uint16_t len
Definition: e1000.c:97
uint32_t rxTail
Definition: e1000.c:136
#define E1000_REG_RDT
Definition: e1000.c:52
static MBuf mbuf
Definition: ethdump.c:11
uint64_t vaddr
Definition: mbuf.h:15
uint64_t len
Definition: multiboot.h:2
void Semaphore_Acquire(Semaphore *sema)
Definition: semaphore.c:49
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
unsigned short uint16_t
Definition: types.h:11
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_EEPROM_Read()

static uint16_t E1000_EEPROM_Read ( E1000Dev dev,
uint8_t  addr 
)
static

Definition at line 205 of file e1000.c.

206{
207 uint16_t val;
208
209 // Write Address
210 MMIO_Write32(dev, E1000_REG_EERD, ((uint32_t)addr << 8) | 1);
211
212 // Wait for ready bit
213 while (1) {
214 val = MMIO_Read32(dev, E1000_REG_EERD);
215 if (val & 0x10)
216 break;
217 }
218
219 kprintf("%08x\n", val);
220
221 return (uint16_t)((val >> 16) & 0x0000FFFF);
222}
#define E1000_REG_EERD
Definition: e1000.c:40
uint64_t addr
Definition: multiboot.h:1
unsigned int uint32_t
Definition: types.h:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_Enqueue()

int E1000_Enqueue ( NIC nic,
MBuf mbuf,
NICCB  cb,
void *  arg 
)

Definition at line 360 of file e1000.c.

361{
362 E1000Dev *dev = (E1000Dev *)nic;
363 void *data = (void *)DMPA2VA(dev->txDesc[dev->txTail].addr);
364
365 // Copy data
366 memcpy(data, (void *)mbuf->vaddr, mbuf->len);
367 dev->txDesc[dev->txTail].len = mbuf->len;
368
371 dev->txTail = (dev->txTail + 1) % E1000_TX_QLEN;
372
373 // Wait for transmit to complete
374
375 return 0;
376}
volatile uint8_t cmd
Definition: e1000.c:114
#define E1000_REG_TDT
Definition: e1000.c:59
#define TDESC_CMD_RS
Definition: e1000.c:120
E1000TXDesc * txDesc
Definition: e1000.c:135
volatile uint64_t addr
Definition: e1000.c:111
uint32_t txTail
Definition: e1000.c:137
#define TDESC_CMD_IFCS
Definition: e1000.c:122
volatile uint16_t len
Definition: e1000.c:112
#define TDESC_CMD_EOP
Definition: e1000.c:123
uint32_t len
Definition: mbuf.h:17
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_Init()

void E1000_Init ( uint32_t  bus,
uint32_t  slot,
uint32_t  func 
)

Definition at line 168 of file e1000.c.

169{
170 PCIDevice dev;
171
172 dev.bus = bus;
173 dev.slot = slot;
174 dev.func = func;
175 dev.vendor = PCI_GetVendorID(&dev);
176 dev.device = PCI_GetDeviceID(&dev);
177
178 uint32_t device = dev.vendor << 16 | dev.device;
179
180 int deviceIdx = 0;
181 while (deviceList[deviceIdx].device != 0x0) {
182 if (deviceList[deviceIdx].device == device) {
183 kprintf("E1000: Found %s\n", deviceList[deviceIdx].name);
184 // Configure and add disks
185 E1000_Configure(dev);
186 }
187
188 deviceIdx++;
189 }
190}
uint16_t PCI_GetVendorID(PCIDevice *dev)
Definition: pci.c:107
uint16_t PCI_GetDeviceID(PCIDevice *dev)
Definition: pci.c:101
static E1000Device deviceList[]
Definition: e1000.c:24
void E1000_Configure(PCIDevice dev)
Definition: e1000.c:437
uint8_t slot
Definition: pci.h:61
uint16_t device
Definition: pci.h:58
uint8_t func
Definition: pci.h:62
uint16_t vendor
Definition: pci.h:57
uint8_t bus
Definition: pci.h:60
Definition: pci.h:56
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_Interrupt()

void E1000_Interrupt ( void *  arg)

Definition at line 271 of file e1000.c.

272{
273 E1000Dev *dev = (E1000Dev *)arg;
274
275 kprintf("E1000 (%d:%d) Interrupt\n",
276 dev->dev.bus, dev->dev.slot);
277
278 uint32_t cause = MMIO_Read32(dev, E1000_REG_ICR);
279
280 // Link Status
281 if (cause & ICR_LSC) {
282 cause &= ~ICR_LSC;
284 }
285
286 // Transmit Queue Empty
287 if (cause & 3) {
288 cause &= ~3;
289 E1000_TXPoll(dev);
290 }
291
292 // Receive Overrun
293 if (cause & ICR_RXO) {
294 cause &= ~ICR_RXO;
295 kprintf("underrun %u %u\n", MMIO_Read32(dev, E1000_REG_RDH), dev->rxTail);
296
297 E1000_RXPoll(dev);
298 }
299
300 // Receive Timer
301 if (cause & ICR_RXT0) {
302 cause &= ~ICR_RXT0;
303 E1000_RXPoll(dev);
304 }
305
306 if (cause != 0) {
307 kprintf("E1000: Unhandled cause %08x\n", cause);
308 }
309
311}
void E1000_TXPoll(E1000Dev *dev)
Definition: e1000.c:225
#define ICR_LSC
Definition: e1000.c:91
#define ICR_RXO
Definition: e1000.c:92
void E1000_RXPoll(E1000Dev *dev)
Definition: e1000.c:232
#define E1000_REG_RDH
Definition: e1000.c:51
#define ICR_RXT0
Definition: e1000.c:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_RXInit()

void E1000_RXInit ( E1000Dev dev)

Definition at line 379 of file e1000.c.

380{
381 int i;
382
383 // Zero out Multicast Table Array
384 for (i = 0; i < 128; i++) {
385 MMIO_Write32(dev, E1000_REG_MTABASE + (i * 4), 0);
386 }
387
388 dev->rxDesc = (E1000RXDesc *)E1000RXDesc_Alloc();
389 for (i = 0; i < E1000_RX_QLEN; i++) {
390 dev->rxDesc[i].addr = VA2PA((uintptr_t)PAlloc_AllocPage()); // LOOKUP IN PMAP
391 dev->rxDesc[i].status = 0;
392 }
393
394 // Setup base and length of recieve descriptors
397 MMIO_Write32(dev, E1000_REG_RDBAL, (uint32_t)(base & 0xFFFFFFFF));
399
402 dev->rxTail = 0;
403
406}
#define E1000_REG_MTABASE
Definition: e1000.c:63
#define E1000_REG_RDLEN
Definition: e1000.c:50
#define E1000_REG_RDBAH
Definition: e1000.c:49
#define E1000_REG_RCTL
Definition: e1000.c:45
#define RCTL_EN
Definition: e1000.c:74
#define RCTL_MPE
Definition: e1000.c:77
#define E1000_REG_RDBAL
Definition: e1000.c:48
#define RCTL_BSIZE_4K
Definition: e1000.c:81
#define RCTL_UPE
Definition: e1000.c:76
#define VA2PA(va)
Definition: pmap.h:49
static uint16_t base
Definition: sercons.c:37
uint64_t uintptr_t
Definition: types.h:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_RXPoll()

void E1000_RXPoll ( E1000Dev dev)

Definition at line 232 of file e1000.c.

233{
234 while (dev->rxDesc[dev->rxTail].status & RDESC_STATUS_DD) {
235 //void *data = (void *)DMPA2VA(dev->rxDesc[dev->rxTail].addr);
236 //uint16_t len = dev->rxDesc[dev->rxTail].len;
237
238 // Look for packet fragments up to EOP set in status
239 if ((dev->rxDesc[dev->rxTail].status & RDESC_STATUS_EOP) &&
240 (dev->rxDesc[dev->rxTail].errors == 0)) {
241 // Process packet
242 /*
243 * XXX: Need to create a queue and copyout packets here, because
244 * I'm seeing multiple interrupts.
245 *
246 * kprintf("E1000: Int\n");
247 */
249 }
250
251 if (dev->rxDesc[dev->rxTail].errors) {
252 kprintf("E1000: Error in RX Queue %x\n",
253 dev->rxDesc[dev->rxTail].errors);
254 dev->rxDesc[dev->rxTail].status = 0;
255 dev->rxDesc[dev->rxTail].errors = 0;
257 dev->rxTail = (dev->rxTail + 1) % E1000_RX_QLEN;
258 }
259
260 /*
261 dev->rxDesc[dev->rxTail].status = 0;
262 dev->rxDesc[dev->rxTail].errors = 0;
263 // XXX: Should write this only once
264 MMIO_Write32(dev, E1000_REG_RDT, dev->rxTail);
265 dev->rxTail = (dev->rxTail + 1) % E1000_RX_QLEN;
266 */
267 }
268}
#define RDESC_STATUS_DD
Definition: e1000.c:105
void Semaphore_Release(Semaphore *sema)
Definition: semaphore.c:72
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_TXInit()

void E1000_TXInit ( E1000Dev dev)

Definition at line 409 of file e1000.c.

410{
411 int i;
412
413 dev->txDesc = (E1000TXDesc *)E1000RXDesc_Alloc();
414 for (i = 0; i < E1000_TX_QLEN; i++) {
415 dev->txDesc[i].addr = VA2PA((uintptr_t)PAlloc_AllocPage()); // LOOKUP IN PMAP
416 dev->txDesc[i].cmd = 0;
417 }
418
419 // Setup base and length of recieve descriptors
422 MMIO_Write32(dev, E1000_REG_TDBAL, (uint32_t)(base & 0xFFFFFFFF));
424
427 dev->txTail = 0;
428
429 // Interrupt Delay Timers
432
434}
#define E1000_REG_TCTL
Definition: e1000.c:46
#define TCTL_PSP
Definition: e1000.c:87
#define E1000_REG_TDH
Definition: e1000.c:58
#define E1000_REG_TDBAH
Definition: e1000.c:56
#define TCTL_EN
Definition: e1000.c:86
#define E1000_REG_TIDV
Definition: e1000.c:60
#define E1000_REG_TDLEN
Definition: e1000.c:57
#define E1000_REG_TDBAL
Definition: e1000.c:55
#define E1000_REG_TADV
Definition: e1000.c:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ E1000_TXPoll()

void E1000_TXPoll ( E1000Dev dev)

Definition at line 225 of file e1000.c.

226{
227 // Free memory
228 kprintf("TXPOLL\n");
229}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MMIO_Read32()

static uint32_t MMIO_Read32 ( E1000Dev dev,
uint64_t  addr 
)
inlinestatic

Definition at line 193 of file e1000.c.

194{
195 return *(uint32_t volatile *)(dev->mmiobase + addr);
196}
Here is the caller graph for this function:

◆ MMIO_Write32()

static void MMIO_Write32 ( E1000Dev dev,
uint64_t  addr,
uint32_t  val 
)
inlinestatic

Definition at line 199 of file e1000.c.

200{
201 *(uint32_t *)(dev->mmiobase + addr) = val;
202}
Here is the caller graph for this function:

◆ RXPOOL_Alloc()

void * RXPOOL_Alloc ( )

Definition at line 156 of file e1000.c.

157{
158 return Slab_Alloc(&rxPool);
159}
void * Slab_Alloc(Slab *slab) __attribute__((malloc))
Definition: slab.c:105
Here is the call graph for this function:

◆ RXPOOL_Free()

void RXPOOL_Free ( void *  buf)

Definition at line 162 of file e1000.c.

163{
165}
static char buf[4096]
Definition: ethdump.c:10
void Slab_Free(Slab *slab, void *obj)
Definition: slab.c:135
Here is the call graph for this function:

Variable Documentation

◆ deviceList

E1000Device deviceList[]
static
Initial value:
=
{
{ 0x8086100e, "E1000", 0 },
{ 0, "", 0 },
}

Definition at line 24 of file e1000.c.

◆ runOnce

bool runOnce = false
static

Definition at line 148 of file e1000.c.

◆ rxDescPool

Slab rxDescPool
static

Definition at line 150 of file e1000.c.

◆ rxPool

Slab rxPool
static

Definition at line 149 of file e1000.c.

◆ txDescPool

Slab txDescPool
static

Definition at line 151 of file e1000.c.