162306a36Sopenharmony_ci/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This program is dual-licensed; you may select either version 2 of 662306a36Sopenharmony_ci * the GNU General Public License ("GPL") or BSD license ("BSD"). 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This Synopsys DWC XLGMAC software driver and associated documentation 962306a36Sopenharmony_ci * (hereinafter the "Software") is an unsupported proprietary work of 1062306a36Sopenharmony_ci * Synopsys, Inc. unless otherwise expressly agreed to in writing between 1162306a36Sopenharmony_ci * Synopsys and you. The Software IS NOT an item of Licensed Software or a 1262306a36Sopenharmony_ci * Licensed Product under any End User Software License Agreement or 1362306a36Sopenharmony_ci * Agreement for Licensed Products with Synopsys or any supplement thereto. 1462306a36Sopenharmony_ci * Synopsys is a registered trademark of Synopsys, Inc. Other names included 1562306a36Sopenharmony_ci * in the SOFTWARE may be the trademarks of their respective owners. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#ifndef __DWC_XLGMAC_H__ 1962306a36Sopenharmony_ci#define __DWC_XLGMAC_H__ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/dma-mapping.h> 2262306a36Sopenharmony_ci#include <linux/netdevice.h> 2362306a36Sopenharmony_ci#include <linux/workqueue.h> 2462306a36Sopenharmony_ci#include <linux/phy.h> 2562306a36Sopenharmony_ci#include <linux/if_vlan.h> 2662306a36Sopenharmony_ci#include <linux/bitops.h> 2762306a36Sopenharmony_ci#include <linux/timecounter.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define XLGMAC_DRV_NAME "dwc-xlgmac" 3062306a36Sopenharmony_ci#define XLGMAC_DRV_VERSION "1.0.0" 3162306a36Sopenharmony_ci#define XLGMAC_DRV_DESC "Synopsys DWC XLGMAC Driver" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* Descriptor related parameters */ 3462306a36Sopenharmony_ci#define XLGMAC_TX_DESC_CNT 1024 3562306a36Sopenharmony_ci#define XLGMAC_TX_DESC_MIN_FREE (XLGMAC_TX_DESC_CNT >> 3) 3662306a36Sopenharmony_ci#define XLGMAC_TX_DESC_MAX_PROC (XLGMAC_TX_DESC_CNT >> 1) 3762306a36Sopenharmony_ci#define XLGMAC_RX_DESC_CNT 1024 3862306a36Sopenharmony_ci#define XLGMAC_RX_DESC_MAX_DIRTY (XLGMAC_RX_DESC_CNT >> 3) 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* Descriptors required for maximum contiguous TSO/GSO packet */ 4162306a36Sopenharmony_ci#define XLGMAC_TX_MAX_SPLIT \ 4262306a36Sopenharmony_ci ((GSO_LEGACY_MAX_SIZE / XLGMAC_TX_MAX_BUF_SIZE) + 1) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Maximum possible descriptors needed for a SKB */ 4562306a36Sopenharmony_ci#define XLGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + XLGMAC_TX_MAX_SPLIT + 2) 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define XLGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1)) 4862306a36Sopenharmony_ci#define XLGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 4962306a36Sopenharmony_ci#define XLGMAC_RX_BUF_ALIGN 64 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* Maximum Size for Splitting the Header Data 5262306a36Sopenharmony_ci * Keep in sync with SKB_ALLOC_SIZE 5362306a36Sopenharmony_ci * 3'b000: 64 bytes, 3'b001: 128 bytes 5462306a36Sopenharmony_ci * 3'b010: 256 bytes, 3'b011: 512 bytes 5562306a36Sopenharmony_ci * 3'b100: 1023 bytes , 3'b101'3'b111: Reserved 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ci#define XLGMAC_SPH_HDSMS_SIZE 3 5862306a36Sopenharmony_ci#define XLGMAC_SKB_ALLOC_SIZE 512 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define XLGMAC_MAX_FIFO 81920 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define XLGMAC_MAX_DMA_CHANNELS 16 6362306a36Sopenharmony_ci#define XLGMAC_DMA_STOP_TIMEOUT 5 6462306a36Sopenharmony_ci#define XLGMAC_DMA_INTERRUPT_MASK 0x31c7 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* Default coalescing parameters */ 6762306a36Sopenharmony_ci#define XLGMAC_INIT_DMA_TX_USECS 1000 6862306a36Sopenharmony_ci#define XLGMAC_INIT_DMA_TX_FRAMES 25 6962306a36Sopenharmony_ci#define XLGMAC_INIT_DMA_RX_USECS 30 7062306a36Sopenharmony_ci#define XLGMAC_INIT_DMA_RX_FRAMES 25 7162306a36Sopenharmony_ci#define XLGMAC_MAX_DMA_RIWT 0xff 7262306a36Sopenharmony_ci#define XLGMAC_MIN_DMA_RIWT 0x01 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/* Flow control queue count */ 7562306a36Sopenharmony_ci#define XLGMAC_MAX_FLOW_CONTROL_QUEUES 8 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* System clock is 125 MHz */ 7862306a36Sopenharmony_ci#define XLGMAC_SYSCLOCK 125000000 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/* Maximum MAC address hash table size (256 bits = 8 bytes) */ 8162306a36Sopenharmony_ci#define XLGMAC_MAC_HASH_TABLE_SIZE 8 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* Receive Side Scaling */ 8462306a36Sopenharmony_ci#define XLGMAC_RSS_HASH_KEY_SIZE 40 8562306a36Sopenharmony_ci#define XLGMAC_RSS_MAX_TABLE_SIZE 256 8662306a36Sopenharmony_ci#define XLGMAC_RSS_LOOKUP_TABLE_TYPE 0 8762306a36Sopenharmony_ci#define XLGMAC_RSS_HASH_KEY_TYPE 1 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#define XLGMAC_STD_PACKET_MTU 1500 9062306a36Sopenharmony_ci#define XLGMAC_JUMBO_PACKET_MTU 9000 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* Helper macro for descriptor handling 9362306a36Sopenharmony_ci * Always use XLGMAC_GET_DESC_DATA to access the descriptor data 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_ci#define XLGMAC_GET_DESC_DATA(ring, idx) ({ \ 9662306a36Sopenharmony_ci typeof(ring) _ring = (ring); \ 9762306a36Sopenharmony_ci ((_ring)->desc_data_head + \ 9862306a36Sopenharmony_ci ((idx) & ((_ring)->dma_desc_count - 1))); \ 9962306a36Sopenharmony_ci}) 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#define XLGMAC_GET_REG_BITS(var, pos, len) ({ \ 10262306a36Sopenharmony_ci typeof(pos) _pos = (pos); \ 10362306a36Sopenharmony_ci typeof(len) _len = (len); \ 10462306a36Sopenharmony_ci ((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \ 10562306a36Sopenharmony_ci}) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci#define XLGMAC_GET_REG_BITS_LE(var, pos, len) ({ \ 10862306a36Sopenharmony_ci typeof(pos) _pos = (pos); \ 10962306a36Sopenharmony_ci typeof(len) _len = (len); \ 11062306a36Sopenharmony_ci typeof(var) _var = le32_to_cpu((var)); \ 11162306a36Sopenharmony_ci ((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \ 11262306a36Sopenharmony_ci}) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define XLGMAC_SET_REG_BITS(var, pos, len, val) ({ \ 11562306a36Sopenharmony_ci typeof(var) _var = (var); \ 11662306a36Sopenharmony_ci typeof(pos) _pos = (pos); \ 11762306a36Sopenharmony_ci typeof(len) _len = (len); \ 11862306a36Sopenharmony_ci typeof(val) _val = (val); \ 11962306a36Sopenharmony_ci _val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \ 12062306a36Sopenharmony_ci _var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \ 12162306a36Sopenharmony_ci}) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define XLGMAC_SET_REG_BITS_LE(var, pos, len, val) ({ \ 12462306a36Sopenharmony_ci typeof(var) _var = (var); \ 12562306a36Sopenharmony_ci typeof(pos) _pos = (pos); \ 12662306a36Sopenharmony_ci typeof(len) _len = (len); \ 12762306a36Sopenharmony_ci typeof(val) _val = (val); \ 12862306a36Sopenharmony_ci _val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \ 12962306a36Sopenharmony_ci _var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \ 13062306a36Sopenharmony_ci cpu_to_le32(_var); \ 13162306a36Sopenharmony_ci}) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct xlgmac_pdata; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cienum xlgmac_int { 13662306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_TI, 13762306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_TPS, 13862306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_TBU, 13962306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_RI, 14062306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_RBU, 14162306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_RPS, 14262306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_TI_RI, 14362306a36Sopenharmony_ci XLGMAC_INT_DMA_CH_SR_FBE, 14462306a36Sopenharmony_ci XLGMAC_INT_DMA_ALL, 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistruct xlgmac_stats { 14862306a36Sopenharmony_ci /* MMC TX counters */ 14962306a36Sopenharmony_ci u64 txoctetcount_gb; 15062306a36Sopenharmony_ci u64 txframecount_gb; 15162306a36Sopenharmony_ci u64 txbroadcastframes_g; 15262306a36Sopenharmony_ci u64 txmulticastframes_g; 15362306a36Sopenharmony_ci u64 tx64octets_gb; 15462306a36Sopenharmony_ci u64 tx65to127octets_gb; 15562306a36Sopenharmony_ci u64 tx128to255octets_gb; 15662306a36Sopenharmony_ci u64 tx256to511octets_gb; 15762306a36Sopenharmony_ci u64 tx512to1023octets_gb; 15862306a36Sopenharmony_ci u64 tx1024tomaxoctets_gb; 15962306a36Sopenharmony_ci u64 txunicastframes_gb; 16062306a36Sopenharmony_ci u64 txmulticastframes_gb; 16162306a36Sopenharmony_ci u64 txbroadcastframes_gb; 16262306a36Sopenharmony_ci u64 txunderflowerror; 16362306a36Sopenharmony_ci u64 txoctetcount_g; 16462306a36Sopenharmony_ci u64 txframecount_g; 16562306a36Sopenharmony_ci u64 txpauseframes; 16662306a36Sopenharmony_ci u64 txvlanframes_g; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* MMC RX counters */ 16962306a36Sopenharmony_ci u64 rxframecount_gb; 17062306a36Sopenharmony_ci u64 rxoctetcount_gb; 17162306a36Sopenharmony_ci u64 rxoctetcount_g; 17262306a36Sopenharmony_ci u64 rxbroadcastframes_g; 17362306a36Sopenharmony_ci u64 rxmulticastframes_g; 17462306a36Sopenharmony_ci u64 rxcrcerror; 17562306a36Sopenharmony_ci u64 rxrunterror; 17662306a36Sopenharmony_ci u64 rxjabbererror; 17762306a36Sopenharmony_ci u64 rxundersize_g; 17862306a36Sopenharmony_ci u64 rxoversize_g; 17962306a36Sopenharmony_ci u64 rx64octets_gb; 18062306a36Sopenharmony_ci u64 rx65to127octets_gb; 18162306a36Sopenharmony_ci u64 rx128to255octets_gb; 18262306a36Sopenharmony_ci u64 rx256to511octets_gb; 18362306a36Sopenharmony_ci u64 rx512to1023octets_gb; 18462306a36Sopenharmony_ci u64 rx1024tomaxoctets_gb; 18562306a36Sopenharmony_ci u64 rxunicastframes_g; 18662306a36Sopenharmony_ci u64 rxlengtherror; 18762306a36Sopenharmony_ci u64 rxoutofrangetype; 18862306a36Sopenharmony_ci u64 rxpauseframes; 18962306a36Sopenharmony_ci u64 rxfifooverflow; 19062306a36Sopenharmony_ci u64 rxvlanframes_gb; 19162306a36Sopenharmony_ci u64 rxwatchdogerror; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* Extra counters */ 19462306a36Sopenharmony_ci u64 tx_tso_packets; 19562306a36Sopenharmony_ci u64 rx_split_header_packets; 19662306a36Sopenharmony_ci u64 tx_process_stopped; 19762306a36Sopenharmony_ci u64 rx_process_stopped; 19862306a36Sopenharmony_ci u64 tx_buffer_unavailable; 19962306a36Sopenharmony_ci u64 rx_buffer_unavailable; 20062306a36Sopenharmony_ci u64 fatal_bus_error; 20162306a36Sopenharmony_ci u64 tx_vlan_packets; 20262306a36Sopenharmony_ci u64 rx_vlan_packets; 20362306a36Sopenharmony_ci u64 napi_poll_isr; 20462306a36Sopenharmony_ci u64 napi_poll_txtimer; 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistruct xlgmac_ring_buf { 20862306a36Sopenharmony_ci struct sk_buff *skb; 20962306a36Sopenharmony_ci dma_addr_t skb_dma; 21062306a36Sopenharmony_ci unsigned int skb_len; 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci/* Common Tx and Rx DMA hardware descriptor */ 21462306a36Sopenharmony_cistruct xlgmac_dma_desc { 21562306a36Sopenharmony_ci __le32 desc0; 21662306a36Sopenharmony_ci __le32 desc1; 21762306a36Sopenharmony_ci __le32 desc2; 21862306a36Sopenharmony_ci __le32 desc3; 21962306a36Sopenharmony_ci}; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci/* Page allocation related values */ 22262306a36Sopenharmony_cistruct xlgmac_page_alloc { 22362306a36Sopenharmony_ci struct page *pages; 22462306a36Sopenharmony_ci unsigned int pages_len; 22562306a36Sopenharmony_ci unsigned int pages_offset; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci dma_addr_t pages_dma; 22862306a36Sopenharmony_ci}; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/* Ring entry buffer data */ 23162306a36Sopenharmony_cistruct xlgmac_buffer_data { 23262306a36Sopenharmony_ci struct xlgmac_page_alloc pa; 23362306a36Sopenharmony_ci struct xlgmac_page_alloc pa_unmap; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci dma_addr_t dma_base; 23662306a36Sopenharmony_ci unsigned long dma_off; 23762306a36Sopenharmony_ci unsigned int dma_len; 23862306a36Sopenharmony_ci}; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* Tx-related desc data */ 24162306a36Sopenharmony_cistruct xlgmac_tx_desc_data { 24262306a36Sopenharmony_ci unsigned int packets; /* BQL packet count */ 24362306a36Sopenharmony_ci unsigned int bytes; /* BQL byte count */ 24462306a36Sopenharmony_ci}; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci/* Rx-related desc data */ 24762306a36Sopenharmony_cistruct xlgmac_rx_desc_data { 24862306a36Sopenharmony_ci struct xlgmac_buffer_data hdr; /* Header locations */ 24962306a36Sopenharmony_ci struct xlgmac_buffer_data buf; /* Payload locations */ 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci unsigned short hdr_len; /* Length of received header */ 25262306a36Sopenharmony_ci unsigned short len; /* Length of received packet */ 25362306a36Sopenharmony_ci}; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistruct xlgmac_pkt_info { 25662306a36Sopenharmony_ci struct sk_buff *skb; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci unsigned int attributes; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci unsigned int errors; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* descriptors needed for this packet */ 26362306a36Sopenharmony_ci unsigned int desc_count; 26462306a36Sopenharmony_ci unsigned int length; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci unsigned int tx_packets; 26762306a36Sopenharmony_ci unsigned int tx_bytes; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci unsigned int header_len; 27062306a36Sopenharmony_ci unsigned int tcp_header_len; 27162306a36Sopenharmony_ci unsigned int tcp_payload_len; 27262306a36Sopenharmony_ci unsigned short mss; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci unsigned short vlan_ctag; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci u64 rx_tstamp; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci u32 rss_hash; 27962306a36Sopenharmony_ci enum pkt_hash_types rss_hash_type; 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistruct xlgmac_desc_data { 28362306a36Sopenharmony_ci /* dma_desc: Virtual address of descriptor 28462306a36Sopenharmony_ci * dma_desc_addr: DMA address of descriptor 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_ci struct xlgmac_dma_desc *dma_desc; 28762306a36Sopenharmony_ci dma_addr_t dma_desc_addr; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* skb: Virtual address of SKB 29062306a36Sopenharmony_ci * skb_dma: DMA address of SKB data 29162306a36Sopenharmony_ci * skb_dma_len: Length of SKB DMA area 29262306a36Sopenharmony_ci */ 29362306a36Sopenharmony_ci struct sk_buff *skb; 29462306a36Sopenharmony_ci dma_addr_t skb_dma; 29562306a36Sopenharmony_ci unsigned int skb_dma_len; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* Tx/Rx -related data */ 29862306a36Sopenharmony_ci struct xlgmac_tx_desc_data tx; 29962306a36Sopenharmony_ci struct xlgmac_rx_desc_data rx; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci unsigned int mapped_as_page; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci /* Incomplete receive save location. If the budget is exhausted 30462306a36Sopenharmony_ci * or the last descriptor (last normal descriptor or a following 30562306a36Sopenharmony_ci * context descriptor) has not been DMA'd yet the current state 30662306a36Sopenharmony_ci * of the receive processing needs to be saved. 30762306a36Sopenharmony_ci */ 30862306a36Sopenharmony_ci unsigned int state_saved; 30962306a36Sopenharmony_ci struct { 31062306a36Sopenharmony_ci struct sk_buff *skb; 31162306a36Sopenharmony_ci unsigned int len; 31262306a36Sopenharmony_ci unsigned int error; 31362306a36Sopenharmony_ci } state; 31462306a36Sopenharmony_ci}; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cistruct xlgmac_ring { 31762306a36Sopenharmony_ci /* Per packet related information */ 31862306a36Sopenharmony_ci struct xlgmac_pkt_info pkt_info; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci /* Virtual/DMA addresses of DMA descriptor list and the total count */ 32162306a36Sopenharmony_ci struct xlgmac_dma_desc *dma_desc_head; 32262306a36Sopenharmony_ci dma_addr_t dma_desc_head_addr; 32362306a36Sopenharmony_ci unsigned int dma_desc_count; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci /* Array of descriptor data corresponding the DMA descriptor 32662306a36Sopenharmony_ci * (always use the XLGMAC_GET_DESC_DATA macro to access this data) 32762306a36Sopenharmony_ci */ 32862306a36Sopenharmony_ci struct xlgmac_desc_data *desc_data_head; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci /* Page allocation for RX buffers */ 33162306a36Sopenharmony_ci struct xlgmac_page_alloc rx_hdr_pa; 33262306a36Sopenharmony_ci struct xlgmac_page_alloc rx_buf_pa; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* Ring index values 33562306a36Sopenharmony_ci * cur - Tx: index of descriptor to be used for current transfer 33662306a36Sopenharmony_ci * Rx: index of descriptor to check for packet availability 33762306a36Sopenharmony_ci * dirty - Tx: index of descriptor to check for transfer complete 33862306a36Sopenharmony_ci * Rx: index of descriptor to check for buffer reallocation 33962306a36Sopenharmony_ci */ 34062306a36Sopenharmony_ci unsigned int cur; 34162306a36Sopenharmony_ci unsigned int dirty; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci /* Coalesce frame count used for interrupt bit setting */ 34462306a36Sopenharmony_ci unsigned int coalesce_count; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci union { 34762306a36Sopenharmony_ci struct { 34862306a36Sopenharmony_ci unsigned int xmit_more; 34962306a36Sopenharmony_ci unsigned int queue_stopped; 35062306a36Sopenharmony_ci unsigned short cur_mss; 35162306a36Sopenharmony_ci unsigned short cur_vlan_ctag; 35262306a36Sopenharmony_ci } tx; 35362306a36Sopenharmony_ci }; 35462306a36Sopenharmony_ci} ____cacheline_aligned; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistruct xlgmac_channel { 35762306a36Sopenharmony_ci char name[16]; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* Address of private data area for device */ 36062306a36Sopenharmony_ci struct xlgmac_pdata *pdata; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci /* Queue index and base address of queue's DMA registers */ 36362306a36Sopenharmony_ci unsigned int queue_index; 36462306a36Sopenharmony_ci void __iomem *dma_regs; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* Per channel interrupt irq number */ 36762306a36Sopenharmony_ci int dma_irq; 36862306a36Sopenharmony_ci char dma_irq_name[IFNAMSIZ + 32]; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci /* Netdev related settings */ 37162306a36Sopenharmony_ci struct napi_struct napi; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci unsigned int saved_ier; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci unsigned int tx_timer_active; 37662306a36Sopenharmony_ci struct timer_list tx_timer; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci struct xlgmac_ring *tx_ring; 37962306a36Sopenharmony_ci struct xlgmac_ring *rx_ring; 38062306a36Sopenharmony_ci} ____cacheline_aligned; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_cistruct xlgmac_desc_ops { 38362306a36Sopenharmony_ci int (*alloc_channels_and_rings)(struct xlgmac_pdata *pdata); 38462306a36Sopenharmony_ci void (*free_channels_and_rings)(struct xlgmac_pdata *pdata); 38562306a36Sopenharmony_ci int (*map_tx_skb)(struct xlgmac_channel *channel, 38662306a36Sopenharmony_ci struct sk_buff *skb); 38762306a36Sopenharmony_ci int (*map_rx_buffer)(struct xlgmac_pdata *pdata, 38862306a36Sopenharmony_ci struct xlgmac_ring *ring, 38962306a36Sopenharmony_ci struct xlgmac_desc_data *desc_data); 39062306a36Sopenharmony_ci void (*unmap_desc_data)(struct xlgmac_pdata *pdata, 39162306a36Sopenharmony_ci struct xlgmac_desc_data *desc_data); 39262306a36Sopenharmony_ci void (*tx_desc_init)(struct xlgmac_pdata *pdata); 39362306a36Sopenharmony_ci void (*rx_desc_init)(struct xlgmac_pdata *pdata); 39462306a36Sopenharmony_ci}; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistruct xlgmac_hw_ops { 39762306a36Sopenharmony_ci int (*init)(struct xlgmac_pdata *pdata); 39862306a36Sopenharmony_ci int (*exit)(struct xlgmac_pdata *pdata); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci int (*tx_complete)(struct xlgmac_dma_desc *dma_desc); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci void (*enable_tx)(struct xlgmac_pdata *pdata); 40362306a36Sopenharmony_ci void (*disable_tx)(struct xlgmac_pdata *pdata); 40462306a36Sopenharmony_ci void (*enable_rx)(struct xlgmac_pdata *pdata); 40562306a36Sopenharmony_ci void (*disable_rx)(struct xlgmac_pdata *pdata); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci int (*enable_int)(struct xlgmac_channel *channel, 40862306a36Sopenharmony_ci enum xlgmac_int int_id); 40962306a36Sopenharmony_ci int (*disable_int)(struct xlgmac_channel *channel, 41062306a36Sopenharmony_ci enum xlgmac_int int_id); 41162306a36Sopenharmony_ci void (*dev_xmit)(struct xlgmac_channel *channel); 41262306a36Sopenharmony_ci int (*dev_read)(struct xlgmac_channel *channel); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci int (*set_mac_address)(struct xlgmac_pdata *pdata, const u8 *addr); 41562306a36Sopenharmony_ci int (*config_rx_mode)(struct xlgmac_pdata *pdata); 41662306a36Sopenharmony_ci int (*enable_rx_csum)(struct xlgmac_pdata *pdata); 41762306a36Sopenharmony_ci int (*disable_rx_csum)(struct xlgmac_pdata *pdata); 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci /* For MII speed configuration */ 42062306a36Sopenharmony_ci int (*set_xlgmii_25000_speed)(struct xlgmac_pdata *pdata); 42162306a36Sopenharmony_ci int (*set_xlgmii_40000_speed)(struct xlgmac_pdata *pdata); 42262306a36Sopenharmony_ci int (*set_xlgmii_50000_speed)(struct xlgmac_pdata *pdata); 42362306a36Sopenharmony_ci int (*set_xlgmii_100000_speed)(struct xlgmac_pdata *pdata); 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci /* For descriptor related operation */ 42662306a36Sopenharmony_ci void (*tx_desc_init)(struct xlgmac_channel *channel); 42762306a36Sopenharmony_ci void (*rx_desc_init)(struct xlgmac_channel *channel); 42862306a36Sopenharmony_ci void (*tx_desc_reset)(struct xlgmac_desc_data *desc_data); 42962306a36Sopenharmony_ci void (*rx_desc_reset)(struct xlgmac_pdata *pdata, 43062306a36Sopenharmony_ci struct xlgmac_desc_data *desc_data, 43162306a36Sopenharmony_ci unsigned int index); 43262306a36Sopenharmony_ci int (*is_last_desc)(struct xlgmac_dma_desc *dma_desc); 43362306a36Sopenharmony_ci int (*is_context_desc)(struct xlgmac_dma_desc *dma_desc); 43462306a36Sopenharmony_ci void (*tx_start_xmit)(struct xlgmac_channel *channel, 43562306a36Sopenharmony_ci struct xlgmac_ring *ring); 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci /* For Flow Control */ 43862306a36Sopenharmony_ci int (*config_tx_flow_control)(struct xlgmac_pdata *pdata); 43962306a36Sopenharmony_ci int (*config_rx_flow_control)(struct xlgmac_pdata *pdata); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* For Vlan related config */ 44262306a36Sopenharmony_ci int (*enable_rx_vlan_stripping)(struct xlgmac_pdata *pdata); 44362306a36Sopenharmony_ci int (*disable_rx_vlan_stripping)(struct xlgmac_pdata *pdata); 44462306a36Sopenharmony_ci int (*enable_rx_vlan_filtering)(struct xlgmac_pdata *pdata); 44562306a36Sopenharmony_ci int (*disable_rx_vlan_filtering)(struct xlgmac_pdata *pdata); 44662306a36Sopenharmony_ci int (*update_vlan_hash_table)(struct xlgmac_pdata *pdata); 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci /* For RX coalescing */ 44962306a36Sopenharmony_ci int (*config_rx_coalesce)(struct xlgmac_pdata *pdata); 45062306a36Sopenharmony_ci int (*config_tx_coalesce)(struct xlgmac_pdata *pdata); 45162306a36Sopenharmony_ci unsigned int (*usec_to_riwt)(struct xlgmac_pdata *pdata, 45262306a36Sopenharmony_ci unsigned int usec); 45362306a36Sopenharmony_ci unsigned int (*riwt_to_usec)(struct xlgmac_pdata *pdata, 45462306a36Sopenharmony_ci unsigned int riwt); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* For RX and TX threshold config */ 45762306a36Sopenharmony_ci int (*config_rx_threshold)(struct xlgmac_pdata *pdata, 45862306a36Sopenharmony_ci unsigned int val); 45962306a36Sopenharmony_ci int (*config_tx_threshold)(struct xlgmac_pdata *pdata, 46062306a36Sopenharmony_ci unsigned int val); 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci /* For RX and TX Store and Forward Mode config */ 46362306a36Sopenharmony_ci int (*config_rsf_mode)(struct xlgmac_pdata *pdata, 46462306a36Sopenharmony_ci unsigned int val); 46562306a36Sopenharmony_ci int (*config_tsf_mode)(struct xlgmac_pdata *pdata, 46662306a36Sopenharmony_ci unsigned int val); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /* For TX DMA Operate on Second Frame config */ 46962306a36Sopenharmony_ci int (*config_osp_mode)(struct xlgmac_pdata *pdata); 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci /* For RX and TX PBL config */ 47262306a36Sopenharmony_ci int (*config_rx_pbl_val)(struct xlgmac_pdata *pdata); 47362306a36Sopenharmony_ci int (*get_rx_pbl_val)(struct xlgmac_pdata *pdata); 47462306a36Sopenharmony_ci int (*config_tx_pbl_val)(struct xlgmac_pdata *pdata); 47562306a36Sopenharmony_ci int (*get_tx_pbl_val)(struct xlgmac_pdata *pdata); 47662306a36Sopenharmony_ci int (*config_pblx8)(struct xlgmac_pdata *pdata); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci /* For MMC statistics */ 47962306a36Sopenharmony_ci void (*rx_mmc_int)(struct xlgmac_pdata *pdata); 48062306a36Sopenharmony_ci void (*tx_mmc_int)(struct xlgmac_pdata *pdata); 48162306a36Sopenharmony_ci void (*read_mmc_stats)(struct xlgmac_pdata *pdata); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci /* For Receive Side Scaling */ 48462306a36Sopenharmony_ci int (*enable_rss)(struct xlgmac_pdata *pdata); 48562306a36Sopenharmony_ci int (*disable_rss)(struct xlgmac_pdata *pdata); 48662306a36Sopenharmony_ci int (*set_rss_hash_key)(struct xlgmac_pdata *pdata, 48762306a36Sopenharmony_ci const u8 *key); 48862306a36Sopenharmony_ci int (*set_rss_lookup_table)(struct xlgmac_pdata *pdata, 48962306a36Sopenharmony_ci const u32 *table); 49062306a36Sopenharmony_ci}; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci/* This structure contains flags that indicate what hardware features 49362306a36Sopenharmony_ci * or configurations are present in the device. 49462306a36Sopenharmony_ci */ 49562306a36Sopenharmony_cistruct xlgmac_hw_features { 49662306a36Sopenharmony_ci /* HW Version */ 49762306a36Sopenharmony_ci unsigned int version; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci /* HW Feature Register0 */ 50062306a36Sopenharmony_ci unsigned int phyifsel; /* PHY interface support */ 50162306a36Sopenharmony_ci unsigned int vlhash; /* VLAN Hash Filter */ 50262306a36Sopenharmony_ci unsigned int sma; /* SMA(MDIO) Interface */ 50362306a36Sopenharmony_ci unsigned int rwk; /* PMT remote wake-up packet */ 50462306a36Sopenharmony_ci unsigned int mgk; /* PMT magic packet */ 50562306a36Sopenharmony_ci unsigned int mmc; /* RMON module */ 50662306a36Sopenharmony_ci unsigned int aoe; /* ARP Offload */ 50762306a36Sopenharmony_ci unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ 50862306a36Sopenharmony_ci unsigned int eee; /* Energy Efficient Ethernet */ 50962306a36Sopenharmony_ci unsigned int tx_coe; /* Tx Checksum Offload */ 51062306a36Sopenharmony_ci unsigned int rx_coe; /* Rx Checksum Offload */ 51162306a36Sopenharmony_ci unsigned int addn_mac; /* Additional MAC Addresses */ 51262306a36Sopenharmony_ci unsigned int ts_src; /* Timestamp Source */ 51362306a36Sopenharmony_ci unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */ 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* HW Feature Register1 */ 51662306a36Sopenharmony_ci unsigned int rx_fifo_size; /* MTL Receive FIFO Size */ 51762306a36Sopenharmony_ci unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */ 51862306a36Sopenharmony_ci unsigned int adv_ts_hi; /* Advance Timestamping High Word */ 51962306a36Sopenharmony_ci unsigned int dma_width; /* DMA width */ 52062306a36Sopenharmony_ci unsigned int dcb; /* DCB Feature */ 52162306a36Sopenharmony_ci unsigned int sph; /* Split Header Feature */ 52262306a36Sopenharmony_ci unsigned int tso; /* TCP Segmentation Offload */ 52362306a36Sopenharmony_ci unsigned int dma_debug; /* DMA Debug Registers */ 52462306a36Sopenharmony_ci unsigned int rss; /* Receive Side Scaling */ 52562306a36Sopenharmony_ci unsigned int tc_cnt; /* Number of Traffic Classes */ 52662306a36Sopenharmony_ci unsigned int hash_table_size; /* Hash Table Size */ 52762306a36Sopenharmony_ci unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */ 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* HW Feature Register2 */ 53062306a36Sopenharmony_ci unsigned int rx_q_cnt; /* Number of MTL Receive Queues */ 53162306a36Sopenharmony_ci unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */ 53262306a36Sopenharmony_ci unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */ 53362306a36Sopenharmony_ci unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */ 53462306a36Sopenharmony_ci unsigned int pps_out_num; /* Number of PPS outputs */ 53562306a36Sopenharmony_ci unsigned int aux_snap_num; /* Number of Aux snapshot inputs */ 53662306a36Sopenharmony_ci}; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_cistruct xlgmac_resources { 53962306a36Sopenharmony_ci void __iomem *addr; 54062306a36Sopenharmony_ci int irq; 54162306a36Sopenharmony_ci}; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistruct xlgmac_pdata { 54462306a36Sopenharmony_ci struct net_device *netdev; 54562306a36Sopenharmony_ci struct device *dev; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci struct xlgmac_hw_ops hw_ops; 54862306a36Sopenharmony_ci struct xlgmac_desc_ops desc_ops; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci /* Device statistics */ 55162306a36Sopenharmony_ci struct xlgmac_stats stats; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci u32 msg_enable; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci /* MAC registers base */ 55662306a36Sopenharmony_ci void __iomem *mac_regs; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci /* Hardware features of the device */ 55962306a36Sopenharmony_ci struct xlgmac_hw_features hw_feat; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci struct work_struct restart_work; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci /* Rings for Tx/Rx on a DMA channel */ 56462306a36Sopenharmony_ci struct xlgmac_channel *channel_head; 56562306a36Sopenharmony_ci unsigned int channel_count; 56662306a36Sopenharmony_ci unsigned int tx_ring_count; 56762306a36Sopenharmony_ci unsigned int rx_ring_count; 56862306a36Sopenharmony_ci unsigned int tx_desc_count; 56962306a36Sopenharmony_ci unsigned int rx_desc_count; 57062306a36Sopenharmony_ci unsigned int tx_q_count; 57162306a36Sopenharmony_ci unsigned int rx_q_count; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci /* Tx/Rx common settings */ 57462306a36Sopenharmony_ci unsigned int pblx8; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci /* Tx settings */ 57762306a36Sopenharmony_ci unsigned int tx_sf_mode; 57862306a36Sopenharmony_ci unsigned int tx_threshold; 57962306a36Sopenharmony_ci unsigned int tx_pbl; 58062306a36Sopenharmony_ci unsigned int tx_osp_mode; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci /* Rx settings */ 58362306a36Sopenharmony_ci unsigned int rx_sf_mode; 58462306a36Sopenharmony_ci unsigned int rx_threshold; 58562306a36Sopenharmony_ci unsigned int rx_pbl; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci /* Tx coalescing settings */ 58862306a36Sopenharmony_ci unsigned int tx_usecs; 58962306a36Sopenharmony_ci unsigned int tx_frames; 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* Rx coalescing settings */ 59262306a36Sopenharmony_ci unsigned int rx_riwt; 59362306a36Sopenharmony_ci unsigned int rx_usecs; 59462306a36Sopenharmony_ci unsigned int rx_frames; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci /* Current Rx buffer size */ 59762306a36Sopenharmony_ci unsigned int rx_buf_size; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* Flow control settings */ 60062306a36Sopenharmony_ci unsigned int tx_pause; 60162306a36Sopenharmony_ci unsigned int rx_pause; 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci /* Device interrupt number */ 60462306a36Sopenharmony_ci int dev_irq; 60562306a36Sopenharmony_ci unsigned int per_channel_irq; 60662306a36Sopenharmony_ci int channel_irq[XLGMAC_MAX_DMA_CHANNELS]; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci /* Netdev related settings */ 60962306a36Sopenharmony_ci unsigned char mac_addr[ETH_ALEN]; 61062306a36Sopenharmony_ci netdev_features_t netdev_features; 61162306a36Sopenharmony_ci struct napi_struct napi; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci /* Filtering support */ 61462306a36Sopenharmony_ci unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci /* Device clocks */ 61762306a36Sopenharmony_ci unsigned long sysclk_rate; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci /* RSS addressing mutex */ 62062306a36Sopenharmony_ci struct mutex rss_mutex; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* Receive Side Scaling settings */ 62362306a36Sopenharmony_ci u8 rss_key[XLGMAC_RSS_HASH_KEY_SIZE]; 62462306a36Sopenharmony_ci u32 rss_table[XLGMAC_RSS_MAX_TABLE_SIZE]; 62562306a36Sopenharmony_ci u32 rss_options; 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci int phy_speed; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci char drv_name[32]; 63062306a36Sopenharmony_ci char drv_ver[32]; 63162306a36Sopenharmony_ci}; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_civoid xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops); 63462306a36Sopenharmony_civoid xlgmac_init_hw_ops(struct xlgmac_hw_ops *hw_ops); 63562306a36Sopenharmony_ciconst struct net_device_ops *xlgmac_get_netdev_ops(void); 63662306a36Sopenharmony_ciconst struct ethtool_ops *xlgmac_get_ethtool_ops(void); 63762306a36Sopenharmony_civoid xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata, 63862306a36Sopenharmony_ci struct xlgmac_ring *ring, 63962306a36Sopenharmony_ci unsigned int idx, 64062306a36Sopenharmony_ci unsigned int count, 64162306a36Sopenharmony_ci unsigned int flag); 64262306a36Sopenharmony_civoid xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata, 64362306a36Sopenharmony_ci struct xlgmac_ring *ring, 64462306a36Sopenharmony_ci unsigned int idx); 64562306a36Sopenharmony_civoid xlgmac_print_pkt(struct net_device *netdev, 64662306a36Sopenharmony_ci struct sk_buff *skb, bool tx_rx); 64762306a36Sopenharmony_civoid xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata); 64862306a36Sopenharmony_civoid xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata); 64962306a36Sopenharmony_ciint xlgmac_drv_probe(struct device *dev, 65062306a36Sopenharmony_ci struct xlgmac_resources *res); 65162306a36Sopenharmony_ciint xlgmac_drv_remove(struct device *dev); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci/* For debug prints */ 65462306a36Sopenharmony_ci#ifdef XLGMAC_DEBUG 65562306a36Sopenharmony_ci#define XLGMAC_PR(fmt, args...) \ 65662306a36Sopenharmony_ci pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args) 65762306a36Sopenharmony_ci#else 65862306a36Sopenharmony_ci#define XLGMAC_PR(x...) do { } while (0) 65962306a36Sopenharmony_ci#endif 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci#endif /* __DWC_XLGMAC_H__ */ 662