警告
本文最后更新于 2023-04-22,文中内容可能已过时。
MIT 6.1810 中第七个 lab 的 solution
Your job is to complete e1000_transmit() and e1000_recv(), both in kernel/e1000.c, so that the driver can transmit and receive packets. You are done when make grade says your solution passes all the tests.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| int
e1000_transmit(struct mbuf *m)
{
uint32 index = regs[E1000_TDT];
acquire(&e1000_lock);
if((tx_ring[index].status & E1000_TXD_STAT_DD) != E1000_TXD_STAT_DD){
release(&e1000_lock);
return -1;
}
if(tx_mbufs[index]) mbuffree(tx_mbufs[index]);
tx_ring[index].addr = (uint64)m->head;
tx_ring[index].length = m->len;
tx_ring[index].cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;
tx_mbufs[index] = m;
regs[E1000_TDT] = (index + 1) % TX_RING_SIZE;
release(&e1000_lock);
return 0;
}
static void
e1000_recv(void)
{
while(1){
uint32 index = (regs[E1000_RDT] + 1) % RX_RING_SIZE;
if((rx_ring[index].status & E1000_RXD_STAT_DD) != E1000_RXD_STAT_DD)
break;
rx_mbufs[index]->len = rx_ring[index].length;
net_rx(rx_mbufs[index]);
rx_mbufs[index] = mbufalloc(0);
rx_ring[index].addr = (uint64)rx_mbufs[index]->head;
rx_ring[index].status = 0;
regs[E1000_RDT] = index;
}
}
|