Skip to content

Commit

Permalink
Enable queuing multiple packets on W5500 and W6100
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Oct 19, 2024
1 parent 304b3f7 commit ed9814d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 20 deletions.
33 changes: 23 additions & 10 deletions lwip/netif/w5500if.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ distribution.
#include <ogc/exi.h>
#include <ogc/irq.h>
#include <ogc/lwp.h>
#include <ogc/semaphore.h>
#include <string.h>
#include "lwip/debug.h"
#include "lwip/err.h"
#include "lwip/mem.h"
Expand Down Expand Up @@ -314,8 +314,9 @@ enum {
struct w5500if {
s32 chan;
s32 dev;
s32 txQueued;
u16 txQueue[10];
lwpq_t unlockQueue;
sem_t txSemaphore;
struct eth_addr *ethaddr;
};

Expand Down Expand Up @@ -469,7 +470,16 @@ static s32 ExiHandler(s32 chan, s32 dev)

if (ir & W5500_Sn_IR_SENDOK) {
W5500_WriteReg(chan, W5500_S0_IR, W5500_Sn_IR_SENDOK);
LWP_SemPost(w5500if->txSemaphore);

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]);
W5500_WriteReg(chan, W5500_S0_CR, W5500_Sn_CR_SEND);
}
}
}

if (ir & W5500_Sn_IR_RECV) {
Expand Down Expand Up @@ -558,6 +568,8 @@ static bool W5500_Init(s32 chan, s32 dev, struct w5500if *w5500if)

w5500if->chan = chan;
w5500if->dev = dev;
w5500if->txQueued = 0;
w5500if->txQueue[0] = 0;

err |= !W5500_Reset(chan);

Expand Down Expand Up @@ -623,7 +635,7 @@ static err_t w5500_output(struct netif *netif, struct pbuf *p)
return ERR_CONN;
}

if (LWP_SemTimedWait(w5500if->txSemaphore, &(struct timespec){2, 500000000})) {
if (w5500if->txQueued < 0 || w5500if->txQueued >= 10) {
IRQ_Restore(level);
return ERR_IF;
}
Expand All @@ -632,16 +644,19 @@ static err_t w5500_output(struct netif *netif, struct pbuf *p)
LWP_ThreadSleep(w5500if->unlockQueue);
IRQ_Restore(level);

u16 wr;
W5500_ReadReg16(chan, W5500_S0_TX_WR, &wr);
u16 wr = w5500if->txQueue[w5500if->txQueued ? w5500if->txQueued - 1 : 0];

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

W5500_WriteReg16(chan, W5500_S0_TX_WR, wr);
W5500_WriteReg(chan, W5500_S0_CR, W5500_Sn_CR_SEND);
w5500if->txQueue[w5500if->txQueued++] = wr;

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

EXI_Unlock(chan);
return ERR_OK;
Expand Down Expand Up @@ -670,7 +685,6 @@ err_t w5500if_init(struct netif *netif)
netif->flags = NETIF_FLAG_BROADCAST;

LWP_InitQueue(&w5500if->unlockQueue);
LWP_SemInit(&w5500if->txSemaphore, 1, 1);

w5500if->ethaddr = (struct eth_addr *)netif->hwaddr;
w5500_netif = netif;
Expand All @@ -695,7 +709,6 @@ err_t w5500if_init(struct netif *netif)
}
}

LWP_SemDestroy(w5500if->txSemaphore);
LWP_CloseQueue(w5500if->unlockQueue);

mem_free(w5500if);
Expand Down
33 changes: 23 additions & 10 deletions lwip/netif/w6100if.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ distribution.
#include <ogc/exi.h>
#include <ogc/irq.h>
#include <ogc/lwp.h>
#include <ogc/semaphore.h>
#include <string.h>
#include "lwip/debug.h"
#include "lwip/err.h"
#include "lwip/mem.h"
Expand Down Expand Up @@ -673,8 +673,9 @@ enum {
struct w6100if {
s32 chan;
s32 dev;
s32 txQueued;
u16 txQueue[10];
lwpq_t unlockQueue;
sem_t txSemaphore;
struct eth_addr *ethaddr;
};

Expand Down Expand Up @@ -827,7 +828,16 @@ static s32 ExiHandler(s32 chan, s32 dev)

if (ir & W6100_Sn_IR_SENDOK) {
W6100_WriteReg(chan, W6100_S0_IRCLR, W6100_Sn_IRCLR_SENDOK);
LWP_SemPost(w6100if->txSemaphore);

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]);
W6100_WriteReg(chan, W6100_S0_CR, W6100_Sn_CR_SEND);
}
}
}

if (ir & W6100_Sn_IR_RECV) {
Expand Down Expand Up @@ -918,6 +928,8 @@ static bool W6100_Init(s32 chan, s32 dev, struct w6100if *w6100if)

w6100if->chan = chan;
w6100if->dev = dev;
w6100if->txQueued = 0;
w6100if->txQueue[0] = 0;

err |= !W6100_Reset(chan);

Expand Down Expand Up @@ -985,7 +997,7 @@ static err_t w6100_output(struct netif *netif, struct pbuf *p)
return ERR_CONN;
}

if (LWP_SemTimedWait(w6100if->txSemaphore, &(struct timespec){2, 500000000})) {
if (w6100if->txQueued < 0 || w6100if->txQueued >= 10) {
IRQ_Restore(level);
return ERR_IF;
}
Expand All @@ -994,16 +1006,19 @@ static err_t w6100_output(struct netif *netif, struct pbuf *p)
LWP_ThreadSleep(w6100if->unlockQueue);
IRQ_Restore(level);

u16 wr;
W6100_ReadReg16(chan, W6100_S0_TX_WR, &wr);
u16 wr = w6100if->txQueue[w6100if->txQueued ? w6100if->txQueued - 1 : 0];

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

W6100_WriteReg16(chan, W6100_S0_TX_WR, wr);
W6100_WriteReg(chan, W6100_S0_CR, W6100_Sn_CR_SEND);
w6100if->txQueue[w6100if->txQueued++] = wr;

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

EXI_Unlock(chan);
return ERR_OK;
Expand Down Expand Up @@ -1032,7 +1047,6 @@ err_t w6100if_init(struct netif *netif)
netif->flags = NETIF_FLAG_BROADCAST;

LWP_InitQueue(&w6100if->unlockQueue);
LWP_SemInit(&w6100if->txSemaphore, 1, 1);

w6100if->ethaddr = (struct eth_addr *)netif->hwaddr;
w6100_netif = netif;
Expand All @@ -1057,7 +1071,6 @@ err_t w6100if_init(struct netif *netif)
}
}

LWP_SemDestroy(w6100if->txSemaphore);
LWP_CloseQueue(w6100if->unlockQueue);

mem_free(w6100if);
Expand Down

0 comments on commit ed9814d

Please sign in to comment.