165e0ace2SJie Deng /* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver 265e0ace2SJie Deng * 365e0ace2SJie Deng * Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com) 465e0ace2SJie Deng * 5*ea8c1c64SJie Deng * This program is dual-licensed; you may select either version 2 of 6*ea8c1c64SJie Deng * the GNU General Public License ("GPL") or BSD license ("BSD"). 765e0ace2SJie Deng * 865e0ace2SJie Deng * This Synopsys DWC XLGMAC software driver and associated documentation 965e0ace2SJie Deng * (hereinafter the "Software") is an unsupported proprietary work of 1065e0ace2SJie Deng * Synopsys, Inc. unless otherwise expressly agreed to in writing between 1165e0ace2SJie Deng * Synopsys and you. The Software IS NOT an item of Licensed Software or a 1265e0ace2SJie Deng * Licensed Product under any End User Software License Agreement or 1365e0ace2SJie Deng * Agreement for Licensed Products with Synopsys or any supplement thereto. 1465e0ace2SJie Deng * Synopsys is a registered trademark of Synopsys, Inc. Other names included 1565e0ace2SJie Deng * in the SOFTWARE may be the trademarks of their respective owners. 1665e0ace2SJie Deng */ 1765e0ace2SJie Deng 1865e0ace2SJie Deng #ifndef __DWC_XLGMAC_H__ 1965e0ace2SJie Deng #define __DWC_XLGMAC_H__ 2065e0ace2SJie Deng 2165e0ace2SJie Deng #include <linux/dma-mapping.h> 2265e0ace2SJie Deng #include <linux/netdevice.h> 2365e0ace2SJie Deng #include <linux/workqueue.h> 2465e0ace2SJie Deng #include <linux/phy.h> 2565e0ace2SJie Deng #include <linux/if_vlan.h> 2665e0ace2SJie Deng #include <linux/bitops.h> 2765e0ace2SJie Deng #include <linux/timecounter.h> 2865e0ace2SJie Deng 2965e0ace2SJie Deng #define XLGMAC_DRV_NAME "dwc-xlgmac" 3065e0ace2SJie Deng #define XLGMAC_DRV_VERSION "1.0.0" 3165e0ace2SJie Deng #define XLGMAC_DRV_DESC "Synopsys DWC XLGMAC Driver" 3265e0ace2SJie Deng 3365e0ace2SJie Deng /* Descriptor related parameters */ 3465e0ace2SJie Deng #define XLGMAC_TX_DESC_CNT 1024 3565e0ace2SJie Deng #define XLGMAC_TX_DESC_MIN_FREE (XLGMAC_TX_DESC_CNT >> 3) 3665e0ace2SJie Deng #define XLGMAC_TX_DESC_MAX_PROC (XLGMAC_TX_DESC_CNT >> 1) 3765e0ace2SJie Deng #define XLGMAC_RX_DESC_CNT 1024 3865e0ace2SJie Deng #define XLGMAC_RX_DESC_MAX_DIRTY (XLGMAC_RX_DESC_CNT >> 3) 3965e0ace2SJie Deng 4065e0ace2SJie Deng /* Descriptors required for maximum contiguous TSO/GSO packet */ 4165e0ace2SJie Deng #define XLGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / XLGMAC_TX_MAX_BUF_SIZE) + 1) 4265e0ace2SJie Deng 4365e0ace2SJie Deng /* Maximum possible descriptors needed for a SKB */ 4465e0ace2SJie Deng #define XLGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + XLGMAC_TX_MAX_SPLIT + 2) 4565e0ace2SJie Deng 4665e0ace2SJie Deng #define XLGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1)) 4765e0ace2SJie Deng #define XLGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 4865e0ace2SJie Deng #define XLGMAC_RX_BUF_ALIGN 64 4965e0ace2SJie Deng 5065e0ace2SJie Deng /* Maximum Size for Splitting the Header Data 5165e0ace2SJie Deng * Keep in sync with SKB_ALLOC_SIZE 5265e0ace2SJie Deng * 3'b000: 64 bytes, 3'b001: 128 bytes 5365e0ace2SJie Deng * 3'b010: 256 bytes, 3'b011: 512 bytes 5465e0ace2SJie Deng * 3'b100: 1023 bytes , 3'b101'3'b111: Reserved 5565e0ace2SJie Deng */ 5665e0ace2SJie Deng #define XLGMAC_SPH_HDSMS_SIZE 3 5765e0ace2SJie Deng #define XLGMAC_SKB_ALLOC_SIZE 512 5865e0ace2SJie Deng 5965e0ace2SJie Deng #define XLGMAC_MAX_FIFO 81920 6065e0ace2SJie Deng 6165e0ace2SJie Deng #define XLGMAC_MAX_DMA_CHANNELS 16 6265e0ace2SJie Deng #define XLGMAC_DMA_STOP_TIMEOUT 5 6365e0ace2SJie Deng #define XLGMAC_DMA_INTERRUPT_MASK 0x31c7 6465e0ace2SJie Deng 6565e0ace2SJie Deng /* Default coalescing parameters */ 6665e0ace2SJie Deng #define XLGMAC_INIT_DMA_TX_USECS 1000 6765e0ace2SJie Deng #define XLGMAC_INIT_DMA_TX_FRAMES 25 6865e0ace2SJie Deng #define XLGMAC_INIT_DMA_RX_USECS 30 6965e0ace2SJie Deng #define XLGMAC_INIT_DMA_RX_FRAMES 25 7065e0ace2SJie Deng 7165e0ace2SJie Deng /* Flow control queue count */ 7265e0ace2SJie Deng #define XLGMAC_MAX_FLOW_CONTROL_QUEUES 8 7365e0ace2SJie Deng 7465e0ace2SJie Deng /* System clock is 125 MHz */ 7565e0ace2SJie Deng #define XLGMAC_SYSCLOCK 125000000 7665e0ace2SJie Deng 7765e0ace2SJie Deng /* Maximum MAC address hash table size (256 bits = 8 bytes) */ 7865e0ace2SJie Deng #define XLGMAC_MAC_HASH_TABLE_SIZE 8 7965e0ace2SJie Deng 8065e0ace2SJie Deng /* Receive Side Scaling */ 8165e0ace2SJie Deng #define XLGMAC_RSS_HASH_KEY_SIZE 40 8265e0ace2SJie Deng #define XLGMAC_RSS_MAX_TABLE_SIZE 256 8365e0ace2SJie Deng #define XLGMAC_RSS_LOOKUP_TABLE_TYPE 0 8465e0ace2SJie Deng #define XLGMAC_RSS_HASH_KEY_TYPE 1 8565e0ace2SJie Deng 8665e0ace2SJie Deng #define XLGMAC_STD_PACKET_MTU 1500 8765e0ace2SJie Deng #define XLGMAC_JUMBO_PACKET_MTU 9000 8865e0ace2SJie Deng 8965e0ace2SJie Deng /* Helper macro for descriptor handling 9065e0ace2SJie Deng * Always use XLGMAC_GET_DESC_DATA to access the descriptor data 9165e0ace2SJie Deng */ 9265e0ace2SJie Deng #define XLGMAC_GET_DESC_DATA(ring, idx) ({ \ 9365e0ace2SJie Deng typeof(ring) _ring = (ring); \ 9465e0ace2SJie Deng ((_ring)->desc_data_head + \ 9565e0ace2SJie Deng ((idx) & ((_ring)->dma_desc_count - 1))); \ 9665e0ace2SJie Deng }) 9765e0ace2SJie Deng 9865e0ace2SJie Deng #define XLGMAC_GET_REG_BITS(var, pos, len) ({ \ 9965e0ace2SJie Deng typeof(pos) _pos = (pos); \ 10065e0ace2SJie Deng typeof(len) _len = (len); \ 10165e0ace2SJie Deng ((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \ 10265e0ace2SJie Deng }) 10365e0ace2SJie Deng 10465e0ace2SJie Deng #define XLGMAC_GET_REG_BITS_LE(var, pos, len) ({ \ 10565e0ace2SJie Deng typeof(pos) _pos = (pos); \ 10665e0ace2SJie Deng typeof(len) _len = (len); \ 10765e0ace2SJie Deng typeof(var) _var = le32_to_cpu((var)); \ 10865e0ace2SJie Deng ((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \ 10965e0ace2SJie Deng }) 11065e0ace2SJie Deng 11165e0ace2SJie Deng #define XLGMAC_SET_REG_BITS(var, pos, len, val) ({ \ 11265e0ace2SJie Deng typeof(var) _var = (var); \ 11365e0ace2SJie Deng typeof(pos) _pos = (pos); \ 11465e0ace2SJie Deng typeof(len) _len = (len); \ 11565e0ace2SJie Deng typeof(val) _val = (val); \ 11665e0ace2SJie Deng _val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \ 11765e0ace2SJie Deng _var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \ 11865e0ace2SJie Deng }) 11965e0ace2SJie Deng 12065e0ace2SJie Deng #define XLGMAC_SET_REG_BITS_LE(var, pos, len, val) ({ \ 12165e0ace2SJie Deng typeof(var) _var = (var); \ 12265e0ace2SJie Deng typeof(pos) _pos = (pos); \ 12365e0ace2SJie Deng typeof(len) _len = (len); \ 12465e0ace2SJie Deng typeof(val) _val = (val); \ 12565e0ace2SJie Deng _val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \ 12665e0ace2SJie Deng _var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \ 12765e0ace2SJie Deng cpu_to_le32(_var); \ 12865e0ace2SJie Deng }) 12965e0ace2SJie Deng 13065e0ace2SJie Deng struct xlgmac_pdata; 13165e0ace2SJie Deng 13265e0ace2SJie Deng enum xlgmac_int { 13365e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_TI, 13465e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_TPS, 13565e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_TBU, 13665e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_RI, 13765e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_RBU, 13865e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_RPS, 13965e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_TI_RI, 14065e0ace2SJie Deng XLGMAC_INT_DMA_CH_SR_FBE, 14165e0ace2SJie Deng XLGMAC_INT_DMA_ALL, 14265e0ace2SJie Deng }; 14365e0ace2SJie Deng 14465e0ace2SJie Deng struct xlgmac_stats { 14565e0ace2SJie Deng /* MMC TX counters */ 14665e0ace2SJie Deng u64 txoctetcount_gb; 14765e0ace2SJie Deng u64 txframecount_gb; 14865e0ace2SJie Deng u64 txbroadcastframes_g; 14965e0ace2SJie Deng u64 txmulticastframes_g; 15065e0ace2SJie Deng u64 tx64octets_gb; 15165e0ace2SJie Deng u64 tx65to127octets_gb; 15265e0ace2SJie Deng u64 tx128to255octets_gb; 15365e0ace2SJie Deng u64 tx256to511octets_gb; 15465e0ace2SJie Deng u64 tx512to1023octets_gb; 15565e0ace2SJie Deng u64 tx1024tomaxoctets_gb; 15665e0ace2SJie Deng u64 txunicastframes_gb; 15765e0ace2SJie Deng u64 txmulticastframes_gb; 15865e0ace2SJie Deng u64 txbroadcastframes_gb; 15965e0ace2SJie Deng u64 txunderflowerror; 16065e0ace2SJie Deng u64 txoctetcount_g; 16165e0ace2SJie Deng u64 txframecount_g; 16265e0ace2SJie Deng u64 txpauseframes; 16365e0ace2SJie Deng u64 txvlanframes_g; 16465e0ace2SJie Deng 16565e0ace2SJie Deng /* MMC RX counters */ 16665e0ace2SJie Deng u64 rxframecount_gb; 16765e0ace2SJie Deng u64 rxoctetcount_gb; 16865e0ace2SJie Deng u64 rxoctetcount_g; 16965e0ace2SJie Deng u64 rxbroadcastframes_g; 17065e0ace2SJie Deng u64 rxmulticastframes_g; 17165e0ace2SJie Deng u64 rxcrcerror; 17265e0ace2SJie Deng u64 rxrunterror; 17365e0ace2SJie Deng u64 rxjabbererror; 17465e0ace2SJie Deng u64 rxundersize_g; 17565e0ace2SJie Deng u64 rxoversize_g; 17665e0ace2SJie Deng u64 rx64octets_gb; 17765e0ace2SJie Deng u64 rx65to127octets_gb; 17865e0ace2SJie Deng u64 rx128to255octets_gb; 17965e0ace2SJie Deng u64 rx256to511octets_gb; 18065e0ace2SJie Deng u64 rx512to1023octets_gb; 18165e0ace2SJie Deng u64 rx1024tomaxoctets_gb; 18265e0ace2SJie Deng u64 rxunicastframes_g; 18365e0ace2SJie Deng u64 rxlengtherror; 18465e0ace2SJie Deng u64 rxoutofrangetype; 18565e0ace2SJie Deng u64 rxpauseframes; 18665e0ace2SJie Deng u64 rxfifooverflow; 18765e0ace2SJie Deng u64 rxvlanframes_gb; 18865e0ace2SJie Deng u64 rxwatchdogerror; 18965e0ace2SJie Deng 19065e0ace2SJie Deng /* Extra counters */ 19165e0ace2SJie Deng u64 tx_tso_packets; 19265e0ace2SJie Deng u64 rx_split_header_packets; 19365e0ace2SJie Deng u64 rx_buffer_unavailable; 19465e0ace2SJie Deng }; 19565e0ace2SJie Deng 19665e0ace2SJie Deng struct xlgmac_ring_buf { 19765e0ace2SJie Deng struct sk_buff *skb; 19865e0ace2SJie Deng dma_addr_t skb_dma; 19965e0ace2SJie Deng unsigned int skb_len; 20065e0ace2SJie Deng }; 20165e0ace2SJie Deng 20265e0ace2SJie Deng /* Common Tx and Rx DMA hardware descriptor */ 20365e0ace2SJie Deng struct xlgmac_dma_desc { 20465e0ace2SJie Deng __le32 desc0; 20565e0ace2SJie Deng __le32 desc1; 20665e0ace2SJie Deng __le32 desc2; 20765e0ace2SJie Deng __le32 desc3; 20865e0ace2SJie Deng }; 20965e0ace2SJie Deng 21065e0ace2SJie Deng /* Page allocation related values */ 21165e0ace2SJie Deng struct xlgmac_page_alloc { 21265e0ace2SJie Deng struct page *pages; 21365e0ace2SJie Deng unsigned int pages_len; 21465e0ace2SJie Deng unsigned int pages_offset; 21565e0ace2SJie Deng 21665e0ace2SJie Deng dma_addr_t pages_dma; 21765e0ace2SJie Deng }; 21865e0ace2SJie Deng 21965e0ace2SJie Deng /* Ring entry buffer data */ 22065e0ace2SJie Deng struct xlgmac_buffer_data { 22165e0ace2SJie Deng struct xlgmac_page_alloc pa; 22265e0ace2SJie Deng struct xlgmac_page_alloc pa_unmap; 22365e0ace2SJie Deng 22465e0ace2SJie Deng dma_addr_t dma_base; 22565e0ace2SJie Deng unsigned long dma_off; 22665e0ace2SJie Deng unsigned int dma_len; 22765e0ace2SJie Deng }; 22865e0ace2SJie Deng 22965e0ace2SJie Deng /* Tx-related desc data */ 23065e0ace2SJie Deng struct xlgmac_tx_desc_data { 23165e0ace2SJie Deng unsigned int packets; /* BQL packet count */ 23265e0ace2SJie Deng unsigned int bytes; /* BQL byte count */ 23365e0ace2SJie Deng }; 23465e0ace2SJie Deng 23565e0ace2SJie Deng /* Rx-related desc data */ 23665e0ace2SJie Deng struct xlgmac_rx_desc_data { 23765e0ace2SJie Deng struct xlgmac_buffer_data hdr; /* Header locations */ 23865e0ace2SJie Deng struct xlgmac_buffer_data buf; /* Payload locations */ 23965e0ace2SJie Deng 24065e0ace2SJie Deng unsigned short hdr_len; /* Length of received header */ 24165e0ace2SJie Deng unsigned short len; /* Length of received packet */ 24265e0ace2SJie Deng }; 24365e0ace2SJie Deng 24465e0ace2SJie Deng struct xlgmac_pkt_info { 24565e0ace2SJie Deng struct sk_buff *skb; 24665e0ace2SJie Deng 24765e0ace2SJie Deng unsigned int attributes; 24865e0ace2SJie Deng 24965e0ace2SJie Deng unsigned int errors; 25065e0ace2SJie Deng 25165e0ace2SJie Deng /* descriptors needed for this packet */ 25265e0ace2SJie Deng unsigned int desc_count; 25365e0ace2SJie Deng unsigned int length; 25465e0ace2SJie Deng 25565e0ace2SJie Deng unsigned int tx_packets; 25665e0ace2SJie Deng unsigned int tx_bytes; 25765e0ace2SJie Deng 25865e0ace2SJie Deng unsigned int header_len; 25965e0ace2SJie Deng unsigned int tcp_header_len; 26065e0ace2SJie Deng unsigned int tcp_payload_len; 26165e0ace2SJie Deng unsigned short mss; 26265e0ace2SJie Deng 26365e0ace2SJie Deng unsigned short vlan_ctag; 26465e0ace2SJie Deng 26565e0ace2SJie Deng u64 rx_tstamp; 26665e0ace2SJie Deng 26765e0ace2SJie Deng u32 rss_hash; 26865e0ace2SJie Deng enum pkt_hash_types rss_hash_type; 26965e0ace2SJie Deng }; 27065e0ace2SJie Deng 27165e0ace2SJie Deng struct xlgmac_desc_data { 27265e0ace2SJie Deng /* dma_desc: Virtual address of descriptor 27365e0ace2SJie Deng * dma_desc_addr: DMA address of descriptor 27465e0ace2SJie Deng */ 27565e0ace2SJie Deng struct xlgmac_dma_desc *dma_desc; 27665e0ace2SJie Deng dma_addr_t dma_desc_addr; 27765e0ace2SJie Deng 27865e0ace2SJie Deng /* skb: Virtual address of SKB 27965e0ace2SJie Deng * skb_dma: DMA address of SKB data 28065e0ace2SJie Deng * skb_dma_len: Length of SKB DMA area 28165e0ace2SJie Deng */ 28265e0ace2SJie Deng struct sk_buff *skb; 28365e0ace2SJie Deng dma_addr_t skb_dma; 28465e0ace2SJie Deng unsigned int skb_dma_len; 28565e0ace2SJie Deng 28665e0ace2SJie Deng /* Tx/Rx -related data */ 28765e0ace2SJie Deng struct xlgmac_tx_desc_data tx; 28865e0ace2SJie Deng struct xlgmac_rx_desc_data rx; 28965e0ace2SJie Deng 29065e0ace2SJie Deng unsigned int mapped_as_page; 29165e0ace2SJie Deng 29265e0ace2SJie Deng /* Incomplete receive save location. If the budget is exhausted 29365e0ace2SJie Deng * or the last descriptor (last normal descriptor or a following 29465e0ace2SJie Deng * context descriptor) has not been DMA'd yet the current state 29565e0ace2SJie Deng * of the receive processing needs to be saved. 29665e0ace2SJie Deng */ 29765e0ace2SJie Deng unsigned int state_saved; 29865e0ace2SJie Deng struct { 29965e0ace2SJie Deng struct sk_buff *skb; 30065e0ace2SJie Deng unsigned int len; 30165e0ace2SJie Deng unsigned int error; 30265e0ace2SJie Deng } state; 30365e0ace2SJie Deng }; 30465e0ace2SJie Deng 30565e0ace2SJie Deng struct xlgmac_ring { 30665e0ace2SJie Deng /* Per packet related information */ 30765e0ace2SJie Deng struct xlgmac_pkt_info pkt_info; 30865e0ace2SJie Deng 30965e0ace2SJie Deng /* Virtual/DMA addresses of DMA descriptor list and the total count */ 31065e0ace2SJie Deng struct xlgmac_dma_desc *dma_desc_head; 31165e0ace2SJie Deng dma_addr_t dma_desc_head_addr; 31265e0ace2SJie Deng unsigned int dma_desc_count; 31365e0ace2SJie Deng 31465e0ace2SJie Deng /* Array of descriptor data corresponding the DMA descriptor 31565e0ace2SJie Deng * (always use the XLGMAC_GET_DESC_DATA macro to access this data) 31665e0ace2SJie Deng */ 31765e0ace2SJie Deng struct xlgmac_desc_data *desc_data_head; 31865e0ace2SJie Deng 31965e0ace2SJie Deng /* Page allocation for RX buffers */ 32065e0ace2SJie Deng struct xlgmac_page_alloc rx_hdr_pa; 32165e0ace2SJie Deng struct xlgmac_page_alloc rx_buf_pa; 32265e0ace2SJie Deng 32365e0ace2SJie Deng /* Ring index values 32465e0ace2SJie Deng * cur - Tx: index of descriptor to be used for current transfer 32565e0ace2SJie Deng * Rx: index of descriptor to check for packet availability 32665e0ace2SJie Deng * dirty - Tx: index of descriptor to check for transfer complete 32765e0ace2SJie Deng * Rx: index of descriptor to check for buffer reallocation 32865e0ace2SJie Deng */ 32965e0ace2SJie Deng unsigned int cur; 33065e0ace2SJie Deng unsigned int dirty; 33165e0ace2SJie Deng 33265e0ace2SJie Deng /* Coalesce frame count used for interrupt bit setting */ 33365e0ace2SJie Deng unsigned int coalesce_count; 33465e0ace2SJie Deng 33565e0ace2SJie Deng union { 33665e0ace2SJie Deng struct { 33765e0ace2SJie Deng unsigned int xmit_more; 33865e0ace2SJie Deng unsigned int queue_stopped; 33965e0ace2SJie Deng unsigned short cur_mss; 34065e0ace2SJie Deng unsigned short cur_vlan_ctag; 34165e0ace2SJie Deng } tx; 34265e0ace2SJie Deng }; 34365e0ace2SJie Deng } ____cacheline_aligned; 34465e0ace2SJie Deng 34565e0ace2SJie Deng struct xlgmac_channel { 34665e0ace2SJie Deng char name[16]; 34765e0ace2SJie Deng 34865e0ace2SJie Deng /* Address of private data area for device */ 34965e0ace2SJie Deng struct xlgmac_pdata *pdata; 35065e0ace2SJie Deng 35165e0ace2SJie Deng /* Queue index and base address of queue's DMA registers */ 35265e0ace2SJie Deng unsigned int queue_index; 35365e0ace2SJie Deng void __iomem *dma_regs; 35465e0ace2SJie Deng 35565e0ace2SJie Deng /* Per channel interrupt irq number */ 35665e0ace2SJie Deng int dma_irq; 35765e0ace2SJie Deng char dma_irq_name[IFNAMSIZ + 32]; 35865e0ace2SJie Deng 35965e0ace2SJie Deng /* Netdev related settings */ 36065e0ace2SJie Deng struct napi_struct napi; 36165e0ace2SJie Deng 36265e0ace2SJie Deng unsigned int saved_ier; 36365e0ace2SJie Deng 36465e0ace2SJie Deng unsigned int tx_timer_active; 36565e0ace2SJie Deng struct timer_list tx_timer; 36665e0ace2SJie Deng 36765e0ace2SJie Deng struct xlgmac_ring *tx_ring; 36865e0ace2SJie Deng struct xlgmac_ring *rx_ring; 36965e0ace2SJie Deng } ____cacheline_aligned; 37065e0ace2SJie Deng 37165e0ace2SJie Deng struct xlgmac_desc_ops { 37265e0ace2SJie Deng int (*alloc_channles_and_rings)(struct xlgmac_pdata *pdata); 37365e0ace2SJie Deng void (*free_channels_and_rings)(struct xlgmac_pdata *pdata); 37465e0ace2SJie Deng int (*map_tx_skb)(struct xlgmac_channel *channel, 37565e0ace2SJie Deng struct sk_buff *skb); 37665e0ace2SJie Deng int (*map_rx_buffer)(struct xlgmac_pdata *pdata, 37765e0ace2SJie Deng struct xlgmac_ring *ring, 37865e0ace2SJie Deng struct xlgmac_desc_data *desc_data); 37965e0ace2SJie Deng void (*unmap_desc_data)(struct xlgmac_pdata *pdata, 38065e0ace2SJie Deng struct xlgmac_desc_data *desc_data); 38165e0ace2SJie Deng void (*tx_desc_init)(struct xlgmac_pdata *pdata); 38265e0ace2SJie Deng void (*rx_desc_init)(struct xlgmac_pdata *pdata); 38365e0ace2SJie Deng }; 38465e0ace2SJie Deng 38565e0ace2SJie Deng struct xlgmac_hw_ops { 38665e0ace2SJie Deng int (*init)(struct xlgmac_pdata *pdata); 38765e0ace2SJie Deng int (*exit)(struct xlgmac_pdata *pdata); 38865e0ace2SJie Deng 38965e0ace2SJie Deng int (*tx_complete)(struct xlgmac_dma_desc *dma_desc); 39065e0ace2SJie Deng 39165e0ace2SJie Deng void (*enable_tx)(struct xlgmac_pdata *pdata); 39265e0ace2SJie Deng void (*disable_tx)(struct xlgmac_pdata *pdata); 39365e0ace2SJie Deng void (*enable_rx)(struct xlgmac_pdata *pdata); 39465e0ace2SJie Deng void (*disable_rx)(struct xlgmac_pdata *pdata); 39565e0ace2SJie Deng 39665e0ace2SJie Deng int (*enable_int)(struct xlgmac_channel *channel, 39765e0ace2SJie Deng enum xlgmac_int int_id); 39865e0ace2SJie Deng int (*disable_int)(struct xlgmac_channel *channel, 39965e0ace2SJie Deng enum xlgmac_int int_id); 40065e0ace2SJie Deng void (*dev_xmit)(struct xlgmac_channel *channel); 40165e0ace2SJie Deng int (*dev_read)(struct xlgmac_channel *channel); 40265e0ace2SJie Deng 40365e0ace2SJie Deng int (*set_mac_address)(struct xlgmac_pdata *pdata, u8 *addr); 40465e0ace2SJie Deng int (*config_rx_mode)(struct xlgmac_pdata *pdata); 40565e0ace2SJie Deng int (*enable_rx_csum)(struct xlgmac_pdata *pdata); 40665e0ace2SJie Deng int (*disable_rx_csum)(struct xlgmac_pdata *pdata); 40765e0ace2SJie Deng 40865e0ace2SJie Deng /* For MII speed configuration */ 40965e0ace2SJie Deng int (*set_xlgmii_25000_speed)(struct xlgmac_pdata *pdata); 41065e0ace2SJie Deng int (*set_xlgmii_40000_speed)(struct xlgmac_pdata *pdata); 41165e0ace2SJie Deng int (*set_xlgmii_50000_speed)(struct xlgmac_pdata *pdata); 41265e0ace2SJie Deng int (*set_xlgmii_100000_speed)(struct xlgmac_pdata *pdata); 41365e0ace2SJie Deng 41465e0ace2SJie Deng /* For descriptor related operation */ 41565e0ace2SJie Deng void (*tx_desc_init)(struct xlgmac_channel *channel); 41665e0ace2SJie Deng void (*rx_desc_init)(struct xlgmac_channel *channel); 41765e0ace2SJie Deng void (*tx_desc_reset)(struct xlgmac_desc_data *desc_data); 41865e0ace2SJie Deng void (*rx_desc_reset)(struct xlgmac_pdata *pdata, 41965e0ace2SJie Deng struct xlgmac_desc_data *desc_data, 42065e0ace2SJie Deng unsigned int index); 42165e0ace2SJie Deng int (*is_last_desc)(struct xlgmac_dma_desc *dma_desc); 42265e0ace2SJie Deng int (*is_context_desc)(struct xlgmac_dma_desc *dma_desc); 42365e0ace2SJie Deng void (*tx_start_xmit)(struct xlgmac_channel *channel, 42465e0ace2SJie Deng struct xlgmac_ring *ring); 42565e0ace2SJie Deng 42665e0ace2SJie Deng /* For Flow Control */ 42765e0ace2SJie Deng int (*config_tx_flow_control)(struct xlgmac_pdata *pdata); 42865e0ace2SJie Deng int (*config_rx_flow_control)(struct xlgmac_pdata *pdata); 42965e0ace2SJie Deng 43065e0ace2SJie Deng /* For Vlan related config */ 43165e0ace2SJie Deng int (*enable_rx_vlan_stripping)(struct xlgmac_pdata *pdata); 43265e0ace2SJie Deng int (*disable_rx_vlan_stripping)(struct xlgmac_pdata *pdata); 43365e0ace2SJie Deng int (*enable_rx_vlan_filtering)(struct xlgmac_pdata *pdata); 43465e0ace2SJie Deng int (*disable_rx_vlan_filtering)(struct xlgmac_pdata *pdata); 43565e0ace2SJie Deng int (*update_vlan_hash_table)(struct xlgmac_pdata *pdata); 43665e0ace2SJie Deng 43765e0ace2SJie Deng /* For RX coalescing */ 43865e0ace2SJie Deng int (*config_rx_coalesce)(struct xlgmac_pdata *pdata); 43965e0ace2SJie Deng int (*config_tx_coalesce)(struct xlgmac_pdata *pdata); 44065e0ace2SJie Deng unsigned int (*usec_to_riwt)(struct xlgmac_pdata *pdata, 44165e0ace2SJie Deng unsigned int usec); 44265e0ace2SJie Deng unsigned int (*riwt_to_usec)(struct xlgmac_pdata *pdata, 44365e0ace2SJie Deng unsigned int riwt); 44465e0ace2SJie Deng 44565e0ace2SJie Deng /* For RX and TX threshold config */ 44665e0ace2SJie Deng int (*config_rx_threshold)(struct xlgmac_pdata *pdata, 44765e0ace2SJie Deng unsigned int val); 44865e0ace2SJie Deng int (*config_tx_threshold)(struct xlgmac_pdata *pdata, 44965e0ace2SJie Deng unsigned int val); 45065e0ace2SJie Deng 45165e0ace2SJie Deng /* For RX and TX Store and Forward Mode config */ 45265e0ace2SJie Deng int (*config_rsf_mode)(struct xlgmac_pdata *pdata, 45365e0ace2SJie Deng unsigned int val); 45465e0ace2SJie Deng int (*config_tsf_mode)(struct xlgmac_pdata *pdata, 45565e0ace2SJie Deng unsigned int val); 45665e0ace2SJie Deng 45765e0ace2SJie Deng /* For TX DMA Operate on Second Frame config */ 45865e0ace2SJie Deng int (*config_osp_mode)(struct xlgmac_pdata *pdata); 45965e0ace2SJie Deng 46065e0ace2SJie Deng /* For RX and TX PBL config */ 46165e0ace2SJie Deng int (*config_rx_pbl_val)(struct xlgmac_pdata *pdata); 46265e0ace2SJie Deng int (*get_rx_pbl_val)(struct xlgmac_pdata *pdata); 46365e0ace2SJie Deng int (*config_tx_pbl_val)(struct xlgmac_pdata *pdata); 46465e0ace2SJie Deng int (*get_tx_pbl_val)(struct xlgmac_pdata *pdata); 46565e0ace2SJie Deng int (*config_pblx8)(struct xlgmac_pdata *pdata); 46665e0ace2SJie Deng 46765e0ace2SJie Deng /* For MMC statistics */ 46865e0ace2SJie Deng void (*rx_mmc_int)(struct xlgmac_pdata *pdata); 46965e0ace2SJie Deng void (*tx_mmc_int)(struct xlgmac_pdata *pdata); 47065e0ace2SJie Deng void (*read_mmc_stats)(struct xlgmac_pdata *pdata); 47165e0ace2SJie Deng 47265e0ace2SJie Deng /* For Receive Side Scaling */ 47365e0ace2SJie Deng int (*enable_rss)(struct xlgmac_pdata *pdata); 47465e0ace2SJie Deng int (*disable_rss)(struct xlgmac_pdata *pdata); 47565e0ace2SJie Deng int (*set_rss_hash_key)(struct xlgmac_pdata *pdata, 47665e0ace2SJie Deng const u8 *key); 47765e0ace2SJie Deng int (*set_rss_lookup_table)(struct xlgmac_pdata *pdata, 47865e0ace2SJie Deng const u32 *table); 47965e0ace2SJie Deng }; 48065e0ace2SJie Deng 48165e0ace2SJie Deng /* This structure contains flags that indicate what hardware features 48265e0ace2SJie Deng * or configurations are present in the device. 48365e0ace2SJie Deng */ 48465e0ace2SJie Deng struct xlgmac_hw_features { 48565e0ace2SJie Deng /* HW Version */ 48665e0ace2SJie Deng unsigned int version; 48765e0ace2SJie Deng 48865e0ace2SJie Deng /* HW Feature Register0 */ 48965e0ace2SJie Deng unsigned int phyifsel; /* PHY interface support */ 49065e0ace2SJie Deng unsigned int vlhash; /* VLAN Hash Filter */ 49165e0ace2SJie Deng unsigned int sma; /* SMA(MDIO) Interface */ 49265e0ace2SJie Deng unsigned int rwk; /* PMT remote wake-up packet */ 49365e0ace2SJie Deng unsigned int mgk; /* PMT magic packet */ 49465e0ace2SJie Deng unsigned int mmc; /* RMON module */ 49565e0ace2SJie Deng unsigned int aoe; /* ARP Offload */ 49665e0ace2SJie Deng unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ 49765e0ace2SJie Deng unsigned int eee; /* Energy Efficient Ethernet */ 49865e0ace2SJie Deng unsigned int tx_coe; /* Tx Checksum Offload */ 49965e0ace2SJie Deng unsigned int rx_coe; /* Rx Checksum Offload */ 50065e0ace2SJie Deng unsigned int addn_mac; /* Additional MAC Addresses */ 50165e0ace2SJie Deng unsigned int ts_src; /* Timestamp Source */ 50265e0ace2SJie Deng unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */ 50365e0ace2SJie Deng 50465e0ace2SJie Deng /* HW Feature Register1 */ 50565e0ace2SJie Deng unsigned int rx_fifo_size; /* MTL Receive FIFO Size */ 50665e0ace2SJie Deng unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */ 50765e0ace2SJie Deng unsigned int adv_ts_hi; /* Advance Timestamping High Word */ 50865e0ace2SJie Deng unsigned int dma_width; /* DMA width */ 50965e0ace2SJie Deng unsigned int dcb; /* DCB Feature */ 51065e0ace2SJie Deng unsigned int sph; /* Split Header Feature */ 51165e0ace2SJie Deng unsigned int tso; /* TCP Segmentation Offload */ 51265e0ace2SJie Deng unsigned int dma_debug; /* DMA Debug Registers */ 51365e0ace2SJie Deng unsigned int rss; /* Receive Side Scaling */ 51465e0ace2SJie Deng unsigned int tc_cnt; /* Number of Traffic Classes */ 51565e0ace2SJie Deng unsigned int hash_table_size; /* Hash Table Size */ 51665e0ace2SJie Deng unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */ 51765e0ace2SJie Deng 51865e0ace2SJie Deng /* HW Feature Register2 */ 51965e0ace2SJie Deng unsigned int rx_q_cnt; /* Number of MTL Receive Queues */ 52065e0ace2SJie Deng unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */ 52165e0ace2SJie Deng unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */ 52265e0ace2SJie Deng unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */ 52365e0ace2SJie Deng unsigned int pps_out_num; /* Number of PPS outputs */ 52465e0ace2SJie Deng unsigned int aux_snap_num; /* Number of Aux snapshot inputs */ 52565e0ace2SJie Deng }; 52665e0ace2SJie Deng 52765e0ace2SJie Deng struct xlgmac_resources { 52865e0ace2SJie Deng void __iomem *addr; 52965e0ace2SJie Deng int irq; 53065e0ace2SJie Deng }; 53165e0ace2SJie Deng 53265e0ace2SJie Deng struct xlgmac_pdata { 53365e0ace2SJie Deng struct net_device *netdev; 53465e0ace2SJie Deng struct device *dev; 53565e0ace2SJie Deng 53665e0ace2SJie Deng struct xlgmac_hw_ops hw_ops; 53765e0ace2SJie Deng struct xlgmac_desc_ops desc_ops; 53865e0ace2SJie Deng 53965e0ace2SJie Deng /* Device statistics */ 54065e0ace2SJie Deng struct xlgmac_stats stats; 54165e0ace2SJie Deng 54265e0ace2SJie Deng u32 msg_enable; 54365e0ace2SJie Deng 54465e0ace2SJie Deng /* MAC registers base */ 54565e0ace2SJie Deng void __iomem *mac_regs; 54665e0ace2SJie Deng 54765e0ace2SJie Deng /* Hardware features of the device */ 54865e0ace2SJie Deng struct xlgmac_hw_features hw_feat; 54965e0ace2SJie Deng 55065e0ace2SJie Deng struct work_struct restart_work; 55165e0ace2SJie Deng 55265e0ace2SJie Deng /* Rings for Tx/Rx on a DMA channel */ 55365e0ace2SJie Deng struct xlgmac_channel *channel_head; 55465e0ace2SJie Deng unsigned int channel_count; 55565e0ace2SJie Deng unsigned int tx_ring_count; 55665e0ace2SJie Deng unsigned int rx_ring_count; 55765e0ace2SJie Deng unsigned int tx_desc_count; 55865e0ace2SJie Deng unsigned int rx_desc_count; 55965e0ace2SJie Deng unsigned int tx_q_count; 56065e0ace2SJie Deng unsigned int rx_q_count; 56165e0ace2SJie Deng 56265e0ace2SJie Deng /* Tx/Rx common settings */ 56365e0ace2SJie Deng unsigned int pblx8; 56465e0ace2SJie Deng 56565e0ace2SJie Deng /* Tx settings */ 56665e0ace2SJie Deng unsigned int tx_sf_mode; 56765e0ace2SJie Deng unsigned int tx_threshold; 56865e0ace2SJie Deng unsigned int tx_pbl; 56965e0ace2SJie Deng unsigned int tx_osp_mode; 57065e0ace2SJie Deng 57165e0ace2SJie Deng /* Rx settings */ 57265e0ace2SJie Deng unsigned int rx_sf_mode; 57365e0ace2SJie Deng unsigned int rx_threshold; 57465e0ace2SJie Deng unsigned int rx_pbl; 57565e0ace2SJie Deng 57665e0ace2SJie Deng /* Tx coalescing settings */ 57765e0ace2SJie Deng unsigned int tx_usecs; 57865e0ace2SJie Deng unsigned int tx_frames; 57965e0ace2SJie Deng 58065e0ace2SJie Deng /* Rx coalescing settings */ 58165e0ace2SJie Deng unsigned int rx_riwt; 58265e0ace2SJie Deng unsigned int rx_usecs; 58365e0ace2SJie Deng unsigned int rx_frames; 58465e0ace2SJie Deng 58565e0ace2SJie Deng /* Current Rx buffer size */ 58665e0ace2SJie Deng unsigned int rx_buf_size; 58765e0ace2SJie Deng 58865e0ace2SJie Deng /* Flow control settings */ 58965e0ace2SJie Deng unsigned int tx_pause; 59065e0ace2SJie Deng unsigned int rx_pause; 59165e0ace2SJie Deng 59265e0ace2SJie Deng /* Device interrupt number */ 59365e0ace2SJie Deng int dev_irq; 59465e0ace2SJie Deng unsigned int per_channel_irq; 59565e0ace2SJie Deng int channel_irq[XLGMAC_MAX_DMA_CHANNELS]; 59665e0ace2SJie Deng 59765e0ace2SJie Deng /* Netdev related settings */ 59865e0ace2SJie Deng unsigned char mac_addr[ETH_ALEN]; 59965e0ace2SJie Deng netdev_features_t netdev_features; 60065e0ace2SJie Deng struct napi_struct napi; 60165e0ace2SJie Deng 60265e0ace2SJie Deng /* Filtering support */ 60365e0ace2SJie Deng unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 60465e0ace2SJie Deng 60565e0ace2SJie Deng /* Device clocks */ 60665e0ace2SJie Deng unsigned long sysclk_rate; 60765e0ace2SJie Deng 60865e0ace2SJie Deng /* RSS addressing mutex */ 60965e0ace2SJie Deng struct mutex rss_mutex; 61065e0ace2SJie Deng 61165e0ace2SJie Deng /* Receive Side Scaling settings */ 61265e0ace2SJie Deng u8 rss_key[XLGMAC_RSS_HASH_KEY_SIZE]; 61365e0ace2SJie Deng u32 rss_table[XLGMAC_RSS_MAX_TABLE_SIZE]; 61465e0ace2SJie Deng u32 rss_options; 61565e0ace2SJie Deng 61665e0ace2SJie Deng int phy_speed; 61765e0ace2SJie Deng 61865e0ace2SJie Deng char drv_name[32]; 61965e0ace2SJie Deng char drv_ver[32]; 62065e0ace2SJie Deng }; 62165e0ace2SJie Deng 62265e0ace2SJie Deng void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops); 62365e0ace2SJie Deng void xlgmac_init_hw_ops(struct xlgmac_hw_ops *hw_ops); 62465e0ace2SJie Deng const struct net_device_ops *xlgmac_get_netdev_ops(void); 62565e0ace2SJie Deng void xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata, 62665e0ace2SJie Deng struct xlgmac_ring *ring, 62765e0ace2SJie Deng unsigned int idx, 62865e0ace2SJie Deng unsigned int count, 62965e0ace2SJie Deng unsigned int flag); 63065e0ace2SJie Deng void xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata, 63165e0ace2SJie Deng struct xlgmac_ring *ring, 63265e0ace2SJie Deng unsigned int idx); 63365e0ace2SJie Deng void xlgmac_print_pkt(struct net_device *netdev, 63465e0ace2SJie Deng struct sk_buff *skb, bool tx_rx); 63565e0ace2SJie Deng void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata); 63665e0ace2SJie Deng void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata); 63765e0ace2SJie Deng int xlgmac_drv_probe(struct device *dev, 63865e0ace2SJie Deng struct xlgmac_resources *res); 63965e0ace2SJie Deng int xlgmac_drv_remove(struct device *dev); 64065e0ace2SJie Deng 64165e0ace2SJie Deng /* For debug prints */ 64265e0ace2SJie Deng #ifdef XLGMAC_DEBUG 64365e0ace2SJie Deng #define XLGMAC_PR(fmt, args...) \ 64465e0ace2SJie Deng pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args) 64565e0ace2SJie Deng #else 64665e0ace2SJie Deng #define XLGMAC_PR(x...) do { } while (0) 64765e0ace2SJie Deng #endif 64865e0ace2SJie Deng 64965e0ace2SJie Deng #endif /* __DWC_XLGMAC_H__ */ 650