Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 52 additions & 12 deletions drivers/ethernet/eth_w5500.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@
struct net_buf *pkt_buf = NULL;
struct net_pkt *pkt;
struct w5500_runtime *ctx = dev->data;
const struct w5500_config *config = dev->config;

w5500_spi_read(dev, W5500_S0_RX_RSR, tmp, 2);
rx_buf_len = sys_get_be16(tmp);
Expand All @@ -231,8 +230,8 @@
w5500_readbuf(dev, off, header, 2);
rx_len = sys_get_be16(header) - 2;

pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, rx_len,
NET_AF_UNSPEC, 0, K_MSEC(config->timeout));
pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, rx_len, NET_AF_UNSPEC, 0,
K_MSEC(CONFIG_ETH_W5500_TIMEOUT));
if (!pkt) {
eth_stats_update_errors_rx(ctx->iface);
return;
Expand Down Expand Up @@ -279,21 +278,36 @@
{
uint8_t phycfgr;
struct w5500_runtime *ctx = dev->data;
enum phy_link_speed speed;

if (w5500_spi_read(dev, W5500_PHYCFGR, &phycfgr, 1) < 0) {
return;
}

if (phycfgr & 0x01) {
if (ctx->link_up != true) {
if (IS_BIT_SET(phycfgr, W5500_PHYCFGR_LNK_BIT)) {
if (ctx->state.is_up != true) {
LOG_INF("%s: Link up", dev->name);
ctx->link_up = true;
ctx->state.is_up = true;
net_eth_carrier_on(ctx->iface);
}

speed = IS_BIT_SET(phycfgr, W5500_PHYCFGR_SPD_BIT)
? (IS_BIT_SET(phycfgr, W5500_PHYCFGR_DPX_BIT) ? LINK_FULL_100BASE
: LINK_HALF_100BASE)

Check warning on line 296 in drivers/ethernet/eth_w5500.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested conditional operator into an independent statement.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZrcXAga9_-FphcXcG3Q&open=AZrcXAga9_-FphcXcG3Q&pullRequest=100331
: (IS_BIT_SET(phycfgr, W5500_PHYCFGR_DPX_BIT) ? LINK_FULL_10BASE
: LINK_HALF_10BASE);

Check warning on line 298 in drivers/ethernet/eth_w5500.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested conditional operator into an independent statement.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZrcXAga9_-FphcXcG3R&open=AZrcXAga9_-FphcXcG3R&pullRequest=100331

if (ctx->state.speed != speed) {
ctx->state.speed = speed;
LOG_INF("%s: Link speed %s Mb, %s duplex", dev->name,
PHY_LINK_IS_SPEED_100M(speed) ? "100" : "10",
PHY_LINK_IS_FULL_DUPLEX(speed) ? "full" : "half");
}
} else {
if (ctx->link_up != false) {
if (ctx->state.is_up != false) {
LOG_INF("%s: Link down", dev->name);
ctx->link_up = false;
ctx->state.is_up = false;
ctx->state.speed = 0;
net_eth_carrier_off(ctx->iface);
}
}
Expand All @@ -315,7 +329,7 @@

if (res == 0) {
/* semaphore taken, update link status and receive packets */
if (ctx->link_up != true) {
if (ctx->state.is_up != true) {
w5500_update_link_status(dev);
}

Expand Down Expand Up @@ -459,15 +473,38 @@
return 0;
}

static const struct device *w5500_get_phy(const struct device *dev)
{
const struct w5500_config *config = dev->config;

return config->phy_dev;
}

static const struct ethernet_api w5500_api_funcs = {
.iface_api.init = w5500_iface_init,
.get_capabilities = w5500_get_capabilities,
.set_config = w5500_set_config,
.start = w5500_hw_start,
.stop = w5500_hw_stop,
.get_phy = w5500_get_phy,
.send = w5500_tx,
};

static int w5500_get_link_state(const struct device *dev,
struct phy_link_state *state)
{
struct w5500_runtime *const data = dev->data;

state->speed = data->state.speed;
state->is_up = data->state.is_up;

return 0;
}

static DEVICE_API(ethphy, w5500_phy_driver_api) = {
.get_link = w5500_get_link_state,
};

static int w5500_soft_reset(const struct device *dev)
{
int ret;
Expand Down Expand Up @@ -531,8 +568,6 @@
const struct w5500_config *config = dev->config;
struct w5500_runtime *ctx = dev->data;

ctx->link_up = false;

if (!spi_is_ready_dt(&config->spi)) {
LOG_ERR("SPI master port %s not ready", config->spi.bus->name);
return -EINVAL;
Expand Down Expand Up @@ -600,6 +635,8 @@
return 0;
}

DEVICE_DECLARE(eth_w5500_phy_0);

static struct w5500_runtime w5500_0_runtime = {
#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))
.mac_addr = DT_INST_PROP(0, local_mac_address),
Expand All @@ -614,10 +651,13 @@
.spi = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8)),
.interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios),
.reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }),
.timeout = CONFIG_ETH_W5500_TIMEOUT,
.phy_dev = DEVICE_GET(eth_w5500_phy_0),
};

ETH_NET_DEVICE_DT_INST_DEFINE(0,
w5500_init, NULL,
&w5500_0_runtime, &w5500_0_config,
CONFIG_ETH_INIT_PRIORITY, &w5500_api_funcs, NET_ETH_MTU);

DEVICE_DEFINE(eth_w5500_phy_0, DEVICE_DT_NAME(DT_DRV_INST(0)) "_phy", NULL, NULL, &w5500_0_runtime,
&w5500_0_config, POST_KERNEL, CONFIG_ETH_INIT_PRIORITY, &w5500_phy_driver_api);
9 changes: 7 additions & 2 deletions drivers/ethernet/eth_w5500_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/net/phy.h>

#ifndef _W5500_
#define _W5500_
Expand All @@ -27,6 +28,10 @@
#define W5500_COMMON_REGS_LEN 0x0040
#define W5500_PHYCFGR 0x002E /* PHY Configuration register */

#define W5500_PHYCFGR_LNK_BIT 1 /* Link status */
#define W5500_PHYCFGR_SPD_BIT 2 /* Speed status */
#define W5500_PHYCFGR_DPX_BIT 3 /* Duplex status */

#define W5500_Sn_MR 0x0000 /* Sn Mode Register */
#define W5500_Sn_CR 0x0001 /* Sn Command Register */
#define W5500_Sn_IR 0x0002 /* Sn Interrupt Register */
Expand Down Expand Up @@ -83,7 +88,7 @@ struct w5500_config {
struct spi_dt_spec spi;
struct gpio_dt_spec interrupt;
struct gpio_dt_spec reset;
int32_t timeout;
const struct device *phy_dev;
};

struct w5500_runtime {
Expand All @@ -96,7 +101,7 @@ struct w5500_runtime {
struct gpio_callback gpio_cb;
struct k_sem tx_sem;
struct k_sem int_sem;
bool link_up;
struct phy_link_state state;
uint8_t buf[NET_ETH_MAX_FRAME_SIZE];
};

Expand Down