e1000: rewrite tx a bit
This commit is contained in:
parent
aabbde7877
commit
3f94c70293
@ -214,27 +214,32 @@ static int irq_handler(struct regs *r) {
|
|||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tx_full(struct e1000_nic * device, int tx_tail, int tx_head) {
|
||||||
|
if (tx_tail == tx_head) return 0;
|
||||||
|
if (device->tx_index == tx_head) return 1;
|
||||||
|
if (((device->tx_index + 1) & E1000_NUM_TX_DESC) == tx_head) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_packet(struct e1000_nic * device, uint8_t* payload, size_t payload_size) {
|
static void send_packet(struct e1000_nic * device, uint8_t* payload, size_t payload_size) {
|
||||||
spin_lock(device->tx_lock);
|
spin_lock(device->tx_lock);
|
||||||
int tx_tail = read_command(device, E1000_REG_TXDESCTAIL);
|
int tx_tail = read_command(device, E1000_REG_TXDESCTAIL);
|
||||||
int tx_head = read_command(device, E1000_REG_TXDESCHEAD);
|
int tx_head = read_command(device, E1000_REG_TXDESCHEAD);
|
||||||
|
|
||||||
if (tx_tail != tx_head) {
|
if (tx_full(device, tx_tail, tx_head)) {
|
||||||
/* Queue is not empty, make sure we don't fill it... */
|
int timeout = 1000;
|
||||||
if ((device->tx_index + 1) % E1000_NUM_TX_DESC == tx_head) {
|
do {
|
||||||
int timeout = 1000;
|
spin_unlock(device->tx_lock);
|
||||||
do {
|
delay_yield(10000);
|
||||||
spin_unlock(device->tx_lock);
|
timeout--;
|
||||||
delay_yield(10000);
|
if (timeout == 0) {
|
||||||
timeout--;
|
printf("e1000: wait for tx timed out, giving up\n");
|
||||||
if (timeout == 0) {
|
return;
|
||||||
printf("e1000: wait for tx timed out, giving up\n");
|
}
|
||||||
return;
|
spin_lock(device->tx_lock);
|
||||||
}
|
tx_tail = read_command(device, E1000_REG_TXDESCTAIL);
|
||||||
spin_lock(device->tx_lock);
|
tx_head = read_command(device, E1000_REG_TXDESCHEAD);
|
||||||
tx_head = read_command(device, E1000_REG_TXDESCHEAD);
|
} while (tx_full(device, tx_tail, tx_head));
|
||||||
} while ((device->tx_index + 1) % E1000_NUM_TX_DESC == tx_head);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(device->tx_virt[device->tx_index], payload, payload_size);
|
memcpy(device->tx_virt[device->tx_index], payload, payload_size);
|
||||||
@ -280,10 +285,18 @@ static void init_tx(struct e1000_nic * device) {
|
|||||||
|
|
||||||
device->tx_index = 0;
|
device->tx_index = 0;
|
||||||
|
|
||||||
write_command(device, E1000_REG_TCTRL,
|
uint32_t tctl = read_command(device, E1000_REG_TCTRL);
|
||||||
TCTL_EN |
|
|
||||||
TCTL_PSP |
|
/* Collision threshold */
|
||||||
read_command(device, E1000_REG_TCTRL));
|
tctl &= ~(0xFF << 4);
|
||||||
|
tctl |= (15 << 4);
|
||||||
|
|
||||||
|
/* Turn it on */
|
||||||
|
tctl |= TCTL_EN;
|
||||||
|
tctl |= TCTL_PSP;
|
||||||
|
tctl |= (1 << 24); /* retransmit on late collision */
|
||||||
|
|
||||||
|
write_command(device, E1000_REG_TCTRL, tctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
|
static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
|
||||||
@ -360,13 +373,22 @@ static ssize_t e1000_debug_func(fs_node_t * node, off_t offset, size_t size, uin
|
|||||||
struct e1000_nic * e1000_debug_nic = devices[i];
|
struct e1000_nic * e1000_debug_nic = devices[i];
|
||||||
uint32_t creg = read_command(e1000_debug_nic, E1000_REG_CTRL);
|
uint32_t creg = read_command(e1000_debug_nic, E1000_REG_CTRL);
|
||||||
uint32_t sreg = read_command(e1000_debug_nic, E1000_REG_STATUS);
|
uint32_t sreg = read_command(e1000_debug_nic, E1000_REG_STATUS);
|
||||||
|
int rx_head = read_command(e1000_debug_nic, E1000_REG_RXDESCHEAD);
|
||||||
|
int rx_tail = read_command(e1000_debug_nic, E1000_REG_RXDESCTAIL);
|
||||||
|
int tx_head = read_command(e1000_debug_nic, E1000_REG_TXDESCHEAD);
|
||||||
|
int tx_tail = read_command(e1000_debug_nic, E1000_REG_TXDESCTAIL);
|
||||||
out += snprintf(out, 4095,
|
out += snprintf(out, 4095,
|
||||||
"Device %d\n"
|
"Device %d\n"
|
||||||
"Ctrl reg:\t%#x\n"
|
"Ctrl reg:\t%#x\n"
|
||||||
"Status reg:\t%#x\n",
|
"Status reg:\t%#x\n"
|
||||||
|
"rx head/tail:\t%d %d\n"
|
||||||
|
"tx head/tail:\t%d %d\n",
|
||||||
i,
|
i,
|
||||||
creg,
|
creg,
|
||||||
sreg);
|
sreg,
|
||||||
|
rx_head, rx_tail,
|
||||||
|
tx_head, tx_tail
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _bsize = strlen(buf);
|
size_t _bsize = strlen(buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user