| /* |
| * Copyright (c) 2018 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef ETH_E1000_PRIV_H |
| #define ETH_E1000_PRIV_H |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define CTRL_SLU (1 << 6) /* Set Link Up */ |
| |
| #define TCTL_EN (1 << 1) |
| #define RCTL_EN (1 << 1) |
| |
| #define ICR_TXDW (1) /* Transmit Descriptor Written Back */ |
| #define ICR_TXQE (1 << 1) /* Transmit Queue Empty */ |
| #define ICR_RXO (1 << 6) /* Receiver Overrun */ |
| |
| #define IMS_RXO (1 << 6) /* Receiver FIFO Overrun */ |
| |
| #define RCTL_MPE (1 << 4) /* Multicast Promiscuous Enabled */ |
| |
| #define TDESC_EOP (1) /* End Of Packet */ |
| #define TDESC_RS (1 << 3) /* Report Status */ |
| |
| #define RDESC_STA_DD (1) /* Descriptor Done */ |
| #define TDESC_STA_DD (1) /* Descriptor Done */ |
| |
| #define ETH_ALEN 6 /* TODO: Add a global reusable definition in OS */ |
| |
| enum e1000_reg_t { |
| CTRL = 0x0000, /* Device Control */ |
| ICR = 0x00C0, /* Interrupt Cause Read */ |
| ICS = 0x00C8, /* Interrupt Cause Set */ |
| IMS = 0x00D0, /* Interrupt Mask Set */ |
| RCTL = 0x0100, /* Receive Control */ |
| TCTL = 0x0400, /* Transmit Control */ |
| RDBAL = 0x2800, /* Rx Descriptor Base Address Low */ |
| RDBAH = 0x2804, /* Rx Descriptor Base Address High */ |
| RDLEN = 0x2808, /* Rx Descriptor Length */ |
| RDH = 0x2810, /* Rx Descriptor Head */ |
| RDT = 0x2818, /* Rx Descriptor Tail */ |
| TDBAL = 0x3800, /* Tx Descriptor Base Address Low */ |
| TDBAH = 0x3804, /* Tx Descriptor Base Address High */ |
| TDLEN = 0x3808, /* Tx Descriptor Length */ |
| TDH = 0x3810, /* Tx Descriptor Head */ |
| TDT = 0x3818, /* Tx Descriptor Tail */ |
| RAL = 0x5400, /* Receive Address Low */ |
| RAH = 0x5404, /* Receive Address High */ |
| }; |
| |
| /* Legacy TX Descriptor */ |
| struct e1000_tx { |
| uint64_t addr; |
| uint16_t len; |
| uint8_t cso; |
| uint8_t cmd; |
| uint8_t sta; |
| uint8_t css; |
| uint16_t special; |
| }; |
| |
| /* Legacy RX Descriptor */ |
| struct e1000_rx { |
| uint64_t addr; |
| uint16_t len; |
| uint16_t csum; |
| uint8_t sta; |
| uint8_t err; |
| uint16_t special; |
| }; |
| |
| struct e1000_dev { |
| volatile struct e1000_tx tx __aligned(16); |
| volatile struct e1000_rx rx __aligned(16); |
| mm_reg_t address; |
| |
| /* BDF & DID/VID */ |
| struct pcie_dev *pcie; |
| |
| /* If VLAN is enabled, there can be multiple VLAN interfaces related to |
| * this physical device. In that case, this iface pointer value is not |
| * really used for anything. |
| */ |
| struct net_if *iface; |
| uint8_t mac[ETH_ALEN]; |
| uint8_t txb[NET_ETH_MTU]; |
| uint8_t rxb[NET_ETH_MTU]; |
| #if defined(CONFIG_ETH_E1000_PTP_CLOCK) |
| const struct device *ptp_clock; |
| float clk_ratio; |
| #endif |
| }; |
| |
| struct e1000_config { |
| void (*config_func)(const struct e1000_dev *dev); |
| }; |
| |
| static const char *e1000_reg_to_string(enum e1000_reg_t r) |
| __attribute__((unused)); |
| |
| #define iow32(_dev, _reg, _val) do { \ |
| LOG_DBG("iow32 %s 0x%08x", e1000_reg_to_string(_reg), (_val)); \ |
| sys_write32(_val, (_dev)->address + (_reg)); \ |
| } while (false) |
| |
| #define ior32(_dev, _reg) \ |
| ({ \ |
| uint32_t val = sys_read32((_dev)->address + (_reg)); \ |
| LOG_DBG("ior32 %s 0x%08x", e1000_reg_to_string(_reg), val); \ |
| val; \ |
| }) |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ETH_E1000_PRIV_H_ */ |