Skip to content

Commit

Permalink
Improve transmit buffer utilization
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Oct 20, 2024
1 parent ed9814d commit 0897b53
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
26 changes: 16 additions & 10 deletions lwip/netif/w5500if.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ static vu32 *const _piReg = (u32 *)0xCC003000;
#define W5500_TXBUF_S(n, addr) (W5500_BSB(n * 4 + 2) | W5500_ADDR(addr))
#define W5500_RXBUF_S(n, addr) (W5500_BSB(n * 4 + 3) | W5500_ADDR(addr))

#define W5500_INIT_S0_RXBUF_SIZE (16)
#define W5500_INIT_S0_TXBUF_SIZE (16)

enum {
Sn_MR = 0x00, // Socket n Mode Register
Sn_CR, // Socket n Command Register
Expand Down Expand Up @@ -311,11 +314,14 @@ enum {
#define W5500_Sn_IMR_DISCON (1 << 1) // DISCONNECTED Interrupt Mask
#define W5500_Sn_IMR_CON (1 << 0) // CONNECTED Interrupt Mask

#define W5500_TX_BUFSIZE (W5500_INIT_S0_TXBUF_SIZE * 1024)
#define W5500_TX_QUEUELEN ((W5500_TX_BUFSIZE * 27) / (1536 * 20))

struct w5500if {
s32 chan;
s32 dev;
s32 txQueued;
u16 txQueue[10];
u16 txQueue[W5500_TX_QUEUELEN + 1];
lwpq_t unlockQueue;
struct eth_addr *ethaddr;
};
Expand Down Expand Up @@ -472,11 +478,10 @@ static s32 ExiHandler(s32 chan, s32 dev)
W5500_WriteReg(chan, W5500_S0_IR, W5500_Sn_IR_SENDOK);

if (w5500if->txQueued) {
w5500if->txQueued--;
memmove(&w5500if->txQueue[0], &w5500if->txQueue[1], w5500if->txQueued * sizeof(u16));

if (w5500if->txQueued) {
W5500_WriteReg16(chan, W5500_S0_TX_WR, w5500if->txQueue[0]);
if (--w5500if->txQueued) {
W5500_WriteReg16(chan, W5500_S0_TX_WR, w5500if->txQueue[1]);
W5500_WriteReg(chan, W5500_S0_CR, W5500_Sn_CR_SEND);
}
}
Expand Down Expand Up @@ -581,8 +586,8 @@ static bool W5500_Init(s32 chan, s32 dev, struct w5500if *w5500if)
err |= !W5500_WriteReg(chan, W5500_SHAR4, w5500if->ethaddr->addr[4]);
err |= !W5500_WriteReg(chan, W5500_SHAR5, w5500if->ethaddr->addr[5]);

err |= !W5500_WriteReg(chan, W5500_S0_RXBUF_SIZE, 16);
err |= !W5500_WriteReg(chan, W5500_S0_TXBUF_SIZE, 16);
err |= !W5500_WriteReg(chan, W5500_S0_RXBUF_SIZE, W5500_INIT_S0_RXBUF_SIZE);
err |= !W5500_WriteReg(chan, W5500_S0_TXBUF_SIZE, W5500_INIT_S0_TXBUF_SIZE);

for (int n = 1; n < 8; n++) {
err |= !W5500_WriteReg(chan, W5500_REG_S(n, Sn_RXBUF_SIZE), 0);
Expand Down Expand Up @@ -635,7 +640,8 @@ static err_t w5500_output(struct netif *netif, struct pbuf *p)
return ERR_CONN;
}

if (w5500if->txQueued < 0 || w5500if->txQueued >= 10) {
if (w5500if->txQueued < 0 || w5500if->txQueued >= W5500_TX_QUEUELEN ||
(u16)(w5500if->txQueue[w5500if->txQueued] - w5500if->txQueue[0]) > (W5500_TX_BUFSIZE - p->tot_len)) {
IRQ_Restore(level);
return ERR_IF;
}
Expand All @@ -644,17 +650,17 @@ static err_t w5500_output(struct netif *netif, struct pbuf *p)
LWP_ThreadSleep(w5500if->unlockQueue);
IRQ_Restore(level);

u16 wr = w5500if->txQueue[w5500if->txQueued ? w5500if->txQueued - 1 : 0];
u16 wr = w5500if->txQueue[w5500if->txQueued];

for (struct pbuf *q = p; q; q = q->next) {
W5500_WriteCmd(chan, W5500_TXBUF_S(0, wr), q->payload, q->len);
wr += q->len;
}

w5500if->txQueue[w5500if->txQueued++] = wr;
w5500if->txQueue[++w5500if->txQueued] = wr;

if (w5500if->txQueued == 1) {
W5500_WriteReg16(chan, W5500_S0_TX_WR, w5500if->txQueue[0]);
W5500_WriteReg16(chan, W5500_S0_TX_WR, w5500if->txQueue[1]);
W5500_WriteReg(chan, W5500_S0_CR, W5500_Sn_CR_SEND);
}

Expand Down
26 changes: 16 additions & 10 deletions lwip/netif/w6100if.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ static vu32 *const _piReg = (u32 *)0xCC003000;
#define W6100_TXBUF_S(n, addr) (W6100_BSB(n * 4 + 2) | W6100_ADDR(addr))
#define W6100_RXBUF_S(n, addr) (W6100_BSB(n * 4 + 3) | W6100_ADDR(addr))

#define W6100_INIT_S0_TX_BSR (16)
#define W6100_INIT_S0_RX_BSR (16)

enum {
Sn_MR = 0x0000, // Socket n Mode Register
Sn_PSR = 0x0004, // Socket n Prefer Source IPv6 Address Register
Expand Down Expand Up @@ -670,11 +673,14 @@ enum {
#define W6100_Sn_MR2_DHAM (1 << 1) // Destination Hardware Address Mode
#define W6100_Sn_MR2_FARP (1 << 0) // Force ARP

#define W6100_TX_BUFSIZE (W6100_INIT_S0_TX_BSR * 1024)
#define W6100_TX_QUEUELEN ((W6100_TX_BUFSIZE * 27) / (1536 * 20))

struct w6100if {
s32 chan;
s32 dev;
s32 txQueued;
u16 txQueue[10];
u16 txQueue[W6100_TX_QUEUELEN + 1];
lwpq_t unlockQueue;
struct eth_addr *ethaddr;
};
Expand Down Expand Up @@ -830,11 +836,10 @@ static s32 ExiHandler(s32 chan, s32 dev)
W6100_WriteReg(chan, W6100_S0_IRCLR, W6100_Sn_IRCLR_SENDOK);

if (w6100if->txQueued) {
w6100if->txQueued--;
memmove(&w6100if->txQueue[0], &w6100if->txQueue[1], w6100if->txQueued * sizeof(u16));

if (w6100if->txQueued) {
W6100_WriteReg16(chan, W6100_S0_TX_WR, w6100if->txQueue[0]);
if (--w6100if->txQueued) {
W6100_WriteReg16(chan, W6100_S0_TX_WR, w6100if->txQueue[1]);
W6100_WriteReg(chan, W6100_S0_CR, W6100_Sn_CR_SEND);
}
}
Expand Down Expand Up @@ -943,8 +948,8 @@ static bool W6100_Init(s32 chan, s32 dev, struct w6100if *w6100if)
err |= !W6100_WriteReg(chan, W6100_SHAR5, w6100if->ethaddr->addr[5]);
err |= !W6100_WriteReg(chan, W6100_NETLCKR, W6100_NETLCKR_LOCK);

err |= !W6100_WriteReg(chan, W6100_S0_TX_BSR, 16);
err |= !W6100_WriteReg(chan, W6100_S0_RX_BSR, 16);
err |= !W6100_WriteReg(chan, W6100_S0_TX_BSR, W6100_INIT_S0_TX_BSR);
err |= !W6100_WriteReg(chan, W6100_S0_RX_BSR, W6100_INIT_S0_RX_BSR);

for (int n = 1; n < 8; n++) {
err |= !W6100_WriteReg(chan, W6100_REG_S(n, Sn_TX_BSR), 0);
Expand Down Expand Up @@ -997,7 +1002,8 @@ static err_t w6100_output(struct netif *netif, struct pbuf *p)
return ERR_CONN;
}

if (w6100if->txQueued < 0 || w6100if->txQueued >= 10) {
if (w6100if->txQueued < 0 || w6100if->txQueued >= W6100_TX_QUEUELEN ||
(u16)(w6100if->txQueue[w6100if->txQueued] - w6100if->txQueue[0]) > (W6100_TX_BUFSIZE - p->tot_len)) {
IRQ_Restore(level);
return ERR_IF;
}
Expand All @@ -1006,17 +1012,17 @@ static err_t w6100_output(struct netif *netif, struct pbuf *p)
LWP_ThreadSleep(w6100if->unlockQueue);
IRQ_Restore(level);

u16 wr = w6100if->txQueue[w6100if->txQueued ? w6100if->txQueued - 1 : 0];
u16 wr = w6100if->txQueue[w6100if->txQueued];

for (struct pbuf *q = p; q; q = q->next) {
W6100_WriteCmd(chan, W6100_TXBUF_S(0, wr), q->payload, q->len);
wr += q->len;
}

w6100if->txQueue[w6100if->txQueued++] = wr;
w6100if->txQueue[++w6100if->txQueued] = wr;

if (w6100if->txQueued == 1) {
W6100_WriteReg16(chan, W6100_S0_TX_WR, w6100if->txQueue[0]);
W6100_WriteReg16(chan, W6100_S0_TX_WR, w6100if->txQueue[1]);
W6100_WriteReg(chan, W6100_S0_CR, W6100_Sn_CR_SEND);
}

Expand Down

0 comments on commit 0897b53

Please sign in to comment.