blob: 2d0b6afa26d271e77cee958c3d5ca8580020f208 [file] [log] [blame] [edit]
/*
* 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_ */