You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
426 lines
13 KiB
426 lines
13 KiB
#ifndef __HLETH_H
|
|
#define __HLETH_H
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/list.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/io.h>
|
|
|
|
#define HLETH_SKB_MEMORY_STATS
|
|
|
|
#define HLETH_MIIBUS_NAME "hlmii"
|
|
#define HLETH_DRIVER_NAME "hleth"
|
|
|
|
/* hleth max port */
|
|
#define HLETH_MAX_PORT 2
|
|
|
|
/* invalid phy addr */
|
|
#define HLETH_INVALID_PHY_ADDR 0xff
|
|
|
|
/* hleth monitor timer, 10ms */
|
|
#define HLETH_MONITOR_TIMER 10
|
|
|
|
/* hleth hardware queue send fifo depth, increase to optimize TX performance. */
|
|
#define HLETH_HWQ_XMIT_DEPTH 12
|
|
|
|
/* set irq affinity to cpu1 when multi-processor */
|
|
#define HLETH_IRQ_AFFINITY_CPU 1
|
|
|
|
#define HLETH_MAX_QUEUE_DEPTH 64
|
|
#define HLETH_MAX_RX_HEAD_LEN (10000) /* max skbs for rx */
|
|
#define HLETH_MAX_RCV_LEN 1535 /* max receive length */
|
|
#define TXQ_NUM 64
|
|
#define RXQ_NUM 128
|
|
|
|
#define HLETH_NAPI_WEIGHT 32
|
|
/* mmu should be less than 1600 Bytes
|
|
*/
|
|
|
|
#define HLETH_MAX_FRAME_SIZE (1600)
|
|
#define SKB_SIZE (HLETH_MAX_FRAME_SIZE)
|
|
#define hleth_invalid_rxpkg_len(len) (!((len) >= 42 && \
|
|
(len) <= HLETH_MAX_FRAME_SIZE))
|
|
|
|
#define HLETH_MAX_MAC_FILTER_NUM 8
|
|
#define HLETH_MAX_UNICAST_ADDRESSES 2
|
|
#define HLETH_MAX_MULTICAST_ADDRESSES (HLETH_MAX_MAC_FILTER_NUM - \
|
|
HLETH_MAX_UNICAST_ADDRESSES)
|
|
|
|
/* Register Definition
|
|
*/
|
|
/*------------------------- port register -----------------------------------*/
|
|
/* Mac port sel */
|
|
#define HLETH_P_MAC_PORTSEL 0x0200
|
|
#define HLETH_P_MAC_PORTSEL_STAT 0
|
|
#define HLETH_P_MAC_PORTSEL_STAT_MDIO 0
|
|
#define HLETH_P_MAC_PORTSEL_STAT_CPU 1
|
|
#define HLETH_P_MAC_PORTSEL_MII_MODE 1
|
|
#define HLETH_P_MAC_PORTSEL_MII ~BIT(1)
|
|
#define HLETH_P_MAC_PORTSEL_RMII BIT(1)
|
|
/* Mac ro status */
|
|
#define HLETH_P_MAC_RO_STAT 0x0204
|
|
/* Mac port status set */
|
|
#define HLETH_P_MAC_PORTSET 0x0208
|
|
#define HLETH_P_MAC_PORTSET_SPD_100M BIT(2)
|
|
#define HLETH_P_MAC_PORTSET_LINKED BIT(1)
|
|
#define HLETH_P_MAC_PORTSET_DUP_FULL BIT(0)
|
|
/* Mac status change */
|
|
#define HLETH_P_MAC_STAT_CHANGE 0x020C
|
|
/* Mac set */
|
|
#define HLETH_P_MAC_SET 0x0210
|
|
#define hleth_p_mac_set_len_max(n) ((n) & 0x7FF)
|
|
#define HLETH_P_MAC_SET_LEN_MAX_MSK GENMASK(10, 0)
|
|
|
|
#define HLETH_P_MAC_RX_IPGCTRL 0x0214
|
|
#define HLETH_P_MAC_TX_IPGCTRL 0x0218
|
|
#define HLETH_P_MAC_TX_IPGCTRL_PRE_CNT_LMT_SHIFT 23
|
|
#define HLETH_P_MAC_TX_IPGCTRL_PRE_CNT_LMT_MSK GENMASK(25, 23)
|
|
/* queue length set */
|
|
#define HLETH_P_GLB_QLEN_SET 0x0344
|
|
#define HLETH_P_GLB_QLEN_SET_TXQ_DEP_MSK GENMASK(5, 0)
|
|
#define hleth_p_glb_qlen_set_txq_dep(n) ((n) << 0)
|
|
#define HLETH_P_GLB_QLEN_SET_RXQ_DEP_MSK GENMASK(13, 8)
|
|
#define hleth_p_glb_qlen_set_rxq_dep(n) ((n) << 8)
|
|
/* Rx frame start addr */
|
|
#define HLETH_P_GLB_RXFRM_SADDR 0x0350
|
|
/* Rx (read only) Queue-ID and LEN */
|
|
#define HLETH_P_GLB_RO_IQFRM_DES 0x0354
|
|
#define HLETH_P_GLB_RO_IQFRM_DES_FDIN_LEN_MSK GENMASK(11, 0)
|
|
/* Rx ADDR */
|
|
#define HLETH_P_GLB_IQ_ADDR 0x0358
|
|
/* Tx ADDR and LEN */
|
|
#define HLETH_P_GLB_EQ_ADDR 0x0360
|
|
#define HLETH_P_GLB_EQFRM_LEN 0x0364
|
|
#define HLETH_P_GLB_EQFRM_TXINQ_LEN_MSK GENMASK(10, 0)
|
|
/* Rx/Tx Queue ID */
|
|
#define HLETH_P_GLB_RO_QUEUE_ID 0x0368
|
|
/* Rx/Tx Queue staus */
|
|
#define HLETH_P_GLB_RO_QUEUE_STAT 0x036C
|
|
/* check this bit to see if we can add a Tx package */
|
|
#define HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_RDY_MSK BIT(24)
|
|
/* check this bit to see if we can add a Rx addr */
|
|
#define HLETH_P_GLB_RO_QUEUE_STAT_RECVQ_RDY_MSK BIT(25)
|
|
/* counts in queue, include currently sending */
|
|
#define HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_CNT_INUSE_MSK GENMASK(5, 0)
|
|
/* Rx Checksum Offload Control */
|
|
#define HLETH_P_RX_COE_CTRL 0x0380
|
|
#define BIT_COE_PAYLOAD_DROP BIT(14)
|
|
|
|
#define HLETH_P_RF_OVERCNT 0x634
|
|
|
|
/*------------------------- global register --------------------------------*/
|
|
/* host mac address */
|
|
#define HLETH_GLB_HOSTMAC_L32 0x1300
|
|
#define HLETH_GLB_HOSTMAC_H16 0x1304
|
|
/* soft reset */
|
|
#define HLETH_GLB_SOFT_RESET 0x1308
|
|
#define HLETH_GLB_SOFT_RESET_ALL BIT(0)
|
|
#define HLETH_GLB_SOFT_RESET_P0 BIT(2)
|
|
#define HLETH_GLB_SOFT_RESET_P1 BIT(3)
|
|
/* forward contrl */
|
|
#define HLETH_GLB_FWCTRL 0x1310
|
|
#define HLETH_GLB_FWCTRL_VLAN_ENABLE BIT(0)
|
|
#define HLETH_GLB_FWCTRL_FW2CPU_ENA_U BIT(5)
|
|
#define HLETH_GLB_FWCTRL_FW2CPU_ENA_D BIT(9)
|
|
#define HLETH_GLB_FWCTRL_FWALL2CPU_U BIT(7)
|
|
#define HLETH_GLB_FWCTRL_FWALL2CPU_D BIT(11)
|
|
#define HLETH_GLB_FWCTRL_FW2OTHPORT_ENA_U BIT(4)
|
|
#define HLETH_GLB_FWCTRL_FW2OTHPORT_ENA_D BIT(8)
|
|
#define HLETH_GLB_FWCTRL_FW2OTHPORT_FORCE_U BIT(6)
|
|
#define HLETH_GLB_FWCTRL_FW2OTHPORT_FORCE_D BIT(10)
|
|
/* Mac filter table control */
|
|
#define HLETH_GLB_MACTCTRL 0x1314
|
|
#define HLETH_GLB_MACTCTRL_MACT_ENA_U BIT(7)
|
|
#define HLETH_GLB_MACTCTRL_MACT_ENA_D BIT(15)
|
|
#define HLETH_GLB_MACTCTRL_BROAD2CPU_U BIT(5)
|
|
#define HLETH_GLB_MACTCTRL_BROAD2CPU_D BIT(13)
|
|
#define HLETH_GLB_MACTCTRL_BROAD2OTHPORT_U BIT(4)
|
|
#define HLETH_GLB_MACTCTRL_BROAD2OTHPORT_D BIT(12)
|
|
#define HLETH_GLB_MACTCTRL_MULTI2CPU_U BIT(3)
|
|
#define HLETH_GLB_MACTCTRL_MULTI2CPU_D BIT(11)
|
|
#define HLETH_GLB_MACTCTRL_MULTI2OTHPORT_U BIT(2)
|
|
#define HLETH_GLB_MACTCTRL_MULTI2OTHPORT_D BIT(10)
|
|
#define HLETH_GLB_MACTCTRL_UNI2CPU_U BIT(1)
|
|
#define HLETH_GLB_MACTCTRL_UNI2CPU_D BIT(9)
|
|
#define HLETH_GLB_MACTCTRL_UNI2OTHPORT_U BIT(0)
|
|
#define HLETH_GLB_MACTCTRL_UNI2OTHPORT_D BIT(8)
|
|
/* Host mac address */
|
|
#define HLETH_GLB_DN_HOSTMAC_L32 0x1340
|
|
#define HLETH_GLB_DN_HOSTMAC_H16 0x1344
|
|
#define HLETH_GLB_DN_HOSTMAC_ENA 0x1348
|
|
#define HLETH_GLB_DN_HOSTMAC_ENA_BIT BIT(0)
|
|
/* Mac filter */
|
|
#define HLETH_GLB_MAC_L32_BASE 0x1400
|
|
#define HLETH_GLB_MAC_H16_BASE 0x1404
|
|
#define HLETH_GLB_MAC_L32_BASE_D (0x1400 + 16 * 0x8)
|
|
#define HLETH_GLB_MAC_H16_BASE_D (0x1404 + 16 * 0x8)
|
|
#define HLETH_GLB_MACFLT_H16 GENMASK(15, 0)
|
|
#define HLETH_GLB_MACFLT_FW2CPU_U BIT(21)
|
|
#define HLETH_GLB_MACFLT_FW2CPU_D BIT(19)
|
|
#define HLETH_GLB_MACFLT_FW2PORT_U BIT(20)
|
|
#define HLETH_GLB_MACFLT_FW2PORT_D BIT(18)
|
|
#define HLETH_GLB_MACFLT_ENA_U BIT(17)
|
|
#define HLETH_GLB_MACFLT_ENA_D BIT(16)
|
|
/* ENDIAN */
|
|
#define HLETH_GLB_ENDIAN_MOD 0x1318
|
|
#define HLETH_GLB_ENDIAN_MOD_IN BIT(1)
|
|
#define HLETH_GLB_ENDIAN_MOD_OUT BIT(0)
|
|
/* IRQs */
|
|
#define HLETH_GLB_IRQ_STAT 0x1330
|
|
#define HLETH_GLB_IRQ_ENA 0x1334
|
|
#define HLETH_GLB_IRQ_ENA_IEN_A BIT(19)
|
|
#define HLETH_GLB_IRQ_ENA_IEN_U BIT(18)
|
|
#define HLETH_GLB_IRQ_ENA_IEN_D BIT(17)
|
|
#define HLETH_GLB_IRQ_ENA_BIT_U GENMASK(7, 0)
|
|
#define HLETH_GLB_IRQ_ENA_BIT_D GENMASK(27, 20)
|
|
#define HLETH_GLB_IRQ_RAW 0x1338
|
|
#define HLETH_GLB_IRQ_INT_MULTI_RXRDY_U BIT(7)
|
|
#define HLETH_GLB_IRQ_INT_MULTI_RXRDY_D BIT(27)
|
|
#define HLETH_GLB_IRQ_INT_TXQUE_RDY_U BIT(6)
|
|
#define HLETH_GLB_IRQ_INT_TXQUE_RDY_D BIT(26)
|
|
#define HLETH_GLB_IRQ_INT_RX_RDY_U BIT(0)
|
|
#define HLETH_GLB_IRQ_INT_RX_RDY_D BIT(20)
|
|
|
|
/* ***********************************************************
|
|
*
|
|
* Only for internal used!
|
|
*
|
|
* ***********************************************************
|
|
*/
|
|
|
|
/* read/write IO */
|
|
#define hleth_readl(base, ofs) \
|
|
readl(base + (ofs))
|
|
#define hleth_writel(base, v, ofs) \
|
|
writel(v, base + (ofs))
|
|
|
|
#define HLETH_TRACE_LEVEL 8
|
|
#define hlreg_trace(level, msg...) do { \
|
|
if ((level) >= HLETH_TRACE_LEVEL) { \
|
|
pr_info("hlreg_trace:%s:%d: ", __func__, __LINE__); \
|
|
pr_info(msg); \
|
|
pr_info("\n"); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define hlreg_readl(base, ofs) ({ unsigned long reg = readl((base) + (ofs)); \
|
|
hlreg_trace(2, "_readl(0x%04X) = 0x%08lX", (ofs), reg); \
|
|
reg; })
|
|
|
|
#define hlreg_writel(base, v, ofs) do { writel((v), (base) + (ofs)); \
|
|
hlreg_trace(2, "_writel(0x%04X) = 0x%08lX", \
|
|
(ofs), (unsigned long)(v)); \
|
|
} while (0)
|
|
|
|
#define hleth_dump_buf(buf, len) do { \
|
|
int i; \
|
|
char *p = (void *)(buf); \
|
|
pr_info("%s->%d, buf=0x%.8x, len=%d\n", \
|
|
__func__, __LINE__, \
|
|
(int)(buf), (int)(len)); \
|
|
for (i = 0; i < (len); i++) { \
|
|
pr_info("0x%.2x ", *(p+i)); \
|
|
if (!((i+1) & 0x07)) \
|
|
pr_info("\n"); \
|
|
} \
|
|
pr_info("\n"); \
|
|
} while (0)
|
|
|
|
/* port */
|
|
enum hleth_port_e {
|
|
HLETH_PORT_0 = 0,
|
|
HLETH_PORT_1,
|
|
HLETH_PORT_NUM,
|
|
};
|
|
|
|
struct hleth_queue {
|
|
struct sk_buff **skb;
|
|
dma_addr_t *dma_phys;
|
|
int num;
|
|
unsigned int head;
|
|
unsigned int tail;
|
|
};
|
|
|
|
struct hleth_netdev_priv {
|
|
void __iomem *glb_base; /* virtual io global addr */
|
|
void __iomem *port_base; /* virtual to port addr:
|
|
* port0-0; port1-0x2000
|
|
*/
|
|
int port; /* 0 => up port, 1 => down port */
|
|
int irq;
|
|
|
|
struct device *dev;
|
|
struct net_device *ndev;
|
|
struct net_device_stats stats;
|
|
struct phy_device *phy;
|
|
struct device_node *phy_node;
|
|
struct platform_device *pdev;
|
|
phy_interface_t phy_mode;
|
|
|
|
struct mii_bus *mii_bus;
|
|
|
|
struct sk_buff_head rx_head; /* received pkgs */
|
|
struct hleth_queue rxq;
|
|
struct hleth_queue txq;
|
|
u32 tx_fifo_used_cnt;
|
|
|
|
struct timer_list monitor;
|
|
|
|
struct {
|
|
int hw_xmitq;
|
|
} depth;
|
|
|
|
#ifdef CONFIG_HLETH_MAX_RX_POOLS
|
|
struct {
|
|
unsigned long rx_pool_dry_times;
|
|
} stat;
|
|
|
|
struct rx_skb_pool {
|
|
struct sk_buff *sk_pool[CONFIG_HLETH_MAX_RX_POOLS];/* skb pool */
|
|
int next_free_skb; /* next free skb */
|
|
} rx_pool;
|
|
#endif
|
|
|
|
struct napi_struct napi;
|
|
|
|
int link_stat;
|
|
int (*eee_init)(struct phy_device *phy_dev);
|
|
struct work_struct tx_timeout_task;
|
|
|
|
spinlock_t lock; /* lock for reg rw */
|
|
unsigned long lockflags;
|
|
|
|
spinlock_t mdio_lock; /* lock for mdio reg */
|
|
unsigned long mdio_lockflags;
|
|
|
|
struct clk *clk;
|
|
bool mac_wol_enabled;
|
|
bool pm_state_set;
|
|
bool autoeee_enabled;
|
|
|
|
#ifdef HLETH_SKB_MEMORY_STATS
|
|
atomic_t tx_skb_occupied;
|
|
atomic_t tx_skb_mem_occupied;
|
|
atomic_t rx_skb_occupied;
|
|
atomic_t rx_skb_mem_occupied;
|
|
#endif
|
|
unsigned int rx_fifo_overcnt;
|
|
};
|
|
|
|
/* phy parameter */
|
|
struct hleth_phy_param_s {
|
|
bool isvalid; /* valid or not */
|
|
bool isinternal; /* internal phy or external phy */
|
|
int phy_addr;
|
|
u32 trim_params;
|
|
phy_interface_t phy_mode;
|
|
const char *macaddr;
|
|
|
|
/* gpio reset pin if has */
|
|
void __iomem *gpio_base;
|
|
u32 gpio_bit;
|
|
};
|
|
|
|
#define MAX_MULTICAST_FILTER 8
|
|
#define MAX_MAC_LIMIT ETH_ALEN*MAX_MULTICAST_FILTER
|
|
|
|
struct ethstats {
|
|
void __iomem *base;
|
|
void __iomem *macbase[2];
|
|
|
|
char prbuf[SZ_4K];
|
|
u32 sz_prbuf;
|
|
|
|
struct dentry *dentry;
|
|
};
|
|
|
|
struct mcdump {
|
|
void __iomem *base;
|
|
u32 net_flags;
|
|
u32 mc_rcv;
|
|
u32 mc_drop;
|
|
u32 mac_nr;
|
|
spinlock_t lock;
|
|
char mac[MAX_MAC_LIMIT];
|
|
char prbuf[SZ_1K];
|
|
u32 sz_prbuf;
|
|
|
|
struct dentry *dentry;
|
|
};
|
|
|
|
#ifdef HLETH_SKB_MEMORY_STATS
|
|
struct eth_mem_stats {
|
|
char prbuf[SZ_1K];
|
|
u32 sz_prbuf;
|
|
|
|
struct dentry *dentry;
|
|
};
|
|
#endif
|
|
|
|
struct hleth_platdrv_data {
|
|
struct hleth_phy_param_s hleth_phy_param[HLETH_MAX_PORT];
|
|
struct net_device *hleth_devs_save[HLETH_MAX_PORT];
|
|
struct hleth_netdev_priv hleth_priv;
|
|
int hleth_real_port_cnt;
|
|
|
|
/* debugfs info */
|
|
struct dentry *root;
|
|
struct ethstats ethstats;
|
|
struct mcdump mcdump;
|
|
#ifdef HLETH_SKB_MEMORY_STATS
|
|
struct eth_mem_stats eth_mem_stats;
|
|
#endif
|
|
};
|
|
|
|
#undef local_lock_init
|
|
#undef local_lock
|
|
#undef local_unlock
|
|
|
|
#define local_lock_init(priv) spin_lock_init(&(priv)->lock)
|
|
#define local_lock_exit(priv)
|
|
#define local_lock(priv) spin_lock_irqsave(&(priv)->lock, \
|
|
(priv)->lockflags)
|
|
#define local_unlock(priv) spin_unlock_irqrestore(&(priv)->lock, \
|
|
(priv)->lockflags)
|
|
|
|
#define hleth_mdio_lock_init(priv) spin_lock_init(&(priv)->mdio_lock)
|
|
#define hleth_mdio_lock_exit(priv)
|
|
#define hleth_mdio_lock(priv) spin_lock_irqsave(&(priv)->mdio_lock, \
|
|
(priv)->mdio_lockflags)
|
|
#define hleth_mdio_unlock(priv) spin_unlock_irqrestore(&(priv)->mdio_lock, \
|
|
(priv)->mdio_lockflags)
|
|
|
|
#define ud_bit_name(name) ((priv->port == HLETH_PORT_0) ? \
|
|
name##_U : name##_D)
|
|
|
|
#define glb_mac_h16(port, reg) ((((port) == HLETH_PORT_0) ? \
|
|
HLETH_GLB_MAC_H16_BASE : \
|
|
HLETH_GLB_MAC_H16_BASE_D) + (reg * 0x8))
|
|
#define glb_mac_l32(port, reg) ((((port) == HLETH_PORT_0) ? \
|
|
HLETH_GLB_MAC_L32_BASE : \
|
|
HLETH_GLB_MAC_L32_BASE_D) + (reg * 0x8))
|
|
|
|
#define SIOCGETMODE (SIOCDEVPRIVATE) /* get work mode */
|
|
#define SIOCSETMODE (SIOCDEVPRIVATE + 1) /* set work mode */
|
|
#define SIOCGETFWD (SIOCDEVPRIVATE + 2) /* get forcing forward config */
|
|
#define SIOCSETFWD (SIOCDEVPRIVATE + 3) /* set forcing forward config */
|
|
#define SIOCSETPM (SIOCDEVPRIVATE + 4) /* set pmt wake up config */
|
|
#define SIOCSETSUSPEND (SIOCDEVPRIVATE + 5) /* call dev->suspend */
|
|
#define SIOCSETRESUME (SIOCDEVPRIVATE + 6) /* call dev->resume */
|
|
#define SIOCGETPM (SIOCDEVPRIVATE + 7) /* call dev->resume */
|
|
|
|
extern bool hleth_fephy_opt;
|
|
|
|
void hleth_autoeee_init(struct hleth_netdev_priv *priv, int link_stat);
|
|
void hleth_phy_register_fixups(void);
|
|
void hleth_phy_unregister_fixups(void);
|
|
void hleth_phy_reset(struct hleth_platdrv_data *pdata);
|
|
void hleth_phy_clk_disable(struct hleth_platdrv_data *pdata);
|
|
void hleth_fix_festa_phy_trim(struct mii_bus *bus, struct hleth_platdrv_data *pdata);
|
|
#endif
|
|
|
|
/* vim: set ts=8 sw=8 tw=78: */
|