drivers: ethernet: Remove ugly usage of a goto in enc*j* drivers
This is a working code, but it's harder to read. And for some reason makes some semantic patches of coccinelle running forever. So refactoring it. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
c0bcfd2a77
commit
f818ec2d8d
2 changed files with 91 additions and 88 deletions
|
@ -510,11 +510,96 @@ static int eth_enc28j60_tx(const struct device *dev, struct net_pkt *pkt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
|
static void enc28j60_read_packet(const struct device *dev, uint16_t *vlan_tag,
|
||||||
|
uint16_t frm_len)
|
||||||
{
|
{
|
||||||
const struct eth_enc28j60_config *config = dev->config;
|
const struct eth_enc28j60_config *config = dev->config;
|
||||||
struct eth_enc28j60_runtime *context = dev->data;
|
struct eth_enc28j60_runtime *context = dev->data;
|
||||||
|
struct net_buf *pkt_buf;
|
||||||
|
struct net_pkt *pkt;
|
||||||
uint16_t lengthfr;
|
uint16_t lengthfr;
|
||||||
|
uint8_t dummy[4];
|
||||||
|
|
||||||
|
/* Get the frame from the buffer */
|
||||||
|
pkt = net_pkt_rx_alloc_with_buffer(get_iface(context, *vlan_tag), frm_len,
|
||||||
|
AF_UNSPEC, 0, K_MSEC(config->timeout));
|
||||||
|
if (!pkt) {
|
||||||
|
LOG_ERR("Could not allocate rx buffer");
|
||||||
|
eth_stats_update_errors_rx(get_iface(context, *vlan_tag));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt_buf = pkt->buffer;
|
||||||
|
lengthfr = frm_len;
|
||||||
|
|
||||||
|
do {
|
||||||
|
size_t frag_len;
|
||||||
|
uint8_t *data_ptr;
|
||||||
|
size_t spi_frame_len;
|
||||||
|
|
||||||
|
data_ptr = pkt_buf->data;
|
||||||
|
|
||||||
|
/* Review the space available for the new frag */
|
||||||
|
frag_len = net_buf_tailroom(pkt_buf);
|
||||||
|
|
||||||
|
if (frm_len > frag_len) {
|
||||||
|
spi_frame_len = frag_len;
|
||||||
|
} else {
|
||||||
|
spi_frame_len = frm_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
eth_enc28j60_read_mem(dev, data_ptr, spi_frame_len);
|
||||||
|
|
||||||
|
net_buf_add(pkt_buf, spi_frame_len);
|
||||||
|
|
||||||
|
/* One fragment has been written via SPI */
|
||||||
|
frm_len -= spi_frame_len;
|
||||||
|
pkt_buf = pkt_buf->frags;
|
||||||
|
} while (frm_len > 0);
|
||||||
|
|
||||||
|
/* Let's pop the useless CRC */
|
||||||
|
eth_enc28j60_read_mem(dev, dummy, 4);
|
||||||
|
|
||||||
|
/* Pops one padding byte from spi circular buffer
|
||||||
|
* introduced by the device when the frame length is odd
|
||||||
|
*/
|
||||||
|
if (lengthfr & 0x01) {
|
||||||
|
eth_enc28j60_read_mem(dev, dummy, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_VLAN)
|
||||||
|
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
|
||||||
|
|
||||||
|
if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
|
||||||
|
struct net_eth_vlan_hdr *hdr_vlan =
|
||||||
|
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
|
||||||
|
|
||||||
|
net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
|
||||||
|
*vlan_tag = net_pkt_vlan_tag(pkt);
|
||||||
|
|
||||||
|
#if CONFIG_NET_TC_RX_COUNT > 1
|
||||||
|
enum net_priority prio;
|
||||||
|
|
||||||
|
prio = net_vlan2priority(net_pkt_vlan_priority(pkt));
|
||||||
|
net_pkt_set_priority(pkt, prio);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
net_pkt_set_iface(pkt, context->iface);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_NET_VLAN */
|
||||||
|
net_pkt_set_iface(pkt, context->iface);
|
||||||
|
#endif /* CONFIG_NET_VLAN */
|
||||||
|
|
||||||
|
/* Feed buffer frame to IP stack */
|
||||||
|
LOG_DBG("Received packet of length %u", lengthfr);
|
||||||
|
if (net_recv_data(net_pkt_iface(pkt), pkt) < 0) {
|
||||||
|
net_pkt_unref(pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
|
||||||
|
{
|
||||||
|
struct eth_enc28j60_runtime *context = dev->data;
|
||||||
uint8_t counter;
|
uint8_t counter;
|
||||||
|
|
||||||
/* Errata 6. The Receive Packet Pending Interrupt Flag (EIR.PKTIF)
|
/* Errata 6. The Receive Packet Pending Interrupt Flag (EIR.PKTIF)
|
||||||
|
@ -530,10 +615,8 @@ static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
|
||||||
k_sem_take(&context->tx_rx_sem, K_FOREVER);
|
k_sem_take(&context->tx_rx_sem, K_FOREVER);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
struct net_buf *pkt_buf = NULL;
|
|
||||||
uint16_t frm_len = 0U;
|
uint16_t frm_len = 0U;
|
||||||
uint8_t info[RSV_SIZE];
|
uint8_t info[RSV_SIZE];
|
||||||
struct net_pkt *pkt;
|
|
||||||
uint16_t next_packet;
|
uint16_t next_packet;
|
||||||
uint8_t rdptl = 0U;
|
uint8_t rdptl = 0U;
|
||||||
uint8_t rdpth = 0U;
|
uint8_t rdpth = 0U;
|
||||||
|
@ -565,85 +648,9 @@ static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
|
||||||
* minus CRC size at the end which is always present
|
* minus CRC size at the end which is always present
|
||||||
*/
|
*/
|
||||||
frm_len = sys_get_le16(info) - 4;
|
frm_len = sys_get_le16(info) - 4;
|
||||||
lengthfr = frm_len;
|
|
||||||
|
|
||||||
/* Get the frame from the buffer */
|
enc28j60_read_packet(dev, vlan_tag, frm_len);
|
||||||
pkt = net_pkt_rx_alloc_with_buffer(
|
|
||||||
get_iface(context, *vlan_tag), frm_len,
|
|
||||||
AF_UNSPEC, 0, K_MSEC(config->timeout));
|
|
||||||
if (!pkt) {
|
|
||||||
LOG_ERR("Could not allocate rx buffer");
|
|
||||||
eth_stats_update_errors_rx(get_iface(context,
|
|
||||||
*vlan_tag));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt_buf = pkt->buffer;
|
|
||||||
|
|
||||||
do {
|
|
||||||
size_t frag_len;
|
|
||||||
uint8_t *data_ptr;
|
|
||||||
size_t spi_frame_len;
|
|
||||||
|
|
||||||
data_ptr = pkt_buf->data;
|
|
||||||
|
|
||||||
/* Review the space available for the new frag */
|
|
||||||
frag_len = net_buf_tailroom(pkt_buf);
|
|
||||||
|
|
||||||
if (frm_len > frag_len) {
|
|
||||||
spi_frame_len = frag_len;
|
|
||||||
} else {
|
|
||||||
spi_frame_len = frm_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
eth_enc28j60_read_mem(dev, data_ptr, spi_frame_len);
|
|
||||||
|
|
||||||
net_buf_add(pkt_buf, spi_frame_len);
|
|
||||||
|
|
||||||
/* One fragment has been written via SPI */
|
|
||||||
frm_len -= spi_frame_len;
|
|
||||||
pkt_buf = pkt_buf->frags;
|
|
||||||
} while (frm_len > 0);
|
|
||||||
|
|
||||||
/* Let's pop the useless CRC */
|
|
||||||
eth_enc28j60_read_mem(dev, NULL, 4);
|
|
||||||
|
|
||||||
/* Pops one padding byte from spi circular buffer
|
|
||||||
* introduced by the device when the frame length is odd
|
|
||||||
*/
|
|
||||||
if (lengthfr & 0x01) {
|
|
||||||
eth_enc28j60_read_mem(dev, NULL, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_NET_VLAN)
|
|
||||||
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
|
|
||||||
|
|
||||||
if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
|
|
||||||
struct net_eth_vlan_hdr *hdr_vlan =
|
|
||||||
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
|
|
||||||
|
|
||||||
net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
|
|
||||||
*vlan_tag = net_pkt_vlan_tag(pkt);
|
|
||||||
|
|
||||||
#if CONFIG_NET_TC_RX_COUNT > 1
|
|
||||||
enum net_priority prio;
|
|
||||||
|
|
||||||
prio = net_vlan2priority(net_pkt_vlan_priority(pkt));
|
|
||||||
net_pkt_set_priority(pkt, prio);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
net_pkt_set_iface(pkt, context->iface);
|
|
||||||
}
|
|
||||||
#else /* CONFIG_NET_VLAN */
|
|
||||||
net_pkt_set_iface(pkt, context->iface);
|
|
||||||
#endif /* CONFIG_NET_VLAN */
|
|
||||||
|
|
||||||
/* Feed buffer frame to IP stack */
|
|
||||||
LOG_DBG("Received packet of length %u", lengthfr);
|
|
||||||
if (net_recv_data(net_pkt_iface(pkt), pkt) < 0) {
|
|
||||||
net_pkt_unref(pkt);
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
/* Free buffer memory and decrement rx counter */
|
/* Free buffer memory and decrement rx counter */
|
||||||
eth_enc28j60_set_bank(dev, ENC28J60_REG_ERXRDPTL);
|
eth_enc28j60_set_bank(dev, ENC28J60_REG_ERXRDPTL);
|
||||||
eth_enc28j60_write_reg(dev, ENC28J60_REG_ERXRDPTL,
|
eth_enc28j60_write_reg(dev, ENC28J60_REG_ERXRDPTL,
|
||||||
|
|
|
@ -467,10 +467,7 @@ static void enc424j600_rx_thread(const struct device *dev)
|
||||||
counter = (uint8_t)estat;
|
counter = (uint8_t)estat;
|
||||||
LOG_DBG("ESTAT: 0x%04x", estat);
|
LOG_DBG("ESTAT: 0x%04x", estat);
|
||||||
}
|
}
|
||||||
goto done;
|
} else if (eir & ENC424J600_EIR_LINKIF) {
|
||||||
}
|
|
||||||
|
|
||||||
if (eir & ENC424J600_EIR_LINKIF) {
|
|
||||||
enc424j600_clear_sfru(dev, ENC424J600_SFRX_EIRL,
|
enc424j600_clear_sfru(dev, ENC424J600_SFRX_EIRL,
|
||||||
ENC424J600_EIR_LINKIF);
|
ENC424J600_EIR_LINKIF);
|
||||||
if (estat & ENC424J600_ESTAT_PHYLNK) {
|
if (estat & ENC424J600_ESTAT_PHYLNK) {
|
||||||
|
@ -484,12 +481,11 @@ static void enc424j600_rx_thread(const struct device *dev)
|
||||||
net_eth_carrier_off(context->iface);
|
net_eth_carrier_off(context->iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto done;
|
} else {
|
||||||
|
LOG_ERR("Unknown Interrupt, EIR: 0x%04x", eir);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_ERR("Unknown Interrupt, EIR: 0x%04x", eir);
|
|
||||||
|
|
||||||
done:
|
|
||||||
enc424j600_set_sfru(dev, ENC424J600_SFR3_EIEL,
|
enc424j600_set_sfru(dev, ENC424J600_SFR3_EIEL,
|
||||||
ENC424J600_EIE_INTIE);
|
ENC424J600_EIE_INTIE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue