diff options
| author | Miguel <m.i@gmx.at> | 2018-09-23 02:05:08 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-23 02:05:08 +0200 |
| commit | 0738f270da6c075b6c48d1b7aa929299ec178f2e (patch) | |
| tree | d536602bde81d4eda42102d4034afd535b2e1c55 /driver | |
| parent | e73d89fd48a71a1cff764fc07edd46cb951e9418 (diff) | |
interrupts from e1000 come in at least
Diffstat (limited to 'driver')
| -rw-r--r-- | driver/e1000.c | 97 | ||||
| -rw-r--r-- | driver/e1000.h | 2 | ||||
| -rw-r--r-- | driver/keyboard.c | 14 |
3 files changed, 67 insertions, 46 deletions
diff --git a/driver/e1000.c b/driver/e1000.c index 21d3924..8233993 100644 --- a/driver/e1000.c +++ b/driver/e1000.c @@ -14,6 +14,7 @@ // I have gathered those from different Hobby online operating systems instead of getting them one by one from the manual #define REG_CTRL 0x0000 +#define REG_ICR 0x00C0 // interrupt cause register #define REG_STATUS 0x0008 #define REG_EEPROM 0x0014 #define REG_CTRL_EXT 0x0018 @@ -269,49 +270,56 @@ void rxinit() rx_cur = 0; //enable receiving - uint32_t flags = (2 << 16) | (1 << 25) | (1 << 26) | (1 << 15) | (1 << 5) | (0 << 8) | (0 << 4) | (0 << 3) | ( 1 << 2); - writeCommand(REG_RCTRL, flags); - //writeCommand(REG_RCTRL, RCTL_EN| RCTL_SBP| RCTL_UPE | RCTL_MPE | RCTL_LBM_NONE | RTCL_RDMTS_HALF | RCTL_BAM | RCTL_SECRC | RCTL_BSIZE_2048); + //uint32_t flags = (2 << 16) | (1 << 25) | (1 << 26) | (1 << 15) | (1 << 5) | (0 << 8) | (0 << 4) | (0 << 3) | ( 1 << 2); + //writeCommand(REG_RCTRL, flags); + writeCommand(REG_RCTRL, RCTL_EN| RCTL_SBP| RCTL_UPE | RCTL_MPE | RCTL_LBM_NONE | RTCL_RDMTS_HALF | RCTL_BAM | RCTL_SECRC | RCTL_BSIZE_2048); } void txinit() { uint8_t * ptr; - struct e1000_tx_desc *descs; // Allocate buffer for receive descriptors. For simplicity, in my case khmalloc returns a virtual address that is identical to it physical mapped address. // In your case you should handle virtual and physical addresses as the addresses passed to the NIC should be physical ones - // + uint32_t alloc_pages=1+(sizeof(struct e1000_tx_desc)*E1000_NUM_TX_DESC + 16)/4096; ptr = kballoc(alloc_pages); - descs = (struct e1000_tx_desc *)ptr; + struct e1000_tx_desc *descs=ptr; for(int i = 0; i < E1000_NUM_TX_DESC; i++) { - tx_descs[i] = (struct e1000_tx_desc *)((uint8_t*)descs + i*16); + tx_descs[i] = descs++; tx_descs[i]->addr = 0; tx_descs[i]->cmd = 0; tx_descs[i]->status = TSTA_DD; } - writeCommand(REG_TXDESCHI, (uint32_t)(0) ); - writeCommand(REG_TXDESCLO, (uint32_t)(ptr)); + writeCommand(REG_TXDESCLO, ptr); //physical here + writeCommand(REG_TXDESCHI, 0); //now setup total length of descriptors - writeCommand(REG_TXDESCLEN, E1000_NUM_TX_DESC * 16); + writeCommand(REG_TXDESCLEN, E1000_NUM_TX_DESC * 16); // //setup numbers writeCommand( REG_TXDESCHEAD, 0); writeCommand( REG_TXDESCTAIL, 0); tx_cur = 0; + + writeCommand(REG_TCTRL, TCTL_EN | TCTL_PSP | (15 << TCTL_CT_SHIFT) | (64 << TCTL_COLD_SHIFT) | TCTL_RTLC); - +/* + writeCommand(REG_TCTRL, + 1<<0 // enable transmitter + |1<<3 // pad short packets +// ,64<<12 // collision distance + ); + */ // This line of code overrides the one before it but I left both to // highlight that the previous one works with e1000 cards, but for the // e1000e cards you should set the TCTRL register as follows. For detailed @@ -319,8 +327,8 @@ void txinit() // of I217 and 82577LM packets will not be sent if the TCTRL is not // configured using the following bits. - // writeCommand(REG_TCTRL, 0b0110000000000111111000011111010); - // writeCommand(REG_TIPG, 0x0060200A); + //writeCommand(REG_TCTRL, 0b0110000000000111111000011111010); + //writeCommand(REG_TIPG, 0x0060200A); } @@ -347,23 +355,29 @@ void e1000_handleReceive() int e1000_sendPacket(const void * p_data, uint16_t p_len) { - tx_descs[tx_cur]->addr = p_data; - tx_descs[tx_cur]->length = p_len; - tx_descs[tx_cur]->cmd = CMD_EOP | CMD_IFCS | CMD_RS | CMD_RPS; + tx_descs[tx_cur]->addr = p_data; // physical addy of data + tx_descs[tx_cur]->length = p_len; // length in bytes + //tx_descs[tx_cur]->cmd = CMD_EOP | CMD_IFCS | CMD_RS | CMD_RPS; + tx_descs[tx_cur]->cmd = ((1<<3)|3); tx_descs[tx_cur]->status = 0; + uint8_t old_cur = tx_cur; tx_cur = (tx_cur + 1) % E1000_NUM_TX_DESC; writeCommand(REG_TXDESCTAIL, tx_cur); while(!(tx_descs[old_cur]->status & 0xff)); + klog("SENT FIRST PACKET WOOOOW"); return 0; } void enableInterrupt() { - writeCommand(REG_IMASK ,0x1F6DC); - writeCommand(REG_IMASK ,0xff & ~4); - readCommand(0xc0); +// uint32_t status = readCommand(REG_ICR); // check interrupt cause register. +// klog("status before enabling e1000 interrupts=%d",status); + +// writeCommand(REG_IMASK ,0x1F6DC); +// writeCommand(REG_IMASK ,0xff & ~4); + writeCommand(REG_IMASK,0xffffffff); } void e1000_linkup() @@ -373,25 +387,34 @@ void e1000_linkup() writeCommand(REG_CTRL, val | ECTRL_SLU); } +void e1000_linkdown() +{ + uint32_t val; + val = readCommand(REG_CTRL); + writeCommand(REG_CTRL, val | ~ECTRL_SLU); +} + bool e1000_init(uint32_t base) { klog("init E1000"); - if(base!=0) mem_base=base; + if(base!=0){ mem_base=base; return true;} + detectEEProm(); if (! readMACAddress()) return false; klog("mac : %02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],mac[6]); - e1000_linkup(); +// e1000_linkup(); for(int i = 0; i < 0x80; i++)writeCommand(0x5200 + i*4, 0); enableInterrupt(); - rxinit(); txinit(); - + rxinit(); + + klog("E1000 initialized"); return true; @@ -405,25 +428,15 @@ void e1000_irq (int irq) Without this, the card will spam interrupts as the int-line will stay high. */ - writeCommand(REG_IMASK, 0x1); - enableInterrupt(); - - uint32_t status = readCommand(0xc0); + //writeCommand(REG_IMASK, 0x1); + //enableInterrupt(); + int status =0; +// uint32_t status = readCommand(REG_ICR); // check interrupt cause register. klog("e1000_irq status=%d",status); - if(status & 0x04) - { - e1000_linkup(); -// startLink(); - } - else if(status & 0x10) - { - // good threshold - } - else if(status & 0x80) - { - e1000_handleReceive(); - } - - //} + if(status & 0x1) klog ("transmit descriptor written back"); + if(status & 0x2) klog ("transmit queue empty"); + if(status & 0x4) klog ("link status change"); + if(status & 0x8) klog ("receive sequence error"); + //... } diff --git a/driver/e1000.h b/driver/e1000.h index 8534b6d..ba7db7d 100644 --- a/driver/e1000.h +++ b/driver/e1000.h @@ -2,3 +2,5 @@ bool e1000_init(uint32_t base); int e1000_sendPacket(const void * p_data, uint16_t p_len); void e1000_irq (int irq); +void e1000_linkup(); +void e1000_linkdown(); diff --git a/driver/keyboard.c b/driver/keyboard.c index 2352532..90a18c9 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -18,11 +18,17 @@ static void put(uint8_t c) { uint16_t dat[]={ 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x52,0x5,0x50a,0x00,0x02,0x02,0x08,0x06,0x00, - 0x01,0x08,0x00,0x06,0x04,0x00,0x01,0x52,0x5,0x50a,0x00,0x02,0x02,0x0a,0x00,0x02}; + 0x01,0x08,0x00,0x06,0x04,0x00,0x01,0x52,0x5,0x50a,0x00,0x02,0x02,0x0a,0x00,0x02, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x52,0x5,0x50a,0x00,0x02,0x02,0x08,0x06,0x00, + 0x01,0x08,0x00,0x06,0x04,0x00,0x01,0x52,0x5,0x50a,0x00,0x02,0x02,0x0a,0x00,0x02 + }; + + if(c=='p')e1000_sendPacket(dat,64); // packet + if(c=='s')e1000_init(0); // start + if(c=='i')e1000_irq(11); // interrupt + if(c=='u')e1000_linkup(); // up + if(c=='d')e1000_linkdown(); // down - if(c=='y')e1000_sendPacket(dat,32); - if(c=='x')e1000_init(0); - if(c=='i')e1000_irq(11); syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0); } |
