summaryrefslogtreecommitdiff
path: root/driver/e1000.c
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-23 02:05:08 +0200
committerMiguel <m.i@gmx.at>2018-09-23 02:05:08 +0200
commit0738f270da6c075b6c48d1b7aa929299ec178f2e (patch)
treed536602bde81d4eda42102d4034afd535b2e1c55 /driver/e1000.c
parente73d89fd48a71a1cff764fc07edd46cb951e9418 (diff)
interrupts from e1000 come in at least
Diffstat (limited to 'driver/e1000.c')
-rw-r--r--driver/e1000.c97
1 files changed, 55 insertions, 42 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");
+ //...
}