blob: 4e595bbc04977f5214ea264b6f5fe3c8cfddcac9 [file] [log] [blame]
/* Mediatek STAR MAC network driver.
*
* Copyright (c) 2016-2017 Mediatek Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/
#ifndef _STAR_MAC_H_
#define _STAR_MAC_H_
#include <linux/netdevice.h>
#include <linux/delay.h>
#define desc_tx_dma(desc) ((((desc)->ctrl_len) & TX_COWN) ? 0 : 1)
#define desc_rx_dma(desc) ((((desc)->ctrl_len) & RX_COWN) ? 0 : 1)
#define desc_tx_last(desc) ((((desc)->ctrl_len) & TX_EOR) ? 1 : 0)
#define desc_rx_last(desc) ((((desc)->ctrl_len) & RX_EOR) ? 1 : 0)
#define desc_tx_empty(desc) (((desc)->buffer == 0) && \
(((desc)->ctrl_len & ~TX_EOR) == TX_COWN) && \
((desc)->vtag == 0) && ((desc)->reserve == 0))
#define desc_rx_empty(desc) (((desc)->buffer == 0) && \
(((desc)->ctrl_len & ~RX_EOR) == RX_COWN) && \
((desc)->vtag == 0) && ((desc)->reserve == 0))
#ifndef STAR_POLLING_TIMEOUT
#define STAR_TIMEOUT_COUNT 3000
#define STAR_POLLING_TIMEOUT(cond) \
do {\
u32 timeout = STAR_TIMEOUT_COUNT; \
while (!cond) { \
if (--timeout == 0) \
break; \
} \
if (timeout == 0) { \
STAR_MSG(STAR_ERR, "polling timeout in %s\n", __func__); \
} \
} while (0)
#endif
/* Star Ethernet Controller registers */
/* =============================== */
#define STAR_PHY_CTRL0(base) (base + 0x0000)
#define STAR_PHY_CTRL0_RWDATA_MASK (0xffff)
#define STAR_PHY_CTRL0_RWDATA_OFFSET (16)
#define STAR_PHY_CTRL0_RWOK BIT(15)
#define STAR_PHY_CTRL0_RDCMD BIT(14)
#define STAR_PHY_CTRL0_WTCMD BIT(13)
#define STAR_PHY_CTRL0_PREG_MASK (0x1f)
#define STAR_PHY_CTRL0_PREG_OFFSET (8)
#define STAR_PHY_CTRL0_PA_MASK (0x1f)
#define STAR_PHY_CTRL0_PA_OFFSET (0)
#define STAR_PHY_CTRL1(base) (base + 0x0004)
#define STAR_PHY_CTRL1_APDIS BIT(31)
#define STAR_PHY_CTRL1_APEN (0 << 31)
#define STAR_PHY_CTRL1_phy_addr_MASK (0x1f)
#define STAR_PHY_CTRL1_phy_addr_OFFSET (24)
#define STAR_PHY_CTRL1_RGMII BIT(17)
#define STAR_PHY_CTRL1_REVMII BIT(16)
#define STAR_PHY_CTRL1_TXCLK_CKEN BIT(14)
#define STAR_PHY_CTRL1_FORCETXFC BIT(13)
#define STAR_PHY_CTRL1_FORCERXFC BIT(12)
#define STAR_PHY_CTRL1_FORCEFULL BIT(11)
#define STAR_PHY_CTRL1_FORCESPD_MASK (0x3)
#define STAR_PHY_CTRL1_FORCESPD_OFFSET (9)
#define STAR_PHY_CTRL1_FORCESPD_10M (0 << STAR_PHY_CTRL1_FORCESPD_OFFSET)
#define STAR_PHY_CTRL1_FORCESPD_100M BIT(9)
#define STAR_PHY_CTRL1_FORCESPD_1G (2 << STAR_PHY_CTRL1_FORCESPD_OFFSET)
#define STAR_PHY_CTRL1_FORCESPD_RESV (3 << STAR_PHY_CTRL1_FORCESPD_OFFSET)
#define STAR_PHY_CTRL1_ANEN BIT(8)
#define STAR_PHY_CTRL1_MIDIS BIT(7)
#define STAR_PHY_CTRL1_STA_TXFC BIT(6)
#define STAR_PHY_CTRL1_STA_RXFC BIT(5)
#define STAR_PHY_CTRL1_STA_FULL BIT(4)
#define STAR_PHY_CTRL1_STA_SPD_MASK (0x3)
#define STAR_PHY_CTRL1_STA_DPX_MASK (0x1)
#define STAR_PHY_CTRL1_STA_SPD_DPX_MASK (0x7)
#define STAR_PHY_CTRL1_STA_SPD_OFFSET (2)
#define STAR_PHY_CTRL1_STA_SPD_10M (0 << STAR_PHY_CTRL1_STA_SPD_OFFSET)
#define STAR_PHY_CTRL1_STA_SPD_100M BIT(2)
#define STAR_PHY_CTRL1_STA_SPD_1G (2 << STAR_PHY_CTRL1_STA_SPD_OFFSET)
#define STAR_PHY_CTRL1_STA_SPD_RESV (3 << STAR_PHY_CTRL1_STA_SPD_OFFSET)
#define STAR_PHY_CTRL1_STA_TXCLK BIT(1)
#define STAR_PHY_CTRL1_STA_LINK BIT(0)
#define STAR_PHY_CTRL1_STA_10M_HALF (0x0)
#define STAR_PHY_CTRL1_STA_100M_HALF (0x1)
#define STAR_PHY_CTRL1_STA_10M_FULL (0x4)
#define STAR_PHY_CTRL1_STA_100M_FULL (0x5)
#define STAR_MAC_CFG(base) (base + 0x0008)
#define STAR_MAC_CFG_NICPD BIT(31)
#define STAR_MAC_CFG_WOLEN BIT(30)
#define STAR_MAC_CFG_NICPDRDY BIT(29)
#define STAR_MAC_CFG_TXCKSEN BIT(26)
#define STAR_MAC_CFG_RXCKSEN BIT(25)
#define STAR_MAC_CFG_ACPTCKSERR BIT(24)
#define STAR_MAC_CFG_ISTEN BIT(23)
#define STAR_MAC_CFG_VLANSTRIP BIT(22)
#define STAR_MAC_CFG_ACPTCRCERR BIT(21)
#define STAR_MAC_CFG_CRCSTRIP BIT(20)
#define STAR_MAC_CFG_TXAUTOPAD BIT(19)
#define STAR_MAC_CFG_ACPTLONGPKT BIT(18)
#define STAR_MAC_CFG_MAXLEN_MASK (0x3)
#define STAR_MAC_CFG_MAXLEN_OFFSET (16)
#define STAR_MAC_CFG_MAXLEN_1518 (0 << STAR_MAC_CFG_MAXLEN_OFFSET)
#define STAR_MAC_CFG_MAXLEN_1522 BIT(16)
#define STAR_MAC_CFG_MAXLEN_1536 (2 << STAR_MAC_CFG_MAXLEN_OFFSET)
#define STAR_MAC_CFG_MAXLEN_RESV (3 << STAR_MAC_CFG_MAXLEN_OFFSET)
#define STAR_MAC_CFG_IPG_MASK (0x1f)
#define STAR_MAC_CFG_IPG_OFFSET (10)
#define STAR_MAC_CFG_NSKP16COL BIT(9)
#define STAR_MAC_CFG_FASTBACKOFF BIT(8)
#define STAR_MAC_CFG_TXVLAN_ATPARSE BIT(0)
#define STAR_FC_CFG(base) (base + 0x000c)
#define STAR_FC_CFG_SENDPAUSETH_MASK (0xfff)
#define STAR_FC_CFG_SENDPAUSETH_OFFSET (16)
#define STAR_FC_CFG_COLCNT_CLR_MODE BIT(9)
#define STAR_FC_CFG_UCPAUSEDIS BIT(8)
#define STAR_FC_CFG_BPEN BIT(7)
#define STAR_FC_CFG_CRS_BP_MODE BIT(6)
#define STAR_FC_CFG_MAXBPCOLEN BIT(5)
#define STAR_FC_CFG_MAXBPCOLCNT_MASK (0x1f)
#define STAR_FC_CFG_MAXBPCOLCNT_OFFSET (0)
/* default value for SEND_PAUSE_TH */
#define STAR_FC_CFG_SEND_PAUSE_TH_DEF ((STAR_FC_CFG_SEND_PAUSE_TH_2K & \
STAR_FC_CFG_SENDPAUSETH_MASK) \
<< STAR_FC_CFG_SENDPAUSETH_OFFSET)
#define STAR_FC_CFG_SEND_PAUSE_TH_2K (0x800)
#define STAR_ARL_CFG(base) (base + 0x0010)
#define STAR_ARL_CFG_FILTER_PRI_TAG BIT(6)
#define STAR_ARL_CFG_FILTER_VLAN_UNTAG BIT(5)
#define STAR_ARL_CFG_MISCMODE BIT(4)
#define STAR_ARL_CFG_MYMACONLY BIT(3)
#define STAR_ARL_CFG_CPULEARNDIS BIT(2)
#define STAR_ARL_CFG_RESVMCFILTER BIT(1)
#define STAR_ARL_CFG_HASHALG_CRCDA BIT(0)
#define star_my_mac_h(base) (base + 0x0014)
#define star_my_mac_l(base) (base + 0x0018)
#define star_hash_ctrl(base) (base + 0x001c)
#define STAR_HASH_CTRL_HASHEN BIT(31)
#define STAR_HASH_CTRL_HTBISTDONE BIT(17)
#define STAR_HASH_CTRL_HTBISTOK BIT(16)
#define STAR_HASH_CTRL_START BIT(14)
#define STAR_HASH_CTRL_ACCESSWT BIT(13)
#define STAR_HASH_CTRL_ACCESSRD (0 << 13)
#define STAR_HASH_CTRL_HBITDATA BIT(12)
#define STAR_HASH_CTRL_HBITADDR_MASK (0x1ff)
#define STAR_HASH_CTRL_HBITADDR_OFFSET (0)
#define star_vlan_ctrl(base) (base + 0x0020)
#define STAR_VLAN_ID_0_1(base) (base + 0x0024)
#define STAR_VLAN_ID_2_3(base) (base + 0x0028)
#define star_dummy(base) (base + 0x002C)
#define STAR_DUMMY_FPGA_MODE BIT(31)
#define STAR_DUMMY_E2_ECO BIT(7)
#define STAR_DUMMY_TXRXRDY BIT(1)
#define STAR_DUMMY_MDCMDIODONE BIT(0)
#define star_dma_cfg(base) (base + 0x0030)
#define STAR_DMA_CFG_RX2BOFSTDIS BIT(16)
#define STAR_DMA_CFG_TXPOLLPERIOD_MASK (0x3)
#define STAR_DMA_CFG_TXPOLLPERIOD_OFFSET (6)
#define STAR_DMA_CFG_TXPOLLPERIOD_1US (0 << STAR_DMA_CFG_TXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_TXPOLLPERIOD_10US BIT(6)
#define STAR_DMA_CFG_TXPOLLPERIOD_100US (2 << STAR_DMA_CFG_TXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_TXPOLLPERIOD_1000US (3 << STAR_DMA_CFG_TXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_TXPOLLEN BIT(5)
#define STAR_DMA_CFG_TXSUSPEND BIT(4)
#define STAR_DMA_CFG_RXPOLLPERIOD_MASK (0x3)
#define STAR_DMA_CFG_RXPOLLPERIOD_OFFSET (2)
#define STAR_DMA_CFG_RXPOLLPERIOD_1US (0 << STAR_DMA_CFG_RXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_RXPOLLPERIOD_10US BIT(2)
#define STAR_DMA_CFG_RXPOLLPERIOD_100US (2 << STAR_DMA_CFG_RXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_RXPOLLPERIOD_1000US (3 << STAR_DMA_CFG_RXPOLLPERIOD_OFFSET)
#define STAR_DMA_CFG_RXPOLLEN BIT(1)
#define STAR_DMA_CFG_RXSUSPEND BIT(0)
#define star_tx_dma_ctrl(base) (base + 0x0034)
#define TX_RESUME ((u32)0x01 << 2)
#define TX_STOP ((u32)0x01 << 1)
#define TX_START ((u32)0x01 << 0)
#define star_rx_dma_ctrl(base) (base + 0x0038)
#define STAR_TX_DPTR(base) (base + 0x003c)
#define STAR_RX_DPTR(base) (base + 0x0040)
#define STAR_TX_BASE_ADDR(base) (base + 0x0044)
#define STAR_RX_BASE_ADDR(base) (base + 0x0048)
#define star_int_sta(base) (base + 0x0050)
#define STAR_INT_STA_RX_PCODE BIT(10)
#define STAR_INT_STA_TX_SKIP BIT(9)
#define STAR_INT_STA_TXC BIT(8)
#define STAR_INT_STA_TXQE BIT(7)
#define STAR_INT_STA_RXC BIT(6)
#define STAR_INT_STA_RXQF BIT(5)
#define STAR_INT_STA_MAGICPKT BIT(4)
#define STAR_INT_STA_MIBCNTHALF BIT(3)
#define STAR_INT_STA_PORTCHANGE BIT(2)
#define STAR_INT_STA_RXFIFOFULL BIT(1)
#define star_int_mask(base) (base + 0x0054)
#define star_test0(base) (base + 0x0058)
#define star_test1(base) (base + 0x005c)
#define STAR_TEST1_RST_HASH_BIST BIT(31)
#define STAR_TEST1_EXTEND_RETRY BIT(20)
#define star_extend_cfg(base) (base + 0x0060)
#define STAR_EXTEND_CFG_SDPAUSEOFFTH_MASK (0xfff)
#define STAR_EXTEND_CFG_SDPAUSEOFFTH_OFFSET (16)
/* default value for SEND_PAUSE_RLS */
#define STAR_EXTEND_CFG_SEND_PAUSE_RLS_DEF \
((STAR_EXTEND_CFG_SEND_PAUSE_RLS_1K & \
STAR_EXTEND_CFG_SDPAUSEOFFTH_MASK) \
<< STAR_EXTEND_CFG_SDPAUSEOFFTH_OFFSET)
#define STAR_EXTEND_CFG_SEND_PAUSE_RLS_1K (0x400)
#define ETHSYS_CONFIG(base) (base + 0x94)
#define INT_PHY_SEL BIT(3)
#define SWC_MII_MODE BIT(2)
#define EXT_MDC_MODE BIT(1)
#define MII_PAD_OE BIT(0)
#define MAC_MODE_CONFIG(base) (base + 0x98)
#define BIG_ENDIAN BIT(0)
#define MAC_CLOCK_CONFIG(base) (base + 0xac)
#define TXCLK_OUT_INV BIT(19)
#define RXCLK_OUT_INV BIT(18)
#define TXCLK_IN_INV BIT(17)
#define RXCLK_IN_INV BIT(16)
#define MDC_INV BIT(12)
#define MDC_NEG_LAT BIT(8)
#define MDC_DIV ((u32)0xFF << 0)
#define MDC_CLK_DIV_10 ((u32)0x0A << 0)
/* MIB Counter register */
#define STAR_MIB_RXOKPKT(base) (base + 0x0100)
#define STAR_MIB_RXOKBYTE(base) (base + 0x0104)
#define STAR_MIB_RXRUNT(base) (base + 0x0108)
#define STAR_MIB_RXOVERSIZE(base) (base + 0x010c)
#define STAR_MIB_RXNOBUFDROP(base) (base + 0x0110)
#define STAR_MIB_RXCRCERR(base) (base + 0x0114)
#define STAR_MIB_RXARLDROP(base) (base + 0x0118)
#define STAR_MIB_RXVLANDROP(base) (base + 0x011c)
#define STAR_MIB_RXCKSERR(base) (base + 0x0120)
#define STAR_MIB_RXPAUSE(base) (base + 0x0124)
#define STAR_MIB_TXOKPKT(base) (base + 0x0128)
#define STAR_MIB_TXOKBYTE(base) (base + 0x012c)
#define STAR_MIB_TXPAUSECOL(base) (base + 0x0130)
/**
* @brief structure for Tx descriptor Ring
*/
typedef struct tx_desc_s {
/* Tx control and length */
u32 ctrl_len;
/* Tx descriptor Own bit; 1: CPU own */
#define TX_COWN BIT(31)
/* End of Tx descriptor ring */
#define TX_EOR BIT(30)
/* First Segment descriptor */
#define TX_FS BIT(29)
/* Last Segment descriptor */
#define TX_LS BIT(28)
/* Tx complete interrupt enable (when set, DMA generate
* interrupt after tx sending out pkt)
*/
#define TX_INT BIT(27)
/* Insert VLAN Tag in the following word (in tdes2) */
#define TX_INSV BIT(26)
/* Enable IP checksum generation offload */
#define TX_ICO BIT(25)
/* Enable UDP checksum generation offload */
#define TX_UCO BIT(24)
/* Enable TCP checksum generation offload */
#define TX_TCO BIT(23)
/* Tx Segment Data length */
#define TX_LEN_MASK (0xffff)
#define TX_LEN_OFFSET (0)
/* Tx segment data pointer */
u32 buffer;
u32 vtag;
/* VLAN Tag EPID */
#define TX_EPID_MASK (0xffff)
#define TX_EPID_OFFSET (16)
/* VLNA Tag Priority */
#define TX_PRI_MASK (0x7)
#define TX_PRI_OFFSET (13)
/* VLAN Tag CFI (Canonical Format Indicator) */
#define TX_CFI BIT(12)
/* VLAN Tag VID */
#define TX_VID_MASK (0xfff)
#define TX_VID_OFFSET (0)
/* Tx pointer for external management usage */
u32 reserve;
} tx_desc;
/* Rx Ring */
typedef struct rx_desc_s {
/* Rx control and length */
u32 ctrl_len;
/* RX descriptor Own bit; 1: CPU own */
#define RX_COWN BIT(31)
/* End of Rx descriptor ring */
#define RX_EOR BIT(30)
/* First Segment descriptor */
#define RX_FS BIT(29)
/* Last Segment descriptor */
#define RX_LS BIT(28)
/* Rx packet is oversize */
#define RX_OSIZE BIT(25)
/* Rx packet is CRC Error */
#define RX_CRCERR BIT(24)
/* Rx packet DMAC is Reserved Multicast Address */
#define RX_RMC BIT(23)
/* Rx packet DMAC is hit in hash table */
#define RX_HHIT BIT(22)
/* Rx packet DMAC is My_MAC */
#define RX_MYMAC BIT(21)
/* VLAN Tagged int the following word */
#define RX_VTAG BIT(20)
#define RX_PROT_MASK (0x3)
#define RX_PROT_OFFSET (18)
/* Protocol: IPV4 */
#define RX_PROT_IP (0x0)
/* Protocol: UDP */
#define RX_PROT_UDP (0x1)
/* Protocol: TCP */
#define RX_PROT_TCP (0x2)
/* Protocol: TCP */
#define RX_PROT_OTHERS (0x3)
/* IP checksum fail (meaningful when PROT is IPV4) */
#define RX_IPF BIT(17)
/* Layer-4 checksum fail (meaningful when PROT is UDP or TCP) */
#define RX_L4F BIT(16)
/* Segment Data length(FS=0) / Whole Packet Length(FS=1) */
#define RX_LEN_MASK (0xffff)
#define RX_LEN_OFFSET (0)
/* RX segment data pointer */
u32 buffer;
u32 vtag;
#define RX_EPID_MASK (0xffff) /* VLAN Tag EPID */
#define RX_EPID_OFFSET (16)
#define RX_PRI_MASK (0x7) /* VLAN Tag Priority */
#define RX_PRI_OFFSET (13)
#define RX_CFI BIT(12)
#define RX_VID_MASK (0xfff) /* VLAN Tag VID */
#define RX_VID_OFFSET (0)
u32 reserve; /* Rx pointer for external management usage */
} rx_desc;
typedef struct star_dev_s {
void __iomem *base; /* Base register of Star Ethernet */
void __iomem *pericfg_base; /* Base register of PERICFG */
tx_desc *tx_desc; /* Base Address of Tx descriptor Ring */
rx_desc *rx_desc; /* Base Address of Rx descriptor Ring */
u32 tx_ring_size;
u32 rx_ring_size;
u32 tx_head; /* Head of Tx descriptor (least sent) */
u32 tx_tail; /* Tail of Tx descriptor (least be free) */
u32 rx_head; /* Head of Rx descriptor (least sent) */
u32 rx_tail; /* Tail of Rx descriptor (least be free) */
u32 tx_num;
u32 rx_num;
u32 link_up; /*link status */
void *star_prv;
struct net_device_stats stats;
struct eth_phy_ops *phy_ops;
struct device *dev;
} star_dev;
int star_hw_init(star_dev *dev);
u16 star_mdc_mdio_read(star_dev *dev, u32 phy_addr, u32 phy_reg);
void star_mdc_mdio_write(star_dev *dev, u32 phy_addr, u32 phy_reg, u16 value);
int star_dma_init(star_dev *dev, uintptr_t desc_viraddr,
dma_addr_t desc_dmaaddr);
int star_dma_tx_set(star_dev *dev, u32 buffer,
u32 length, uintptr_t extBuf);
int star_dma_tx_get(star_dev *dev, u32 *buffer,
u32 *ctrl_len, uintptr_t *extBuf);
int star_dma_rx_set(star_dev *dev, u32 buffer,
u32 length, uintptr_t extBuf);
int star_dma_rx_get(star_dev *dev, u32 *buffer,
u32 *ctrl_len, uintptr_t *extBuf);
void star_dma_tx_stop(star_dev *dev);
void star_dma_rx_stop(star_dev *dev);
int star_mac_init(star_dev *dev, u8 mac_addr[6]);
int star_mib_init(star_dev *dev);
int star_phyctrl_init(star_dev *dev, u32 enable, u32 phy_addr);
void star_set_hashbit(star_dev *dev, u32 addr, u32 value);
void star_link_status_change(star_dev *dev);
void star_nic_pdset(star_dev *dev, bool flag);
void star_config_wol(star_dev *star_dev, bool enable);
void enable_eth_wol(star_dev *star_dev);
void disable_eth_wol(star_dev *star_dev);
void star_switch_to_rmii_mode(star_dev *star_dev);
#endif