Rename mip_rxcb to mip_qwrite, add mip_qread and enforce rx() for drivers

This commit is contained in:
Sergio R. Caprile 2023-01-03 19:33:26 -03:00
parent 042465387f
commit b259bdeddd
10 changed files with 59 additions and 34 deletions

View File

@ -15,7 +15,7 @@ static void blink_cb(void *arg) { // Blink periodically
}
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
mip_rxcb((void *) buf, len, s_ifp);
mip_qwrite((void *) buf, len, s_ifp);
// MG_INFO(("RECV %hu", len));
// mg_hexdump(buf, len);
tud_network_recv_renew();
@ -55,7 +55,7 @@ int main(void) {
mg_mgr_init(&mgr); // and attach it to the MIP interface
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
struct mip_driver driver = {.tx = usb_tx, .up = usb_up};
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),

View File

@ -25,7 +25,7 @@ void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
}
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
mip_rxcb((void *) buf, len, s_ifp);
mip_qwrite((void *) buf, len, s_ifp);
// MG_INFO(("RECV %hu", len));
// mg_hexdump(buf, len);
tud_network_recv_renew();
@ -84,7 +84,7 @@ int main(void) {
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
MG_INFO(("Init TCP/IP stack ..."));
struct mip_driver driver = {.tx = usb_tx, .up = usb_up};
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),

View File

@ -25,7 +25,7 @@ void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
}
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
mip_rxcb((void *) buf, len, s_ifp);
mip_qwrite((void *) buf, len, s_ifp);
// MG_INFO(("RECV %hu", len));
// mg_hexdump(buf, len);
tud_network_recv_renew();
@ -84,7 +84,7 @@ int main(void) {
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
MG_INFO(("Init TCP/IP stack ..."));
struct mip_driver driver = {.tx = usb_tx, .up = usb_up};
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),

View File

@ -147,6 +147,7 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
((uint32_t) ifp->mac[2] << 16) |
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@ -191,7 +192,7 @@ void ETH_IRQHandler(void) {
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
// ETH->DMASR);
mip_rxcb(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
}
s_rxdesc[s_rxno][0] = BIT(31);
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
@ -202,5 +203,5 @@ void ETH_IRQHandler(void) {
}
struct mip_driver mip_driver_stm32 = {
mip_driver_stm32_init, mip_driver_stm32_tx, NULL, mip_driver_stm32_up};
mip_driver_stm32_init, mip_driver_stm32_tx, mip_driver_rx, mip_driver_stm32_up};
#endif

View File

@ -173,6 +173,7 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
// NOTE(scaprile) There are 3 additional slots for filtering, disabled by
// default. This also applies to the STM32 driver (at least for F7)
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@ -219,7 +220,7 @@ void EMAC0_IRQHandler(void) {
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
// EMAC->EMACDMARIS);
mip_rxcb(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
}
s_rxdesc[s_rxno][0] = BIT(31);
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
@ -230,5 +231,5 @@ void EMAC0_IRQHandler(void) {
}
struct mip_driver mip_driver_tm4c = {mip_driver_tm4c_init, mip_driver_tm4c_tx,
NULL, mip_driver_tm4c_up};
mip_driver_rx, mip_driver_tm4c_up};
#endif

View File

@ -452,11 +452,11 @@ static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
while (p + 1 < end && p[0] != 255) { // Parse options
if (p[0] == 53 && p[1] == 1 && p + 2 < end) { // Message type
op = p[2];
}
}
p += p[1] + 2;
}
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
uint8_t opts[] = {
53, 1, msg, // Message type
1, 4, 0, 0, 0, 0, // Subnet mask
@ -815,10 +815,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
}
// Read data from the network
size_t len = ifp->queue.len > 0
? q_read(&ifp->queue, (void *) ifp->rx.ptr)
: ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
qp_mark(QP_FRAMEPOPPED, (int) q_space(&ifp->queue));
size_t len = ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
mip_rx(ifp, (void *) ifp->rx.ptr, len);
qp_mark(QP_FRAMEDONE, (int) q_space(&ifp->queue));
@ -849,7 +846,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
// This function executes in interrupt context, thus it should copy data
// somewhere fast. Note that newlib's malloc is not thread safe, thus use
// our lock-free queue with preallocated buffer to copy data and return asap
void mip_rxcb(void *buf, size_t len, struct mip_if *ifp) {
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
if (q_write(&ifp->queue, buf, len)) {
qp_mark(QP_FRAMEPUSHED, (int) q_space(&ifp->queue));
} else {
@ -859,6 +856,17 @@ void mip_rxcb(void *buf, size_t len, struct mip_if *ifp) {
}
}
size_t mip_qread(void *buf, struct mip_if *ifp) {
size_t len = q_read(&ifp->queue, buf);
qp_mark(QP_FRAMEPOPPED, (int) q_space(&ifp->queue));
return len;
}
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp) {
return mip_qread((void *) ifp->rx.ptr, ifp);
(void) len, (void) buf;
}
void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
if (ifp->driver->init && !ifp->driver->init(ifp)) {
MG_ERROR(("driver init failed"));
@ -866,7 +874,6 @@ void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
size_t maxpktsize = 1540;
ifp->rx.ptr = (char *) calloc(1, maxpktsize), ifp->rx.len = maxpktsize;
ifp->tx.ptr = (char *) calloc(1, maxpktsize), ifp->tx.len = maxpktsize;
if (ifp->driver->rx == NULL && ifp->queue.len == 0) ifp->queue.len = 8192;
if (ifp->queue.len) ifp->queue.buf = (uint8_t *) calloc(1, ifp->queue.len);
ifp->timer_1000ms = mg_millis();
arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12);

