#ifndef __HLETH_H #define __HLETH_H #include #include #include #include #include #include #include #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: */