Lines Matching +full:rx +full:- +full:addr +full:- +full:mode
1 /* W5500 Stand-alone Ethernet Controller with SPI
6 * SPDX-License-Identifier: Apache-2.0
32 #define W5500_SPI_BLOCK_SELECT(addr) (((addr) >> 16) & 0x1f) argument
33 #define W5500_SPI_READ_CONTROL(addr) (W5500_SPI_BLOCK_SELECT(addr) << 3) argument
34 #define W5500_SPI_WRITE_CONTROL(addr) \ argument
35 ((W5500_SPI_BLOCK_SELECT(addr) << 3) | BIT(2))
37 static int w5500_spi_read(const struct device *dev, uint32_t addr, in w5500_spi_read() argument
40 const struct w5500_config *cfg = dev->config; in w5500_spi_read()
44 addr >> 8, in w5500_spi_read()
45 addr, in w5500_spi_read()
46 W5500_SPI_READ_CONTROL(addr) in w5500_spi_read()
67 const struct spi_buf_set rx = { in w5500_spi_read() local
72 ret = spi_transceive_dt(&cfg->spi, &tx, &rx); in w5500_spi_read()
77 static int w5500_spi_write(const struct device *dev, uint32_t addr, in w5500_spi_write() argument
80 const struct w5500_config *cfg = dev->config; in w5500_spi_write()
83 addr >> 8, in w5500_spi_write()
84 addr, in w5500_spi_write()
85 W5500_SPI_WRITE_CONTROL(addr), in w5500_spi_write()
102 ret = spi_write_dt(&cfg->spi, &tx); in w5500_spi_write()
110 uint32_t addr; in w5500_readbuf() local
117 addr = mem_start + offset; in w5500_readbuf()
121 len = mem_size - offset; in w5500_readbuf()
124 ret = w5500_spi_read(dev, addr, buf, len); in w5500_readbuf()
135 uint32_t addr; in w5500_writebuf() local
142 addr = mem_start + offset; in w5500_writebuf()
146 len = mem_size - offset; in w5500_writebuf()
149 ret = w5500_spi_write(dev, addr, buf, len); in w5500_writebuf()
169 return -EIO; in w5500_command()
178 struct w5500_runtime *ctx = dev->data; in w5500_tx()
187 if (net_pkt_read(pkt, ctx->buf, len)) { in w5500_tx()
188 return -EIO; in w5500_tx()
191 ret = w5500_writebuf(dev, offset, ctx->buf, len); in w5500_tx()
200 if (k_sem_take(&ctx->tx_sem, K_MSEC(10))) { in w5500_tx()
201 return -EIO; in w5500_tx()
218 struct w5500_runtime *ctx = dev->data; in w5500_rx()
219 const struct w5500_config *config = dev->config; in w5500_rx()
232 rx_len = sys_get_be16(header) - 2; in w5500_rx()
234 pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, rx_len, in w5500_rx()
235 AF_UNSPEC, 0, K_MSEC(config->timeout)); in w5500_rx()
237 eth_stats_update_errors_rx(ctx->iface); in w5500_rx()
241 pkt_buf = pkt->buffer; in w5500_rx()
251 data_ptr = pkt_buf->data; in w5500_rx()
265 read_len -= (uint16_t)frame_len; in w5500_rx()
266 pkt_buf = pkt_buf->frags; in w5500_rx()
269 if (net_recv_data(ctx->iface, pkt) < 0) { in w5500_rx()
281 struct w5500_runtime *ctx = dev->data; in w5500_update_link_status()
288 if (ctx->link_up != true) { in w5500_update_link_status()
289 LOG_INF("%s: Link up", dev->name); in w5500_update_link_status()
290 ctx->link_up = true; in w5500_update_link_status()
291 net_eth_carrier_on(ctx->iface); in w5500_update_link_status()
294 if (ctx->link_up != false) { in w5500_update_link_status()
295 LOG_INF("%s: Link down", dev->name); in w5500_update_link_status()
296 ctx->link_up = false; in w5500_update_link_status()
297 net_eth_carrier_off(ctx->iface); in w5500_update_link_status()
310 struct w5500_runtime *ctx = dev->data; in w5500_thread()
311 const struct w5500_config *config = dev->config; in w5500_thread()
314 res = k_sem_take(&ctx->int_sem, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); in w5500_thread()
318 if (ctx->link_up != true) { in w5500_thread()
322 while (gpio_pin_get_dt(&(config->interrupt))) { in w5500_thread()
333 k_sem_give(&ctx->tx_sem); in w5500_thread()
339 LOG_DBG("RX Done"); in w5500_thread()
343 } else if (res == -EAGAIN) { in w5500_thread()
353 struct w5500_runtime *ctx = dev->data; in w5500_iface_init()
355 net_if_set_link_addr(iface, ctx->mac_addr, in w5500_iface_init()
356 sizeof(ctx->mac_addr), in w5500_iface_init()
359 if (!ctx->iface) { in w5500_iface_init()
360 ctx->iface = iface; in w5500_iface_init()
384 struct w5500_runtime *ctx = dev->data; in w5500_set_config()
388 memcpy(ctx->mac_addr, in w5500_set_config()
389 config->mac_address.addr, in w5500_set_config()
390 sizeof(ctx->mac_addr)); in w5500_set_config()
391 w5500_spi_write(dev, W5500_SHAR, ctx->mac_addr, sizeof(ctx->mac_addr)); in w5500_set_config()
393 dev->name, in w5500_set_config()
394 ctx->mac_addr[0], ctx->mac_addr[1], in w5500_set_config()
395 ctx->mac_addr[2], ctx->mac_addr[3], in w5500_set_config()
396 ctx->mac_addr[4], ctx->mac_addr[5]); in w5500_set_config()
399 net_if_set_link_addr(ctx->iface, ctx->mac_addr, in w5500_set_config()
400 sizeof(ctx->mac_addr), in w5500_set_config()
406 uint8_t mode; in w5500_set_config() local
409 w5500_spi_read(dev, W5500_S0_MR, &mode, 1); in w5500_set_config()
411 if (config->promisc_mode) { in w5500_set_config()
412 if (!(mode & BIT(mr))) { in w5500_set_config()
413 return -EALREADY; in w5500_set_config()
417 WRITE_BIT(mode, mr, 0); in w5500_set_config()
419 if (mode & BIT(mr)) { in w5500_set_config()
420 return -EALREADY; in w5500_set_config()
424 WRITE_BIT(mode, mr, 1); in w5500_set_config()
427 return w5500_spi_write(dev, W5500_S0_MR, &mode, 1); in w5500_set_config()
430 return -ENOTSUP; in w5500_set_config()
432 return -ENOTSUP; in w5500_set_config()
438 uint8_t mode = S0_MR_MACRAW | BIT(W5500_S0_MR_MF); in w5500_hw_start() local
441 /* configure Socket 0 with MACRAW mode and MAC filtering enabled */ in w5500_hw_start()
442 w5500_spi_write(dev, W5500_S0_MR, &mode, 1); in w5500_hw_start()
497 k_sem_give(&ctx->int_sem); in w5500_gpio_callback()
502 struct w5500_runtime *ctx = dev->data; in w5500_set_macaddr()
505 gen_random_mac(ctx->mac_addr, WIZNET_OUI_B0, WIZNET_OUI_B1, WIZNET_OUI_B2); in w5500_set_macaddr()
508 w5500_spi_write(dev, W5500_SHAR, ctx->mac_addr, sizeof(ctx->mac_addr)); in w5500_set_macaddr()
516 /* Configure RX & TX memory to 16K */ in w5500_memory_configure()
531 const struct w5500_config *config = dev->config; in w5500_init()
532 struct w5500_runtime *ctx = dev->data; in w5500_init()
534 ctx->link_up = false; in w5500_init()
536 if (!spi_is_ready_dt(&config->spi)) { in w5500_init()
537 LOG_ERR("SPI master port %s not ready", config->spi.bus->name); in w5500_init()
538 return -EINVAL; in w5500_init()
541 if (!gpio_is_ready_dt(&config->interrupt)) { in w5500_init()
542 LOG_ERR("GPIO port %s not ready", config->interrupt.port->name); in w5500_init()
543 return -EINVAL; in w5500_init()
546 if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) { in w5500_init()
547 LOG_ERR("Unable to configure GPIO pin %u", config->interrupt.pin); in w5500_init()
548 return -EINVAL; in w5500_init()
551 gpio_init_callback(&(ctx->gpio_cb), w5500_gpio_callback, in w5500_init()
552 BIT(config->interrupt.pin)); in w5500_init()
554 if (gpio_add_callback(config->interrupt.port, &(ctx->gpio_cb))) { in w5500_init()
555 return -EINVAL; in w5500_init()
558 gpio_pin_interrupt_configure_dt(&config->interrupt, in w5500_init()
561 if (config->reset.port) { in w5500_init()
562 if (!gpio_is_ready_dt(&config->reset)) { in w5500_init()
563 LOG_ERR("GPIO port %s not ready", config->reset.port->name); in w5500_init()
564 return -EINVAL; in w5500_init()
566 if (gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT)) { in w5500_init()
567 LOG_ERR("Unable to configure GPIO pin %u", config->reset.pin); in w5500_init()
568 return -EINVAL; in w5500_init()
570 gpio_pin_set_dt(&config->reset, 0); in w5500_init()
587 return -ENODEV; in w5500_init()
590 k_thread_create(&ctx->thread, ctx->thread_stack, in w5500_init()
596 k_thread_name_set(&ctx->thread, "eth_w5500"); in w5500_init()