View File

@ -52,7 +52,10 @@ struct mip_if {
void mip_init(struct mg_mgr *, struct mip_if *);
void mip_free(struct mip_if *);
void mip_rxcb(void *buf, size_t len, struct mip_if *ifp);
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp);
size_t mip_qread(void *buf, struct mip_if *ifp);
// conveniency rx function for IRQ-driven drivers
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp);
extern struct mip_driver mip_driver_stm32;
extern struct mip_driver mip_driver_w5500;

View File

@ -6074,6 +6074,7 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
((uint32_t) ifp->mac[2] << 16) |
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@ -6118,7 +6119,7 @@ void ETH_IRQHandler(void) {
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
// ETH->DMASR);
mip_rxcb(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
}
s_rxdesc[s_rxno][0] = BIT(31);
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
@ -6129,7 +6130,7 @@ void ETH_IRQHandler(void) {
}
struct mip_driver mip_driver_stm32 = {
mip_driver_stm32_init, mip_driver_stm32_tx, NULL, mip_driver_stm32_up};
mip_driver_stm32_init, mip_driver_stm32_tx, mip_driver_rx, mip_driver_stm32_up};
#endif
#ifdef MG_ENABLE_LINES
@ -6310,6 +6311,7 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
// NOTE(scaprile) There are 3 additional slots for filtering, disabled by
// default. This also applies to the STM32 driver (at least for F7)
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@ -6356,7 +6358,7 @@ void EMAC0_IRQHandler(void) {
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
// EMAC->EMACDMARIS);
mip_rxcb(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
}
s_rxdesc[s_rxno][0] = BIT(31);
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
@ -6367,7 +6369,7 @@ void EMAC0_IRQHandler(void) {
}
struct mip_driver mip_driver_tm4c = {mip_driver_tm4c_init, mip_driver_tm4c_tx,
NULL, mip_driver_tm4c_up};
mip_driver_rx, mip_driver_tm4c_up};
#endif
#ifdef MG_ENABLE_LINES
@ -6920,11 +6922,11 @@ static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
while (p + 1 < end && p[0] != 255) { // Parse options
if (p[0] == 53 && p[1] == 1 && p + 2 < end) { // Message type
op = p[2];
}
}
p += p[1] + 2;
}
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
uint8_t opts[] = {
53, 1, msg, // Message type
1, 4, 0, 0, 0, 0, // Subnet mask
@ -7283,10 +7285,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
}
// Read data from the network
size_t len = ifp->queue.len > 0
? q_read(&ifp->queue, (void *) ifp->rx.ptr)
: ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
qp_mark(QP_FRAMEPOPPED, (int) q_space(&ifp->queue));
size_t len = ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
mip_rx(ifp, (void *) ifp->rx.ptr, len);
qp_mark(QP_FRAMEDONE, (int) q_space(&ifp->queue));
@ -7317,7 +7316,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
// This function executes in interrupt context, thus it should copy data
// somewhere fast. Note that newlib's malloc is not thread safe, thus use
// our lock-free queue with preallocated buffer to copy data and return asap
void mip_rxcb(void *buf, size_t len, struct mip_if *ifp) {
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
if (q_write(&ifp->queue, buf, len)) {
qp_mark(QP_FRAMEPUSHED, (int) q_space(&ifp->queue));
} else {
@ -7327,6 +7326,17 @@ void mip_rxcb(void *buf, size_t len, struct mip_if *ifp) {
}
}
size_t mip_qread(void *buf, struct mip_if *ifp) {
size_t len = q_read(&ifp->queue, buf);
qp_mark(QP_FRAMEPOPPED, (int) q_space(&ifp->queue));
return len;
}
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp) {
return mip_qread((void *) ifp->rx.ptr, ifp);
(void) len, (void) buf;
}
void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
if (ifp->driver->init && !ifp->driver->init(ifp)) {
MG_ERROR(("driver init failed"));
@ -7334,7 +7344,6 @@ void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
size_t maxpktsize = 1540;
ifp->rx.ptr = (char *) calloc(1, maxpktsize), ifp->rx.len = maxpktsize;
ifp->tx.ptr = (char *) calloc(1, maxpktsize), ifp->tx.len = maxpktsize;
if (ifp->driver->rx == NULL && ifp->queue.len == 0) ifp->queue.len = 8192;
if (ifp->queue.len) ifp->queue.buf = (uint8_t *) calloc(1, ifp->queue.len);
ifp->timer_1000ms = mg_millis();
arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12);

View File

@ -1472,7 +1472,10 @@ struct mip_if {
void mip_init(struct mg_mgr *, struct mip_if *);
void mip_free(struct mip_if *);
void mip_rxcb(void *buf, size_t len, struct mip_if *ifp);
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp);
size_t mip_qread(void *buf, struct mip_if *ifp);
// conveniency rx function for IRQ-driven drivers
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp);
extern struct mip_driver mip_driver_stm32;
extern struct mip_driver mip_driver_w5500;

View File

@ -5,6 +5,7 @@
#define MG_ENABLE_LINES 1
#include <assert.h>
#include <sys/socket.h>
#ifndef __OpenBSD__
#include <linux/if.h>
#include <linux/if_tun.h>