254 lines
8.3 KiB
C
254 lines
8.3 KiB
C
/*
|
|
* Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#ifndef ETH_ADIN2111_PRIV_H__
|
|
#define ETH_ADIN2111_PRIV_H__
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/drivers/gpio.h>
|
|
#include <zephyr/drivers/spi.h>
|
|
#include <zephyr/net/net_if.h>
|
|
#include <ethernet/eth_stats.h>
|
|
|
|
/* SPI frequency maximum, based on clock cycle time */
|
|
#define ADIN2111_SPI_MAX_FREQUENCY 25000000U
|
|
|
|
#define ADIN2111_PHYID 0x01U
|
|
/* PHY Identification Register Reset Value */
|
|
#define ADIN2111_PHYID_RST_VAL 0x0283BCA1U
|
|
#define ADIN1110_PHYID_RST_VAL 0x0283BC91U
|
|
|
|
/* Reset Control and Status Register */
|
|
#define ADIN2111_RESET 0x03U
|
|
/* MACPHY software reset */
|
|
#define ADIN2111_RESET_SWRESET BIT(0)
|
|
|
|
/* Configuration Register 0 */
|
|
#define ADIN2111_CONFIG0 0x04U
|
|
/* Configuration Synchronization */
|
|
#define ADIN2111_CONFIG0_SYNC BIT(15)
|
|
/* Transmit Frame Check Sequence Validation Enable */
|
|
#define ADIN2111_CONFIG0_TXFCSVE BIT(14)
|
|
/* Zero Align Receive Frame Enable */
|
|
#define ADIN2111_CONFIG0_ZARFE BIT(12)
|
|
/* New packet received only after a new CS assertion */
|
|
#define ADIN2111_CONFIG0_CSARFE BIT(13)
|
|
/* Transmit Cut Through Enable */
|
|
#define ADIN2111_CONFIG0_TXCTE BIT(9)
|
|
/* Receive Cut Through Enable. Must be 0 for Generic SPI */
|
|
#define ADIN2111_CONFIG0_RXCTE BIT(8)
|
|
|
|
/* Configuration Register 2 */
|
|
#define ADIN2111_CONFIG2 0x06U
|
|
/* Forward Frames from Port 2 Not Matching a MAC Address to Port 1 */
|
|
#define ADIN2111_CONFIG2_P2_FWD_UNK2P1 BIT(14)
|
|
/* Forward Frames from Port 1 Not Matching a MAC Address to Port 2 */
|
|
#define ADIN2111_CONFIG2_P1_FWD_UNK2P2 BIT(13)
|
|
/* Enable Cut Through from Port to Port */
|
|
#define ADIN2111_CONFIG2_PORT_CUT_THRU_EN BIT(11)
|
|
/* Enable CRC Append */
|
|
#define ADIN2111_CONFIG2_CRC_APPEND BIT(5)
|
|
|
|
/* Status Register 0 */
|
|
#define ADIN2111_STATUS0 0x08U
|
|
/* PHY Interrupt for Port 1 */
|
|
#define ADIN2111_STATUS0_PHYINT BIT(7)
|
|
/**
|
|
* Reset Complete.
|
|
* The bit is set when the MACPHY reset is complete
|
|
* and ready for configuration.
|
|
*/
|
|
#define ADIN2111_STATUS0_RESETC BIT(6)
|
|
/* Value to completely clear status register 0 */
|
|
#define ADIN2111_STATUS0_CLEAR 0x1F7FU
|
|
|
|
/* Status Register 1 */
|
|
#define ADIN2111_STATUS1 0x09U
|
|
/* PHY Interrupt for Port 2 */
|
|
#define ADIN2111_STATUS1_PHYINT BIT(19)
|
|
/* Port 2 RX FIFO Contains Data */
|
|
#define ADIN2111_STATUS1_P2_RX_RDY BIT(17)
|
|
/* Indicates that a CRC error was detected */
|
|
#define ADIN2111_STATUS1_SPI_ERR BIT(10)
|
|
/* Port 1 RX FIFO Contains Data */
|
|
#define ADIN2111_STATUS1_P1_RX_RDY BIT(4)
|
|
/* Frame transmitted */
|
|
#define ADIN2111_STATUS1_TX_RDY BIT(3)
|
|
/* Value to completely clear status register 1 */
|
|
#define ADIN2111_STATUS1_CLEAR 0xFFF01F08U
|
|
|
|
/* Buffer Status Register */
|
|
#define ADIN2111_BUFSTS 0x0BU
|
|
/* Rx chunks available */
|
|
#define ADIN2111_BUFSTS_RCA_MASK GENMASK(7, 0)
|
|
/* Tx credits */
|
|
#define ADIN2111_BUFSTS_TXC 8U
|
|
#define ADIN2111_BUFSTS_TXC_MASK GENMASK(15, 8)
|
|
|
|
/* Interrupt Mask Register 0 */
|
|
#define ADIN2111_IMASK0 0x0CU
|
|
/* Physical Layer Interrupt Mask */
|
|
#define ADIN2111_IMASK0_PHYINTM BIT(7)
|
|
|
|
/* Interrupt Mask Register 1 */
|
|
#define ADIN2111_IMASK1 0x0DU
|
|
/* Mask Bit for P2_PHYINT */
|
|
#define ADIN2111_IMASK1_P2_PHYINT_MASK BIT(19)
|
|
/*!< Mask Bit for P2_RX_RDY. Generic SPI only.*/
|
|
#define ADIN2111_IMASK1_P2_RX_RDY_MASK BIT(17)
|
|
/*!< Mask Bit for SPI_ERR. Generic SPI only. */
|
|
#define ADIN2111_IMASK1_SPI_ERR_MASK BIT(10)
|
|
/*!< Mask Bit for P1_RX_RDY. Generic SPI only.*/
|
|
#define ADIN2111_IMASK1_P1_RX_RDY_MASK BIT(4)
|
|
/*!< Mask Bit for TX_FRM_DONE. Generic SPI only.*/
|
|
#define ADIN2111_IMASK1_TX_RDY_MASK BIT(3)
|
|
|
|
/* MAC Tx Frame Size Register */
|
|
#define ADIN2111_TX_FSIZE 0x30U
|
|
/* Tx FIFO Space Register */
|
|
#define ADIN2111_TX_SPACE 0x32U
|
|
|
|
/* MAC Address Rule and DA Filter Upper 16 Bits Registers */
|
|
#define ADIN2111_ADDR_FILT_UPR 0x50U
|
|
#define ADIN2111_ADDR_APPLY2PORT2 BIT(31)
|
|
#define ADIN2111_ADDR_APPLY2PORT1 BIT(30)
|
|
#define ADIN2111_ADDR_TO_OTHER_PORT BIT(17)
|
|
#define ADIN2111_ADDR_TO_HOST BIT(16)
|
|
|
|
/* MAC Address DA Filter Lower 32 Bits Registers */
|
|
#define ADIN2111_ADDR_FILT_LWR 0x51U
|
|
/* Upper 16 Bits of the MAC Address Mask */
|
|
#define ADIN2111_ADDR_MSK_UPR 0x70U
|
|
/* Lower 32 Bits of the MAC Address Mask */
|
|
#define ADIN2111_ADDR_MSK_LWR 0x71U
|
|
|
|
/* P1 MAC Rx Frame Size Register */
|
|
#define ADIN2111_P1_RX_FSIZE 0x90U
|
|
/* P1 MAC Receive Register */
|
|
#define ADIN2111_P1_RX 0x91U
|
|
|
|
/* P2 MAC Rx Frame Size Register */
|
|
#define ADIN2111_P2_RX_FSIZE 0xC0U
|
|
/* P2 MAC Receive Register */
|
|
#define ADIN2111_P2_RX 0xC1U
|
|
|
|
/* SPI header size in bytes */
|
|
#define ADIN2111_SPI_HEADER_SIZE 2U
|
|
/* SPI header size for write transaction */
|
|
#define ADIN2111_WRITE_HEADER_SIZE ADIN2111_SPI_HEADER_SIZE
|
|
/* SPI header size for read transaction (1 for TA) */
|
|
#define ADIN2111_READ_HEADER_SIZE (ADIN2111_SPI_HEADER_SIZE + 1U)
|
|
|
|
/* SPI register write buffer size without CRC */
|
|
#define ADIN2111_REG_WRITE_BUF_SIZE (ADIN2111_WRITE_HEADER_SIZE + sizeof(uint32_t))
|
|
/* SPI register write buffer with appended CRC size (1 for header, 1 for register) */
|
|
#define ADIN2111_REG_WRITE_BUF_SIZE_CRC (ADIN2111_REG_WRITE_BUF_SIZE + 2U)
|
|
|
|
/* SPI register read buffer size with TA without CRC */
|
|
#define ADIN2111_REG_READ_BUF_SIZE (ADIN2111_READ_HEADER_SIZE + sizeof(uint32_t))
|
|
/* SPI register read buffer with TA and appended CRC size (1 header, 1 for register) */
|
|
#define ADIN2111_REG_READ_BUF_SIZE_CRC (ADIN2111_REG_READ_BUF_SIZE + 2U)
|
|
|
|
/* SPI read fifo cmd buffer size with TA without CRC */
|
|
#define ADIN2111_FIFO_READ_CMD_BUF_SIZE (ADIN2111_READ_HEADER_SIZE)
|
|
/* SPI read fifo cmd buffer with TA and appended CRC size */
|
|
#define ADIN2111_FIFO_READ_CMD_BUF_SIZE_CRC (ADIN2111_FIFO_READ_CMD_BUF_SIZE + 1U)
|
|
|
|
/* SPI Header for writing control transaction in half duplex mode */
|
|
#define ADIN2111_WRITE_TXN_CTRL 0xA000U
|
|
/* SPI Header for writing control transaction with MAC TX register (!) in half duplex mode */
|
|
#define ADIN2111_TXN_CTRL_TX_REG 0xA031U
|
|
/* SPI Header for reading control transaction in half duplex mode */
|
|
#define ADIN2111_READ_TXN_CTRL 0x8000U
|
|
|
|
/* Frame header size in bytes */
|
|
#define ADIN2111_FRAME_HEADER_SIZE 2U
|
|
#define ADIN2111_INTERNAL_HEADER_SIZE 2U
|
|
/* Number of buffer bytes in TxFIFO to provide frame margin upon writes */
|
|
#define ADIN2111_TX_FIFO_BUFFER_MARGIN 4U
|
|
|
|
/* Manufacturer unique ID */
|
|
#define ADIN2111_PHYID_OUI 0xa0ef
|
|
|
|
/* Open Alliance definitions */
|
|
#define ADIN2111_OA_ALLOC_TIMEOUT K_MSEC(10)
|
|
/* Max setting to a max RCA of 255 68-bytes ckunks */
|
|
#define ADIN2111_OA_BUF_SZ (255U * 64U)
|
|
|
|
#define ADIN2111_OA_CTL_LEN_PROT 16U
|
|
#define ADIN2111_OA_CTL_LEN 12U
|
|
#define ADIN2111_OA_CTL_MMS BIT(24)
|
|
#define ADIN2111_OA_CTL_WNR BIT(29)
|
|
|
|
#define ADIN2111_OA_DATA_HDR_DNC BIT(31)
|
|
#define ADIN2111_OA_DATA_HDR_NORX BIT(29)
|
|
#define ADIN2111_OA_DATA_HDR_VS 22U
|
|
#define ADIN2111_OA_DATA_HDR_DV BIT(21)
|
|
#define ADIN2111_OA_DATA_HDR_SV BIT(20)
|
|
#define ADIN2111_OA_DATA_HDR_EV BIT(14)
|
|
#define ADIN2111_OA_DATA_HDR_EBO 8U
|
|
|
|
#define ADIN2111_OA_DATA_FTR_SYNC BIT(29)
|
|
#define ADIN2111_OA_DATA_FTR_EBO 8U
|
|
#define ADIN2111_OA_DATA_FTR_DV BIT(21)
|
|
#define ADIN2111_OA_DATA_FTR_SV BIT(20)
|
|
#define ADIN2111_OA_DATA_FTR_EV BIT(14)
|
|
#define ADIN2111_OA_DATA_FTR_SWO 16U
|
|
#define ADIN2111_OA_DATA_FTR_SWO_MSK GENMASK(19, 16)
|
|
#define ADIN2111_OA_DATA_FTR_EBO 8U
|
|
#define ADIN2111_OA_DATA_FTR_EBO_MSK GENMASK(13, 8)
|
|
|
|
enum adin2111_chips_id {
|
|
ADIN2111_MAC = 0,
|
|
ADIN1110_MAC,
|
|
};
|
|
|
|
struct adin2111_config {
|
|
enum adin2111_chips_id id;
|
|
struct spi_dt_spec spi;
|
|
struct gpio_dt_spec interrupt;
|
|
struct gpio_dt_spec reset;
|
|
};
|
|
|
|
struct adin2111_data {
|
|
/* Port 0: PHY 1, Port 1: PHY 2 */
|
|
const struct device *port[2];
|
|
struct gpio_callback gpio_int_callback;
|
|
struct k_sem offload_sem;
|
|
struct k_mutex lock;
|
|
uint32_t imask0;
|
|
uint32_t imask1;
|
|
uint16_t ifaces_left_to_init;
|
|
uint8_t *buf;
|
|
uint16_t scur;
|
|
bool oa;
|
|
bool oa_prot;
|
|
uint8_t oa_cps;
|
|
uint8_t oa_tx_buf[ADIN2111_OA_BUF_SZ];
|
|
uint8_t oa_rx_buf[ADIN2111_OA_BUF_SZ];
|
|
|
|
K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_ADIN2111_IRQ_THREAD_STACK_SIZE);
|
|
struct k_thread rx_thread;
|
|
};
|
|
|
|
struct adin2111_port_data {
|
|
struct net_if *iface;
|
|
uint8_t mac_addr[6];
|
|
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
|
|
struct net_stats_eth stats;
|
|
#endif /* CONFIG_NET_STATISTICS_ETHERNET */
|
|
};
|
|
|
|
struct adin2111_port_config {
|
|
const struct device *adin;
|
|
const struct device *phy;
|
|
const uint16_t port_idx;
|
|
const uint16_t phy_addr;
|
|
};
|
|
|
|
#endif /* ETH_ADIN2111_PRIV_H__ */
|