661 lines
19 KiB
C
661 lines
19 KiB
C
|
/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
|
||
|
*
|
||
|
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com)
|
||
|
*
|
||
|
* This program is dual-licensed; you may select either version 2 of
|
||
|
* the GNU General Public License ("GPL") or BSD license ("BSD").
|
||
|
*
|
||
|
* This Synopsys DWC XLGMAC software driver and associated documentation
|
||
|
* (hereinafter the "Software") is an unsupported proprietary work of
|
||
|
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
|
||
|
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
|
||
|
* Licensed Product under any End User Software License Agreement or
|
||
|
* Agreement for Licensed Products with Synopsys or any supplement thereto.
|
||
|
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
|
||
|
* in the SOFTWARE may be the trademarks of their respective owners.
|
||
|
*/
|
||
|
|
||
|
#ifndef __DWC_XLGMAC_H__
|
||
|
#define __DWC_XLGMAC_H__
|
||
|
|
||
|
#include <linux/dma-mapping.h>
|
||
|
#include <linux/netdevice.h>
|
||
|
#include <linux/workqueue.h>
|
||
|
#include <linux/phy.h>
|
||
|
#include <linux/if_vlan.h>
|
||
|
#include <linux/bitops.h>
|
||
|
#include <linux/timecounter.h>
|
||
|
|
||
|
#define XLGMAC_DRV_NAME "dwc-xlgmac"
|
||
|
#define XLGMAC_DRV_VERSION "1.0.0"
|
||
|
#define XLGMAC_DRV_DESC "Synopsys DWC XLGMAC Driver"
|
||
|
|
||
|
/* Descriptor related parameters */
|
||
|
#define XLGMAC_TX_DESC_CNT 1024
|
||
|
#define XLGMAC_TX_DESC_MIN_FREE (XLGMAC_TX_DESC_CNT >> 3)
|
||
|
#define XLGMAC_TX_DESC_MAX_PROC (XLGMAC_TX_DESC_CNT >> 1)
|
||
|
#define XLGMAC_RX_DESC_CNT 1024
|
||
|
#define XLGMAC_RX_DESC_MAX_DIRTY (XLGMAC_RX_DESC_CNT >> 3)
|
||
|
|
||
|
/* Descriptors required for maximum contiguous TSO/GSO packet */
|
||
|
#define XLGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / XLGMAC_TX_MAX_BUF_SIZE) + 1)
|
||
|
|
||
|
/* Maximum possible descriptors needed for a SKB */
|
||
|
#define XLGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + XLGMAC_TX_MAX_SPLIT + 2)
|
||
|
|
||
|
#define XLGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
|
||
|
#define XLGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
|
||
|
#define XLGMAC_RX_BUF_ALIGN 64
|
||
|
|
||
|
/* Maximum Size for Splitting the Header Data
|
||
|
* Keep in sync with SKB_ALLOC_SIZE
|
||
|
* 3'b000: 64 bytes, 3'b001: 128 bytes
|
||
|
* 3'b010: 256 bytes, 3'b011: 512 bytes
|
||
|
* 3'b100: 1023 bytes , 3'b101'3'b111: Reserved
|
||
|
*/
|
||
|
#define XLGMAC_SPH_HDSMS_SIZE 3
|
||
|
#define XLGMAC_SKB_ALLOC_SIZE 512
|
||
|
|
||
|
#define XLGMAC_MAX_FIFO 81920
|
||
|
|
||
|
#define XLGMAC_MAX_DMA_CHANNELS 16
|
||
|
#define XLGMAC_DMA_STOP_TIMEOUT 5
|
||
|
#define XLGMAC_DMA_INTERRUPT_MASK 0x31c7
|
||
|
|
||
|
/* Default coalescing parameters */
|
||
|
#define XLGMAC_INIT_DMA_TX_USECS 1000
|
||
|
#define XLGMAC_INIT_DMA_TX_FRAMES 25
|
||
|
#define XLGMAC_INIT_DMA_RX_USECS 30
|
||
|
#define XLGMAC_INIT_DMA_RX_FRAMES 25
|
||
|
#define XLGMAC_MAX_DMA_RIWT 0xff
|
||
|
#define XLGMAC_MIN_DMA_RIWT 0x01
|
||
|
|
||
|
/* Flow control queue count */
|
||
|
#define XLGMAC_MAX_FLOW_CONTROL_QUEUES 8
|
||
|
|
||
|
/* System clock is 125 MHz */
|
||
|
#define XLGMAC_SYSCLOCK 125000000
|
||
|
|
||
|
/* Maximum MAC address hash table size (256 bits = 8 bytes) */
|
||
|
#define XLGMAC_MAC_HASH_TABLE_SIZE 8
|
||
|
|
||
|
/* Receive Side Scaling */
|
||
|
#define XLGMAC_RSS_HASH_KEY_SIZE 40
|
||
|
#define XLGMAC_RSS_MAX_TABLE_SIZE 256
|
||
|
#define XLGMAC_RSS_LOOKUP_TABLE_TYPE 0
|
||
|
#define XLGMAC_RSS_HASH_KEY_TYPE 1
|
||
|
|
||
|
#define XLGMAC_STD_PACKET_MTU 1500
|
||
|
#define XLGMAC_JUMBO_PACKET_MTU 9000
|
||
|
|
||
|
/* Helper macro for descriptor handling
|
||
|
* Always use XLGMAC_GET_DESC_DATA to access the descriptor data
|
||
|
*/
|
||
|
#define XLGMAC_GET_DESC_DATA(ring, idx) ({ \
|
||
|
typeof(ring) _ring = (ring); \
|
||
|
((_ring)->desc_data_head + \
|
||
|
((idx) & ((_ring)->dma_desc_count - 1))); \
|
||
|
})
|
||
|
|
||
|
#define XLGMAC_GET_REG_BITS(var, pos, len) ({ \
|
||
|
typeof(pos) _pos = (pos); \
|
||
|
typeof(len) _len = (len); \
|
||
|
((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
|
||
|
})
|
||
|
|
||
|
#define XLGMAC_GET_REG_BITS_LE(var, pos, len) ({ \
|
||
|
typeof(pos) _pos = (pos); \
|
||
|
typeof(len) _len = (len); \
|
||
|
typeof(var) _var = le32_to_cpu((var)); \
|
||
|
((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
|
||
|
})
|
||
|
|
||
|
#define XLGMAC_SET_REG_BITS(var, pos, len, val) ({ \
|
||
|
typeof(var) _var = (var); \
|
||
|
typeof(pos) _pos = (pos); \
|
||
|
typeof(len) _len = (len); \
|
||
|
typeof(val) _val = (val); \
|
||
|
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
|
||
|
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
|
||
|
})
|
||
|
|
||
|
#define XLGMAC_SET_REG_BITS_LE(var, pos, len, val) ({ \
|
||
|
typeof(var) _var = (var); \
|
||
|
typeof(pos) _pos = (pos); \
|
||
|
typeof(len) _len = (len); \
|
||
|
typeof(val) _val = (val); \
|
||
|
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
|
||
|
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
|
||
|
cpu_to_le32(_var); \
|
||
|
})
|
||
|
|
||
|
struct xlgmac_pdata;
|
||
|
|
||
|
enum xlgmac_int {
|
||
|
XLGMAC_INT_DMA_CH_SR_TI,
|
||
|
XLGMAC_INT_DMA_CH_SR_TPS,
|
||
|
XLGMAC_INT_DMA_CH_SR_TBU,
|
||
|
XLGMAC_INT_DMA_CH_SR_RI,
|
||
|
XLGMAC_INT_DMA_CH_SR_RBU,
|
||
|
XLGMAC_INT_DMA_CH_SR_RPS,
|
||
|
XLGMAC_INT_DMA_CH_SR_TI_RI,
|
||
|
XLGMAC_INT_DMA_CH_SR_FBE,
|
||
|
XLGMAC_INT_DMA_ALL,
|
||
|
};
|
||
|
|
||
|
struct xlgmac_stats {
|
||
|
/* MMC TX counters */
|
||
|
u64 txoctetcount_gb;
|
||
|
u64 txframecount_gb;
|
||
|
u64 txbroadcastframes_g;
|
||
|
u64 txmulticastframes_g;
|
||
|
u64 tx64octets_gb;
|
||
|
u64 tx65to127octets_gb;
|
||
|
u64 tx128to255octets_gb;
|
||
|
u64 tx256to511octets_gb;
|
||
|
u64 tx512to1023octets_gb;
|
||
|
u64 tx1024tomaxoctets_gb;
|
||
|
u64 txunicastframes_gb;
|
||
|
u64 txmulticastframes_gb;
|
||
|
u64 txbroadcastframes_gb;
|
||
|
u64 txunderflowerror;
|
||
|
u64 txoctetcount_g;
|
||
|
u64 txframecount_g;
|
||
|
u64 txpauseframes;
|
||
|
u64 txvlanframes_g;
|
||
|
|
||
|
/* MMC RX counters */
|
||
|
u64 rxframecount_gb;
|
||
|
u64 rxoctetcount_gb;
|
||
|
u64 rxoctetcount_g;
|
||
|
u64 rxbroadcastframes_g;
|
||
|
u64 rxmulticastframes_g;
|
||
|
u64 rxcrcerror;
|
||
|
u64 rxrunterror;
|
||
|
u64 rxjabbererror;
|
||
|
u64 rxundersize_g;
|
||
|
u64 rxoversize_g;
|
||
|
u64 rx64octets_gb;
|
||
|
u64 rx65to127octets_gb;
|
||
|
u64 rx128to255octets_gb;
|
||
|
u64 rx256to511octets_gb;
|
||
|
u64 rx512to1023octets_gb;
|
||
|
u64 rx1024tomaxoctets_gb;
|
||
|
u64 rxunicastframes_g;
|
||
|
u64 rxlengtherror;
|
||
|
u64 rxoutofrangetype;
|
||
|
u64 rxpauseframes;
|
||
|
u64 rxfifooverflow;
|
||
|
u64 rxvlanframes_gb;
|
||
|
u64 rxwatchdogerror;
|
||
|
|
||
|
/* Extra counters */
|
||
|
u64 tx_tso_packets;
|
||
|
u64 rx_split_header_packets;
|
||
|
u64 tx_process_stopped;
|
||
|
u64 rx_process_stopped;
|
||
|
u64 tx_buffer_unavailable;
|
||
|
u64 rx_buffer_unavailable;
|
||
|
u64 fatal_bus_error;
|
||
|
u64 tx_vlan_packets;
|
||
|
u64 rx_vlan_packets;
|
||
|
u64 napi_poll_isr;
|
||
|
u64 napi_poll_txtimer;
|
||
|
};
|
||
|
|
||
|
struct xlgmac_ring_buf {
|
||
|
struct sk_buff *skb;
|
||
|
dma_addr_t skb_dma;
|
||
|
unsigned int skb_len;
|
||
|
};
|
||
|
|
||
|
/* Common Tx and Rx DMA hardware descriptor */
|
||
|
struct xlgmac_dma_desc {
|
||
|
__le32 desc0;
|
||
|
__le32 desc1;
|
||
|
__le32 desc2;
|
||
|
__le32 desc3;
|
||
|
};
|
||
|
|
||
|
/* Page allocation related values */
|
||
|
struct xlgmac_page_alloc {
|
||
|
struct page *pages;
|
||
|
unsigned int pages_len;
|
||
|
unsigned int pages_offset;
|
||
|
|
||
|
dma_addr_t pages_dma;
|
||
|
};
|
||
|
|
||
|
/* Ring entry buffer data */
|
||
|
struct xlgmac_buffer_data {
|
||
|
struct xlgmac_page_alloc pa;
|
||
|
struct xlgmac_page_alloc pa_unmap;
|
||
|
|
||
|
dma_addr_t dma_base;
|
||
|
unsigned long dma_off;
|
||
|
unsigned int dma_len;
|
||
|
};
|
||
|
|
||
|
/* Tx-related desc data */
|
||
|
struct xlgmac_tx_desc_data {
|
||
|
unsigned int packets; /* BQL packet count */
|
||
|
unsigned int bytes; /* BQL byte count */
|
||
|
};
|
||
|
|
||
|
/* Rx-related desc data */
|
||
|
struct xlgmac_rx_desc_data {
|
||
|
struct xlgmac_buffer_data hdr; /* Header locations */
|
||
|
struct xlgmac_buffer_data buf; /* Payload locations */
|
||
|
|
||
|
unsigned short hdr_len; /* Length of received header */
|
||
|
unsigned short len; /* Length of received packet */
|
||
|
};
|
||
|
|
||
|
struct xlgmac_pkt_info {
|
||
|
struct sk_buff *skb;
|
||
|
|
||
|
unsigned int attributes;
|
||
|
|
||
|
unsigned int errors;
|
||
|
|
||
|
/* descriptors needed for this packet */
|
||
|
unsigned int desc_count;
|
||
|
unsigned int length;
|
||
|
|
||
|
unsigned int tx_packets;
|
||
|
unsigned int tx_bytes;
|
||
|
|
||
|
unsigned int header_len;
|
||
|
unsigned int tcp_header_len;
|
||
|
unsigned int tcp_payload_len;
|
||
|
unsigned short mss;
|
||
|
|
||
|
unsigned short vlan_ctag;
|
||
|
|
||
|
u64 rx_tstamp;
|
||
|
|
||
|
u32 rss_hash;
|
||
|
enum pkt_hash_types rss_hash_type;
|
||
|
};
|
||
|
|
||
|
struct xlgmac_desc_data {
|
||
|
/* dma_desc: Virtual address of descriptor
|
||
|
* dma_desc_addr: DMA address of descriptor
|
||
|
*/
|
||
|
struct xlgmac_dma_desc *dma_desc;
|
||
|
dma_addr_t dma_desc_addr;
|
||
|
|
||
|
/* skb: Virtual address of SKB
|
||
|
* skb_dma: DMA address of SKB data
|
||
|
* skb_dma_len: Length of SKB DMA area
|
||
|
*/
|
||
|
struct sk_buff *skb;
|
||
|
dma_addr_t skb_dma;
|
||
|
unsigned int skb_dma_len;
|
||
|
|
||
|
/* Tx/Rx -related data */
|
||
|
struct xlgmac_tx_desc_data tx;
|
||
|
struct xlgmac_rx_desc_data rx;
|
||
|
|
||
|
unsigned int mapped_as_page;
|
||
|
|
||
|
/* Incomplete receive save location. If the budget is exhausted
|
||
|
* or the last descriptor (last normal descriptor or a following
|
||
|
* context descriptor) has not been DMA'd yet the current state
|
||
|
* of the receive processing needs to be saved.
|
||
|
*/
|
||
|
unsigned int state_saved;
|
||
|
struct {
|
||
|
struct sk_buff *skb;
|
||
|
unsigned int len;
|
||
|
unsigned int error;
|
||
|
} state;
|
||
|
};
|
||
|
|
||
|
struct xlgmac_ring {
|
||
|
/* Per packet related information */
|
||
|
struct xlgmac_pkt_info pkt_info;
|
||
|
|
||
|
/* Virtual/DMA addresses of DMA descriptor list and the total count */
|
||
|
struct xlgmac_dma_desc *dma_desc_head;
|
||
|
dma_addr_t dma_desc_head_addr;
|
||
|
unsigned int dma_desc_count;
|
||
|
|
||
|
/* Array of descriptor data corresponding the DMA descriptor
|
||
|
* (always use the XLGMAC_GET_DESC_DATA macro to access this data)
|
||
|
*/
|
||
|
struct xlgmac_desc_data *desc_data_head;
|
||
|
|
||
|
/* Page allocation for RX buffers */
|
||
|
struct xlgmac_page_alloc rx_hdr_pa;
|
||
|
struct xlgmac_page_alloc rx_buf_pa;
|
||
|
|
||
|
/* Ring index values
|
||
|
* cur - Tx: index of descriptor to be used for current transfer
|
||
|
* Rx: index of descriptor to check for packet availability
|
||
|
* dirty - Tx: index of descriptor to check for transfer complete
|
||
|
* Rx: index of descriptor to check for buffer reallocation
|
||
|
*/
|
||
|
unsigned int cur;
|
||
|
unsigned int dirty;
|
||
|
|
||
|
/* Coalesce frame count used for interrupt bit setting */
|
||
|
unsigned int coalesce_count;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
unsigned int xmit_more;
|
||
|
unsigned int queue_stopped;
|
||
|
unsigned short cur_mss;
|
||
|
unsigned short cur_vlan_ctag;
|
||
|
} tx;
|
||
|
};
|
||
|
} ____cacheline_aligned;
|
||
|
|
||
|
struct xlgmac_channel {
|
||
|
char name[16];
|
||
|
|
||
|
/* Address of private data area for device */
|
||
|
struct xlgmac_pdata *pdata;
|
||
|
|
||
|
/* Queue index and base address of queue's DMA registers */
|
||
|
unsigned int queue_index;
|
||
|
void __iomem *dma_regs;
|
||
|
|
||
|
/* Per channel interrupt irq number */
|
||
|
int dma_irq;
|
||
|
char dma_irq_name[IFNAMSIZ + 32];
|
||
|
|
||
|
/* Netdev related settings */
|
||
|
struct napi_struct napi;
|
||
|
|
||
|
unsigned int saved_ier;
|
||
|
|
||
|
unsigned int tx_timer_active;
|
||
|
struct timer_list tx_timer;
|
||
|
|
||
|
struct xlgmac_ring *tx_ring;
|
||
|
struct xlgmac_ring *rx_ring;
|
||
|
} ____cacheline_aligned;
|
||
|
|
||
|
struct xlgmac_desc_ops {
|
||
|
int (*alloc_channles_and_rings)(struct xlgmac_pdata *pdata);
|
||
|
void (*free_channels_and_rings)(struct xlgmac_pdata *pdata);
|
||
|
int (*map_tx_skb)(struct xlgmac_channel *channel,
|
||
|
struct sk_buff *skb);
|
||
|
int (*map_rx_buffer)(struct xlgmac_pdata *pdata,
|
||
|
struct xlgmac_ring *ring,
|
||
|
struct xlgmac_desc_data *desc_data);
|
||
|
void (*unmap_desc_data)(struct xlgmac_pdata *pdata,
|
||
|
struct xlgmac_desc_data *desc_data);
|
||
|
void (*tx_desc_init)(struct xlgmac_pdata *pdata);
|
||
|
void (*rx_desc_init)(struct xlgmac_pdata *pdata);
|
||
|
};
|
||
|
|
||
|
struct xlgmac_hw_ops {
|
||
|
int (*init)(struct xlgmac_pdata *pdata);
|
||
|
int (*exit)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
int (*tx_complete)(struct xlgmac_dma_desc *dma_desc);
|
||
|
|
||
|
void (*enable_tx)(struct xlgmac_pdata *pdata);
|
||
|
void (*disable_tx)(struct xlgmac_pdata *pdata);
|
||
|
void (*enable_rx)(struct xlgmac_pdata *pdata);
|
||
|
void (*disable_rx)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
int (*enable_int)(struct xlgmac_channel *channel,
|
||
|
enum xlgmac_int int_id);
|
||
|
int (*disable_int)(struct xlgmac_channel *channel,
|
||
|
enum xlgmac_int int_id);
|
||
|
void (*dev_xmit)(struct xlgmac_channel *channel);
|
||
|
int (*dev_read)(struct xlgmac_channel *channel);
|
||
|
|
||
|
int (*set_mac_address)(struct xlgmac_pdata *pdata, u8 *addr);
|
||
|
int (*config_rx_mode)(struct xlgmac_pdata *pdata);
|
||
|
int (*enable_rx_csum)(struct xlgmac_pdata *pdata);
|
||
|
int (*disable_rx_csum)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For MII speed configuration */
|
||
|
int (*set_xlgmii_25000_speed)(struct xlgmac_pdata *pdata);
|
||
|
int (*set_xlgmii_40000_speed)(struct xlgmac_pdata *pdata);
|
||
|
int (*set_xlgmii_50000_speed)(struct xlgmac_pdata *pdata);
|
||
|
int (*set_xlgmii_100000_speed)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For descriptor related operation */
|
||
|
void (*tx_desc_init)(struct xlgmac_channel *channel);
|
||
|
void (*rx_desc_init)(struct xlgmac_channel *channel);
|
||
|
void (*tx_desc_reset)(struct xlgmac_desc_data *desc_data);
|
||
|
void (*rx_desc_reset)(struct xlgmac_pdata *pdata,
|
||
|
struct xlgmac_desc_data *desc_data,
|
||
|
unsigned int index);
|
||
|
int (*is_last_desc)(struct xlgmac_dma_desc *dma_desc);
|
||
|
int (*is_context_desc)(struct xlgmac_dma_desc *dma_desc);
|
||
|
void (*tx_start_xmit)(struct xlgmac_channel *channel,
|
||
|
struct xlgmac_ring *ring);
|
||
|
|
||
|
/* For Flow Control */
|
||
|
int (*config_tx_flow_control)(struct xlgmac_pdata *pdata);
|
||
|
int (*config_rx_flow_control)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For Vlan related config */
|
||
|
int (*enable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
|
||
|
int (*disable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
|
||
|
int (*enable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
|
||
|
int (*disable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
|
||
|
int (*update_vlan_hash_table)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For RX coalescing */
|
||
|
int (*config_rx_coalesce)(struct xlgmac_pdata *pdata);
|
||
|
int (*config_tx_coalesce)(struct xlgmac_pdata *pdata);
|
||
|
unsigned int (*usec_to_riwt)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int usec);
|
||
|
unsigned int (*riwt_to_usec)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int riwt);
|
||
|
|
||
|
/* For RX and TX threshold config */
|
||
|
int (*config_rx_threshold)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int val);
|
||
|
int (*config_tx_threshold)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int val);
|
||
|
|
||
|
/* For RX and TX Store and Forward Mode config */
|
||
|
int (*config_rsf_mode)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int val);
|
||
|
int (*config_tsf_mode)(struct xlgmac_pdata *pdata,
|
||
|
unsigned int val);
|
||
|
|
||
|
/* For TX DMA Operate on Second Frame config */
|
||
|
int (*config_osp_mode)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For RX and TX PBL config */
|
||
|
int (*config_rx_pbl_val)(struct xlgmac_pdata *pdata);
|
||
|
int (*get_rx_pbl_val)(struct xlgmac_pdata *pdata);
|
||
|
int (*config_tx_pbl_val)(struct xlgmac_pdata *pdata);
|
||
|
int (*get_tx_pbl_val)(struct xlgmac_pdata *pdata);
|
||
|
int (*config_pblx8)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For MMC statistics */
|
||
|
void (*rx_mmc_int)(struct xlgmac_pdata *pdata);
|
||
|
void (*tx_mmc_int)(struct xlgmac_pdata *pdata);
|
||
|
void (*read_mmc_stats)(struct xlgmac_pdata *pdata);
|
||
|
|
||
|
/* For Receive Side Scaling */
|
||
|
int (*enable_rss)(struct xlgmac_pdata *pdata);
|
||
|
int (*disable_rss)(struct xlgmac_pdata *pdata);
|
||
|
int (*set_rss_hash_key)(struct xlgmac_pdata *pdata,
|
||
|
const u8 *key);
|
||
|
int (*set_rss_lookup_table)(struct xlgmac_pdata *pdata,
|
||
|
const u32 *table);
|
||
|
};
|
||
|
|
||
|
/* This structure contains flags that indicate what hardware features
|
||
|
* or configurations are present in the device.
|
||
|
*/
|
||
|
struct xlgmac_hw_features {
|
||
|
/* HW Version */
|
||
|
unsigned int version;
|
||
|
|
||
|
/* HW Feature Register0 */
|
||
|
unsigned int phyifsel; /* PHY interface support */
|
||
|
unsigned int vlhash; /* VLAN Hash Filter */
|
||
|
unsigned int sma; /* SMA(MDIO) Interface */
|
||
|
unsigned int rwk; /* PMT remote wake-up packet */
|
||
|
unsigned int mgk; /* PMT magic packet */
|
||
|
unsigned int mmc; /* RMON module */
|
||
|
unsigned int aoe; /* ARP Offload */
|
||
|
unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */
|
||
|
unsigned int eee; /* Energy Efficient Ethernet */
|
||
|
unsigned int tx_coe; /* Tx Checksum Offload */
|
||
|
unsigned int rx_coe; /* Rx Checksum Offload */
|
||
|
unsigned int addn_mac; /* Additional MAC Addresses */
|
||
|
unsigned int ts_src; /* Timestamp Source */
|
||
|
unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
|
||
|
|
||
|
/* HW Feature Register1 */
|
||
|
unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
|
||
|
unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
|
||
|
unsigned int adv_ts_hi; /* Advance Timestamping High Word */
|
||
|
unsigned int dma_width; /* DMA width */
|
||
|
unsigned int dcb; /* DCB Feature */
|
||
|
unsigned int sph; /* Split Header Feature */
|
||
|
unsigned int tso; /* TCP Segmentation Offload */
|
||
|
unsigned int dma_debug; /* DMA Debug Registers */
|
||
|
unsigned int rss; /* Receive Side Scaling */
|
||
|
unsigned int tc_cnt; /* Number of Traffic Classes */
|
||
|
unsigned int hash_table_size; /* Hash Table Size */
|
||
|
unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
|
||
|
|
||
|
/* HW Feature Register2 */
|
||
|
unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
|
||
|
unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
|
||
|
unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
|
||
|
unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
|
||
|
unsigned int pps_out_num; /* Number of PPS outputs */
|
||
|
unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
|
||
|
};
|
||
|
|
||
|
struct xlgmac_resources {
|
||
|
void __iomem *addr;
|
||
|
int irq;
|
||
|
};
|
||
|
|
||
|
struct xlgmac_pdata {
|
||
|
struct net_device *netdev;
|
||
|
struct device *dev;
|
||
|
|
||
|
struct xlgmac_hw_ops hw_ops;
|
||
|
struct xlgmac_desc_ops desc_ops;
|
||
|
|
||
|
/* Device statistics */
|
||
|
struct xlgmac_stats stats;
|
||
|
|
||
|
u32 msg_enable;
|
||
|
|
||
|
/* MAC registers base */
|
||
|
void __iomem *mac_regs;
|
||
|
|
||
|
/* Hardware features of the device */
|
||
|
struct xlgmac_hw_features hw_feat;
|
||
|
|
||
|
struct work_struct restart_work;
|
||
|
|
||
|
/* Rings for Tx/Rx on a DMA channel */
|
||
|
struct xlgmac_channel *channel_head;
|
||
|
unsigned int channel_count;
|
||
|
unsigned int tx_ring_count;
|
||
|
unsigned int rx_ring_count;
|
||
|
unsigned int tx_desc_count;
|
||
|
unsigned int rx_desc_count;
|
||
|
unsigned int tx_q_count;
|
||
|
unsigned int rx_q_count;
|
||
|
|
||
|
/* Tx/Rx common settings */
|
||
|
unsigned int pblx8;
|
||
|
|
||
|
/* Tx settings */
|
||
|
unsigned int tx_sf_mode;
|
||
|
unsigned int tx_threshold;
|
||
|
unsigned int tx_pbl;
|
||
|
unsigned int tx_osp_mode;
|
||
|
|
||
|
/* Rx settings */
|
||
|
unsigned int rx_sf_mode;
|
||
|
unsigned int rx_threshold;
|
||
|
unsigned int rx_pbl;
|
||
|
|
||
|
/* Tx coalescing settings */
|
||
|
unsigned int tx_usecs;
|
||
|
unsigned int tx_frames;
|
||
|
|
||
|
/* Rx coalescing settings */
|
||
|
unsigned int rx_riwt;
|
||
|
unsigned int rx_usecs;
|
||
|
unsigned int rx_frames;
|
||
|
|
||
|
/* Current Rx buffer size */
|
||
|
unsigned int rx_buf_size;
|
||
|
|
||
|
/* Flow control settings */
|
||
|
unsigned int tx_pause;
|
||
|
unsigned int rx_pause;
|
||
|
|
||
|
/* Device interrupt number */
|
||
|
int dev_irq;
|
||
|
unsigned int per_channel_irq;
|
||
|
int channel_irq[XLGMAC_MAX_DMA_CHANNELS];
|
||
|
|
||
|
/* Netdev related settings */
|
||
|
unsigned char mac_addr[ETH_ALEN];
|
||
|
netdev_features_t netdev_features;
|
||
|
struct napi_struct napi;
|
||
|
|
||
|
/* Filtering support */
|
||
|
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||
|
|
||
|
/* Device clocks */
|
||
|
unsigned long sysclk_rate;
|
||
|
|
||
|
/* RSS addressing mutex */
|
||
|
struct mutex rss_mutex;
|
||
|
|
||
|
/* Receive Side Scaling settings */
|
||
|
u8 rss_key[XLGMAC_RSS_HASH_KEY_SIZE];
|
||
|
u32 rss_table[XLGMAC_RSS_MAX_TABLE_SIZE];
|
||
|
u32 rss_options;
|
||
|
|
||
|
int phy_speed;
|
||
|
|
||
|
char drv_name[32];
|
||
|
char drv_ver[32];
|
||
|
};
|
||
|
|
||
|
void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops);
|
||
|
void xlgmac_init_hw_ops(struct xlgmac_hw_ops *hw_ops);
|
||
|
const struct net_device_ops *xlgmac_get_netdev_ops(void);
|
||
|
const struct ethtool_ops *xlgmac_get_ethtool_ops(void);
|
||
|
void xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata,
|
||
|
struct xlgmac_ring *ring,
|
||
|
unsigned int idx,
|
||
|
unsigned int count,
|
||
|
unsigned int flag);
|
||
|
void xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata,
|
||
|
struct xlgmac_ring *ring,
|
||
|
unsigned int idx);
|
||
|
void xlgmac_print_pkt(struct net_device *netdev,
|
||
|
struct sk_buff *skb, bool tx_rx);
|
||
|
void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata);
|
||
|
void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata);
|
||
|
int xlgmac_drv_probe(struct device *dev,
|
||
|
struct xlgmac_resources *res);
|
||
|
int xlgmac_drv_remove(struct device *dev);
|
||
|
|
||
|
/* For debug prints */
|
||
|
#ifdef XLGMAC_DEBUG
|
||
|
#define XLGMAC_PR(fmt, args...) \
|
||
|
pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args)
|
||
|
#else
|
||
|
#define XLGMAC_PR(x...) do { } while (0)
|
||
|
#endif
|
||
|
|
||
|
#endif /* __DWC_XLGMAC_H__ */
|