Lines Matching +full:adin2111 +full:- +full:phy
4 * SPDX-License-Identifier: Apache-2.0
12 #include <zephyr/net/phy.h>
22 #include <zephyr/net/phy.h>
25 #include "phy/phy_adin2111_priv.h"
86 return -EBUSY; in eth_adin2111_mac_reset()
111 struct adin2111_data *ctx = dev->data; in eth_adin2111_get_iface()
113 return ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface; in eth_adin2111_get_iface()
118 struct adin2111_data *ctx = dev->data; in eth_adin2111_lock()
120 return k_mutex_lock(&ctx->lock, timeout); in eth_adin2111_lock()
125 struct adin2111_data *ctx = dev->data; in eth_adin2111_unlock()
127 return k_mutex_unlock(&ctx->lock); in eth_adin2111_unlock()
145 const struct adin2111_config *cfg = dev->config; in eth_adin2111_oa_spi_xfer()
163 ret = spi_transceive_dt(&cfg->spi, &tx, &rx); in eth_adin2111_oa_spi_xfer()
175 struct adin2111_data *ctx = dev->data; in eth_adin2111_reg_read_oa()
177 uint32_t *hdr = (uint32_t *)ctx->oa_tx_buf; in eth_adin2111_reg_read_oa()
189 len = (ctx->oa_prot) ? ADIN2111_OA_CTL_LEN_PROT : ADIN2111_OA_CTL_LEN; in eth_adin2111_reg_read_oa()
191 ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len); in eth_adin2111_reg_read_oa()
196 *val = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[8]); in eth_adin2111_reg_read_oa()
199 if (ctx->oa_prot) { in eth_adin2111_reg_read_oa()
200 pval = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[12]); in eth_adin2111_reg_read_oa()
203 return -1; in eth_adin2111_reg_read_oa()
213 struct adin2111_data *ctx = dev->data; in eth_adin2111_reg_write_oa()
215 uint32_t *hdr = (uint32_t *)ctx->oa_tx_buf; in eth_adin2111_reg_write_oa()
227 len = (ctx->oa_prot) ? ADIN2111_OA_CTL_LEN_PROT : ADIN2111_OA_CTL_LEN; in eth_adin2111_reg_write_oa()
229 *(uint32_t *)&ctx->oa_tx_buf[4] = sys_cpu_to_be32(val); in eth_adin2111_reg_write_oa()
230 if (ctx->oa_prot) { in eth_adin2111_reg_write_oa()
231 *(uint32_t *)&ctx->oa_tx_buf[8] = sys_cpu_to_be32(~val); in eth_adin2111_reg_write_oa()
234 ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len); in eth_adin2111_reg_write_oa()
239 if (ctx->oa_prot) { in eth_adin2111_reg_write_oa()
240 pval = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[12]); in eth_adin2111_reg_write_oa()
243 return -1; in eth_adin2111_reg_write_oa()
252 struct adin2111_data *ctx = dev->data; in eth_adin2111_oa_data_read()
253 struct net_if *iface = ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface; in eth_adin2111_oa_data_read()
261 return -EIO; in eth_adin2111_oa_data_read()
271 *(uint32_t *)&ctx->oa_tx_buf[len] = sys_cpu_to_be32(hdr); in eth_adin2111_oa_data_read()
273 len += sizeof(uint32_t) + ctx->oa_cps; in eth_adin2111_oa_data_read()
276 ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len); in eth_adin2111_oa_data_read()
284 ftr = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[rx_pos + ctx->oa_cps]); in eth_adin2111_oa_data_read()
288 return -EIO; in eth_adin2111_oa_data_read()
292 return -EIO; in eth_adin2111_oa_data_read()
302 return -EIO; in eth_adin2111_oa_data_read()
305 ctx->scur = 0; in eth_adin2111_oa_data_read()
310 ctx->oa_cps; in eth_adin2111_oa_data_read()
311 memcpy(&ctx->buf[ctx->scur], &ctx->oa_rx_buf[rx_pos], len); in eth_adin2111_oa_data_read()
312 ctx->scur += len; in eth_adin2111_oa_data_read()
320 return -EIO; in eth_adin2111_oa_data_read()
323 ret = net_pkt_write(pkt, ctx->buf, ctx->scur - sizeof(uint32_t)); in eth_adin2111_oa_data_read()
326 LOG_ERR("Failed to write pkt, scur %d, err %d", ctx->scur, ret); in eth_adin2111_oa_data_read()
338 rx_pos += ctx->oa_cps + sizeof(uint32_t); in eth_adin2111_oa_data_read()
350 struct adin2111_data *ctx = dev->data; in eth_adin2111_send_oa_frame()
356 chunks = len / ctx->oa_cps; in eth_adin2111_send_oa_frame()
358 if (len % ctx->oa_cps) { in eth_adin2111_send_oa_frame()
365 return -EIO; in eth_adin2111_send_oa_frame()
370 return -EIO; in eth_adin2111_send_oa_frame()
383 hdr |= (ctx->oa_cps - 1) << ADIN2111_OA_DATA_HDR_EBO; in eth_adin2111_send_oa_frame()
388 *(uint32_t *)&ctx->oa_tx_buf[cur] = sys_cpu_to_be32(hdr); in eth_adin2111_send_oa_frame()
391 clen = len > ctx->oa_cps ? ctx->oa_cps : len; in eth_adin2111_send_oa_frame()
392 ret = net_pkt_read(pkt, &ctx->oa_tx_buf[cur], clen); in eth_adin2111_send_oa_frame()
397 cur += ctx->oa_cps; in eth_adin2111_send_oa_frame()
398 len -= clen; in eth_adin2111_send_oa_frame()
401 ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, cur); in eth_adin2111_send_oa_frame()
414 const struct adin2111_config *cfg = dev->config; in eth_adin2111_reg_read_generic()
444 ret = spi_transceive_dt(&cfg->spi, &tx, &rx); in eth_adin2111_reg_read_generic()
455 return -EIO; in eth_adin2111_reg_read_generic()
468 const struct adin2111_config *cfg = dev->config; in eth_adin2111_reg_write_generic()
497 return spi_write_dt(&cfg->spi, &tx); in eth_adin2111_reg_write_generic()
503 struct adin2111_data *ctx = dev->data; in eth_adin2111_reg_read()
506 if (ctx->oa) { in eth_adin2111_reg_read()
518 struct adin2111_data *ctx = dev->data; in eth_adin2111_reg_write()
521 if (ctx->oa) { in eth_adin2111_reg_write()
532 const struct adin2111_config *cfg = dev->config; in adin2111_read_fifo()
533 struct adin2111_data *ctx = dev->data; in adin2111_read_fifo()
548 iface = ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface; in adin2111_read_fifo()
559 padding_len = ((fsize % 4) == 0) ? 0U : (ROUND_UP(fsize, 4U) - fsize); in adin2111_read_fifo()
560 /* actual available frame length is FSIZE - FRAME HEADER */ in adin2111_read_fifo()
561 fsize -= ADIN2111_FRAME_HEADER_SIZE; in adin2111_read_fifo()
577 {.buf = ctx->buf, .len = fsize}, in adin2111_read_fifo()
586 ret = spi_transceive_dt(&cfg->spi, &tx, &rx); in adin2111_read_fifo()
594 fsize_real = fsize - sizeof(uint32_t); in adin2111_read_fifo()
602 return -ENOMEM; in adin2111_read_fifo()
605 ret = net_pkt_write(pkt, ctx->buf, fsize_real); in adin2111_read_fifo()
630 const struct adin2111_port_config *cfg = dev->config; in adin2111_port_on_phyint()
631 struct adin2111_port_data *data = dev->data; in adin2111_port_on_phyint()
634 if (phy_adin2111_handle_phy_irq(cfg->phy, &state) < 0) { in adin2111_port_on_phyint()
640 net_eth_carrier_on(data->iface); in adin2111_port_on_phyint()
642 net_eth_carrier_off(data->iface); in adin2111_port_on_phyint()
652 struct adin2111_data *ctx = dev->data; in adin2111_offload_thread()
653 const struct adin2111_config *adin_cfg = dev->config; in adin2111_offload_thread()
654 const bool is_adin2111 = (adin_cfg->id == ADIN2111_MAC); in adin2111_offload_thread()
661 k_sem_take(&ctx->offload_sem, K_FOREVER); in adin2111_offload_thread()
686 /* handle port 1 phy interrupts */ in adin2111_offload_thread()
688 adin2111_port_on_phyint(ctx->port[0]); in adin2111_offload_thread()
691 /* handle port 2 phy interrupts */ in adin2111_offload_thread()
693 adin2111_port_on_phyint(ctx->port[1]); in adin2111_offload_thread()
696 if (ctx->oa) { in adin2111_offload_thread()
760 ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0); in adin2111_offload_thread()
764 ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1); in adin2111_offload_thread()
781 k_sem_give(&ctx->offload_sem); in adin2111_int_callback()
794 /* tx space is a number of halfwords (16-bits), multiply by 2 for bytes */ in adin2111_read_tx_space()
802 const struct adin2111_port_config *cfg = dev->config; in adin2111_port_send()
804 struct adin2111_port_data *data = dev->data; in adin2111_port_send()
806 const struct device *adin = cfg->adin; in adin2111_port_send()
807 struct adin2111_data *ctx = cfg->adin->data; in adin2111_port_send()
817 if (ctx->oa) { in adin2111_port_send()
820 * By high-traffic zperf test, noted that ADIN2111 does not like we send in adin2111_port_send()
832 k_sem_give(&ctx->offload_sem); in adin2111_port_send()
837 ret = eth_adin2111_send_oa_frame(cfg->adin, pkt, htons(cfg->port_idx)); in adin2111_port_send()
845 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
857 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
858 ret = -EBUSY; in adin2111_port_send()
863 * pad to 64 bytes, otherwise MAC/PHY has to do it in adin2111_port_send()
868 + (64 - (pkt_len + ADIN2111_TX_FIFO_BUFFER_MARGIN)) in adin2111_port_send()
877 ret = -ENOMEM; in adin2111_port_send()
878 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
883 memset(ctx->buf, 0, burst_size + ADIN2111_WRITE_HEADER_SIZE); in adin2111_port_send()
886 *(uint16_t *)ctx->buf = htons(ADIN2111_TXN_CTRL_TX_REG); in adin2111_port_send()
888 ctx->buf[2] = crc8_ccitt(0, ctx->buf, header_size); in adin2111_port_send()
893 *(uint16_t *)(ctx->buf + header_size) = htons(cfg->port_idx); in adin2111_port_send()
897 (ctx->buf + header_size + ADIN2111_FRAME_HEADER_SIZE), in adin2111_port_send()
900 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
902 cfg->port_idx, ret); in adin2111_port_send()
909 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
910 LOG_ERR("Port %u write FSIZE failed, %d", cfg->port_idx, ret); in adin2111_port_send()
916 .buf = ctx->buf, in adin2111_port_send()
921 ret = spi_write_dt(&((const struct adin2111_config *) adin->config)->spi, in adin2111_port_send()
925 eth_stats_update_errors_tx(data->iface); in adin2111_port_send()
926 LOG_ERR("Port %u frame SPI write failed, %d", cfg->port_idx, ret); in adin2111_port_send()
930 eth_stats_update_bytes_tx(data->iface, pkt_len); in adin2111_port_send()
931 eth_stats_update_pkts_tx(data->iface); in adin2111_port_send()
999 const struct adin2111_config *cfg = dev->config; in adin2111_filter_multicast()
1000 const bool is_adin2111 = (cfg->id == ADIN2111_MAC); in adin2111_filter_multicast()
1014 const struct adin2111_config *cfg = dev->config; in adin2111_filter_broadcast()
1015 const bool is_adin2111 = (cfg->id == ADIN2111_MAC); in adin2111_filter_broadcast()
1080 return -ENOENT; in eth_adin2111_find_filter()
1094 if (ret != -ENOENT) { in eth_adin2111_set_mac_filter()
1113 return -ENOSPC; in eth_adin2111_set_mac_filter()
1134 const struct adin2111_config *cfg = dev->config; in eth_adin2111_set_promiscuous()
1135 const bool is_adin2111 = (cfg->id == ADIN2111_MAC); in eth_adin2111_set_promiscuous()
1139 return -EINVAL; in eth_adin2111_set_promiscuous()
1151 const struct adin2111_port_config *cfg = dev->config; in adin2111_port_iface_init()
1152 struct adin2111_port_data *data = dev->data; in adin2111_port_iface_init()
1153 const struct device *adin = cfg->adin; in adin2111_port_iface_init()
1154 struct adin2111_data *ctx = adin->data; in adin2111_port_iface_init()
1159 cfg->adin->name, cfg->port_idx); in adin2111_port_iface_init()
1163 if (!device_is_ready(cfg->phy)) { in adin2111_port_iface_init()
1164 LOG_ERR("PHY %u is not ready, can't init port %u iface", in adin2111_port_iface_init()
1165 cfg->phy_addr, cfg->port_idx); in adin2111_port_iface_init()
1169 ctx->port[cfg->port_idx] = dev; in adin2111_port_iface_init()
1170 data->iface = iface; in adin2111_port_iface_init()
1172 ret = adin2111_filter_unicast(adin, data->mac_addr, cfg->port_idx); in adin2111_port_iface_init()
1175 cfg->port_idx, ret); in adin2111_port_iface_init()
1178 net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr), in adin2111_port_iface_init()
1183 --ctx->ifaces_left_to_init; in adin2111_port_iface_init()
1186 if (ctx->ifaces_left_to_init == 0U) { in adin2111_port_iface_init()
1207 k_thread_create(&ctx->rx_thread, ctx->rx_thread_stack, in adin2111_port_iface_init()
1208 K_KERNEL_STACK_SIZEOF(ctx->rx_thread_stack), in adin2111_port_iface_init()
1213 k_thread_name_set(&ctx->rx_thread, "eth_adin2111_offload"); in adin2111_port_iface_init()
1232 const struct adin2111_port_config *cfg = dev->config; in adin2111_port_set_config()
1233 struct adin2111_port_data *data = dev->data; in adin2111_port_set_config()
1234 const struct device *adin = cfg->adin; in adin2111_port_set_config()
1235 int ret = -ENOTSUP; in adin2111_port_set_config()
1240 ret = adin2111_filter_unicast(adin, (uint8_t *)&config->mac_address.addr[0], in adin2111_port_set_config()
1241 cfg->port_idx); in adin2111_port_set_config()
1246 (void)memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr)); in adin2111_port_set_config()
1248 (void)net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr), in adin2111_port_set_config()
1254 if (config->filter.type & ETHERNET_FILTER_TYPE_DST_MAC_ADDRESS) { in adin2111_port_set_config()
1255 uint8_t *mac = (uint8_t *)config->filter.mac_address.addr; in adin2111_port_set_config()
1257 if (config->filter.set) { in adin2111_port_set_config()
1258 ret = eth_adin2111_set_mac_filter(adin, mac, cfg->port_idx); in adin2111_port_set_config()
1260 ret = eth_adin2111_clear_mac_filter(adin, mac, cfg->port_idx); in adin2111_port_set_config()
1267 ret = eth_adin2111_set_promiscuous(adin, cfg->port_idx, config->promisc_mode); in adin2111_port_set_config()
1279 struct adin2111_port_data *data = dev->data; in adin2111_port_get_stats()
1281 return &data->stats; in adin2111_port_get_stats()
1298 ret = -ETIMEDOUT; in adin2111_check_spi()
1319 * so checking OUI read-only value instead. in adin2111_await_device()
1329 ret = -ETIMEDOUT; in adin2111_await_device()
1359 const struct adin2111_config *cfg = dev->config; in adin2111_init()
1360 const bool is_adin2111 = (cfg->id == ADIN2111_MAC); in adin2111_init()
1361 struct adin2111_data *ctx = dev->data; in adin2111_init()
1365 __ASSERT(cfg->spi.config.frequency <= ADIN2111_SPI_MAX_FREQUENCY, in adin2111_init()
1368 if (!spi_is_ready_dt(&cfg->spi)) { in adin2111_init()
1369 LOG_ERR("SPI bus %s not ready", cfg->spi.bus->name); in adin2111_init()
1370 return -ENODEV; in adin2111_init()
1373 if (!gpio_is_ready_dt(&cfg->interrupt)) { in adin2111_init()
1375 cfg->interrupt.port->name); in adin2111_init()
1376 return -ENODEV; in adin2111_init()
1379 ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT); in adin2111_init()
1385 if (cfg->reset.port != NULL) { in adin2111_init()
1386 if (!gpio_is_ready_dt(&cfg->reset)) { in adin2111_init()
1388 cfg->reset.port->name); in adin2111_init()
1389 return -ENODEV; in adin2111_init()
1392 ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE); in adin2111_init()
1400 gpio_pin_set_dt(&cfg->reset, 1); in adin2111_init()
1403 gpio_pin_set_dt(&cfg->reset, 0); in adin2111_init()
1407 gpio_init_callback(&(ctx->gpio_int_callback), in adin2111_init()
1409 BIT(cfg->interrupt.pin)); in adin2111_init()
1411 ret = gpio_add_callback(cfg->interrupt.port, &ctx->gpio_int_callback); in adin2111_init()
1445 if (ctx->oa) { in adin2111_init()
1479 ctx->imask0 = ~((uint32_t)ADIN2111_IMASK0_PHYINTM); in adin2111_init()
1480 ctx->imask1 = ~(ADIN2111_IMASK1_TX_RDY_MASK | in adin2111_init()
1487 ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0); in adin2111_init()
1492 ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1); in adin2111_init()
1498 ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt, in adin2111_init()
1535 .phy = ADIN2111_MDIO_PHY_BY_ADDR(parent_n, phy_n), \
1578 #define ADIN2111_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2, adin2111) \
1580 ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin2111) \
1581 ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2, adin2111)