/* SPDX-License-Identifier: GPL-2.0-only */
/* 10G controller driver for Samsung SoCs
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Siva Reddy Kallam <siva.kallam@samsung.com>
*/
#ifndef __SXGBE_COMMON_H__
#define __SXGBE_COMMON_H__
/* forward references */
struct sxgbe_desc_ops;
struct sxgbe_dma_ops;
struct sxgbe_mtl_ops;
#define SXGBE_RESOURCE_NAME
"sam_sxgbeeth"
#define DRV_MODULE_VERSION
"November_2013"
/* MAX HW feature words */
#define SXGBE_HW_WORDS
3
#define SXGBE_RX_COE_NONE
0
/* CSR Frequency Access Defines*/
#define SXGBE_CSR_F_150M
150000000
#define SXGBE_CSR_F_250M
250000000
#define SXGBE_CSR_F_300M
300000000
#define SXGBE_CSR_F_350M
350000000
#define SXGBE_CSR_F_400M
400000000
#define SXGBE_CSR_F_500M
500000000
/* pause time */
#define SXGBE_PAUSE_TIME
0x200
/* tx queues */
#define SXGBE_TX_QUEUES
8
#define SXGBE_RX_QUEUES
16
/* Calculated based how much time does it take to fill 256KB Rx memory
* at 10Gb speed at 156MHz clock rate and considered little less then
* the actual value.
*/
#define SXGBE_MAX_DMA_RIWT
0x70
#define SXGBE_MIN_DMA_RIWT
0x01
/* Tx coalesce parameters */
#define SXGBE_COAL_TX_TIMER
40000
#define SXGBE_MAX_COAL_TX_TICK
100000
#define SXGBE_TX_MAX_FRAMES
512
#define SXGBE_TX_FRAMES
128
/* SXGBE TX FIFO is 8K, Rx FIFO is 16K */
#define BUF_SIZE_16KiB
16384
#define BUF_SIZE_8KiB
8192
#define BUF_SIZE_4KiB
4096
#define BUF_SIZE_2KiB
2048
#define SXGBE_DEFAULT_LIT_LS
0x3E8
#define SXGBE_DEFAULT_TWT_LS
0x0
/* Flow Control defines */
#define SXGBE_FLOW_OFF
0
#define SXGBE_FLOW_RX
1
#define SXGBE_FLOW_TX
2
#define SXGBE_FLOW_AUTO (SXGBE_FLOW_TX | SXGBE_FLOW_RX)
#define SF_DMA_MODE
1 /* DMA STORE-AND-FORWARD Operation Mode */
/* errors */
#define RX_GMII_ERR
0x01
#define RX_WATCHDOG_ERR
0x02
#define RX_CRC_ERR
0x03
#define RX_GAINT_ERR
0x04
#define RX_IP_HDR_ERR
0x05
#define RX_PAYLOAD_ERR
0x06
#define RX_OVERFLOW_ERR
0x07
/* pkt type */
#define RX_LEN_PKT
0x00
#define RX_MACCTL_PKT
0x01
#define RX_DCBCTL_PKT
0x02
#define RX_ARP_PKT
0x03
#define RX_OAM_PKT
0x04
#define RX_UNTAG_PKT
0x05
#define RX_OTHER_PKT
0x07
#define RX_SVLAN_PKT
0x08
#define RX_CVLAN_PKT
0x09
#define RX_DVLAN_OCVLAN_ICVLAN_PKT
0x0A
#define RX_DVLAN_OSVLAN_ISVLAN_PKT
0x0B
#define RX_DVLAN_OSVLAN_ICVLAN_PKT
0x0C
#define RX_DVLAN_OCVLAN_ISVLAN_PKT
0x0D
#define RX_NOT_IP_PKT
0x00
#define RX_IPV4_TCP_PKT
0x01
#define RX_IPV4_UDP_PKT
0x02
#define RX_IPV4_ICMP_PKT
0x03
#define RX_IPV4_UNKNOWN_PKT
0x07
#define RX_IPV6_TCP_PKT
0x09
#define RX_IPV6_UDP_PKT
0x0A
#define RX_IPV6_ICMP_PKT
0x0B
#define RX_IPV6_UNKNOWN_PKT
0x0F
#define RX_NO_PTP
0x00
#define RX_PTP_SYNC
0x01
#define RX_PTP_FOLLOW_UP
0x02
#define RX_PTP_DELAY_REQ
0x03
#define RX_PTP_DELAY_RESP
0x04
#define RX_PTP_PDELAY_REQ
0x05
#define RX_PTP_PDELAY_RESP
0x06
#define RX_PTP_PDELAY_FOLLOW_UP
0x07
#define RX_PTP_ANNOUNCE
0x08
#define RX_PTP_MGMT
0x09
#define RX_PTP_SIGNAL
0x0A
#define RX_PTP_RESV_MSG
0x0F
/* EEE-LPI mode flags*/
#define TX_ENTRY_LPI_MODE
0x10
#define TX_EXIT_LPI_MODE
0x20
#define RX_ENTRY_LPI_MODE
0x40
#define RX_EXIT_LPI_MODE
0x80
/* EEE-LPI Interrupt status flag */
#define LPI_INT_STATUS BIT(
5)
/* EEE-LPI Default timer values */
#define LPI_LINK_STATUS_TIMER
0x3E8
#define LPI_MAC_WAIT_TIMER
0x00
/* EEE-LPI Control and status definitions */
#define LPI_CTRL_STATUS_TXA BIT(
19)
#define LPI_CTRL_STATUS_PLSDIS BIT(
18)
#define LPI_CTRL_STATUS_PLS BIT(
17)
#define LPI_CTRL_STATUS_LPIEN BIT(
16)
#define LPI_CTRL_STATUS_TXRSTP BIT(
11)
#define LPI_CTRL_STATUS_RXRSTP BIT(
10)
#define LPI_CTRL_STATUS_RLPIST BIT(
9)
#define LPI_CTRL_STATUS_TLPIST BIT(
8)
#define LPI_CTRL_STATUS_RLPIEX BIT(
3)
#define LPI_CTRL_STATUS_RLPIEN BIT(
2)
#define LPI_CTRL_STATUS_TLPIEX BIT(
1)
#define LPI_CTRL_STATUS_TLPIEN BIT(
0)
enum dma_irq_status {
tx_hard_error = BIT(
0),
tx_bump_tc = BIT(
1),
handle_tx = BIT(
2),
rx_hard_error = BIT(
3),
rx_bump_tc = BIT(
4),
handle_rx = BIT(
5),
};
#define NETIF_F_HW_VLAN_ALL (NETIF_F_HW_VLAN_CTAG_RX | \
NETIF_F_HW_VLAN_STAG_RX | \
NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_HW_VLAN_STAG_TX | \
NETIF_F_HW_VLAN_CTAG_FILTER | \
NETIF_F_HW_VLAN_STAG_FILTER)
/* MMC control defines */
#define SXGBE_MMC_CTRL_CNT_FRZ
0x00000008
/* SXGBE HW ADDR regs */
#define SXGBE_ADDR_HIGH(reg) (((reg >
15) ?
0x00000800 :
0x00000040) + \
(reg *
8))
#define SXGBE_ADDR_LOW(reg) (((reg >
15) ?
0x00000804 :
0x00000044) + \
(reg *
8))
#define SXGBE_MAX_PERFECT_ADDRESSES
32 /* Maximum unicast perfect filtering */
#define SXGBE_FRAME_FILTER
0x00000004
/* Frame Filter */
/* SXGBE Frame Filter defines */
#define SXGBE_FRAME_FILTER_PR
0x00000001
/* Promiscuous Mode */
#define SXGBE_FRAME_FILTER_HUC
0x00000002
/* Hash Unicast */
#define SXGBE_FRAME_FILTER_HMC
0x00000004
/* Hash Multicast */
#define SXGBE_FRAME_FILTER_DAIF
0x00000008
/* DA Inverse Filtering */
#define SXGBE_FRAME_FILTER_PM
0x00000010
/* Pass all multicast */
#define SXGBE_FRAME_FILTER_DBF
0x00000020
/* Disable Broadcast frames */
#define SXGBE_FRAME_FILTER_SAIF
0x00000100
/* Inverse Filtering */
#define SXGBE_FRAME_FILTER_SAF
0x00000200
/* Source Address Filter */
#define SXGBE_FRAME_FILTER_HPF
0x00000400
/* Hash or perfect Filter */
#define SXGBE_FRAME_FILTER_RA
0x80000000
/* Receive all mode */
#define SXGBE_HASH_TABLE_SIZE
64
#define SXGBE_HASH_HIGH
0x00000008
/* Multicast Hash Table High */
#define SXGBE_HASH_LOW
0x0000000c
/* Multicast Hash Table Low */
#define SXGBE_HI_REG_AE
0x80000000
/* Minimum and maximum MTU */
#define MIN_MTU
68
#define MAX_MTU
9000
#define SXGBE_FOR_EACH_QUEUE(max_queues, queue_num) \
for (queue_num =
0; queue_num < max_queues; queue_num++)
#define DRV_VERSION
"1.0.0"
#define SXGBE_MAX_RX_CHANNELS
16
#define SXGBE_MAX_TX_CHANNELS
16
#define START_MAC_REG_OFFSET
0x0000
#define MAX_MAC_REG_OFFSET
0x0DFC
#define START_MTL_REG_OFFSET
0x1000
#define MAX_MTL_REG_OFFSET
0x18FC
#define START_DMA_REG_OFFSET
0x3000
#define MAX_DMA_REG_OFFSET
0x38FC
#define REG_SPACE_SIZE
0x2000
/* sxgbe statistics counters */
struct sxgbe_extra_stats {
/* TX/RX IRQ events */
unsigned long tx_underflow_irq;
unsigned long tx_process_stopped_irq;
unsigned long tx_ctxt_desc_err;
unsigned long tx_threshold;
unsigned long rx_threshold;
unsigned long tx_pkt_n;
unsigned long rx_pkt_n;
unsigned long normal_irq_n;
unsigned long tx_normal_irq_n;
unsigned long rx_normal_irq_n;
unsigned long napi_poll;
unsigned long tx_clean;
unsigned long tx_reset_ic_bit;
unsigned long rx_process_stopped_irq;
unsigned long rx_underflow_irq;
/* Bus access errors */
unsigned long fatal_bus_error_irq;
unsigned long tx_read_transfer_err;
unsigned long tx_write_transfer_err;
unsigned long tx_desc_access_err;
unsigned long tx_buffer_access_err;
unsigned long tx_data_transfer_err;
unsigned long rx_read_transfer_err;
unsigned long rx_write_transfer_err;
unsigned long rx_desc_access_err;
unsigned long rx_buffer_access_err;
unsigned long rx_data_transfer_err;
/* EEE-LPI stats */
unsigned long tx_lpi_entry_n;
unsigned long tx_lpi_exit_n;
unsigned long rx_lpi_entry_n;
unsigned long rx_lpi_exit_n;
unsigned long eee_wakeup_error_n;
/* RX specific */
/* L2 error */
unsigned long rx_code_gmii_err;
unsigned long rx_watchdog_err;
unsigned long rx_crc_err;
unsigned long rx_gaint_pkt_err;
unsigned long ip_hdr_err;
unsigned long ip_payload_err;
unsigned long overflow_error;
/* L2 Pkt type */
unsigned long len_pkt;
unsigned long mac_ctl_pkt;
unsigned long dcb_ctl_pkt;
unsigned long arp_pkt;
unsigned long oam_pkt;
unsigned long untag_okt;
unsigned long other_pkt;
unsigned long svlan_tag_pkt;
unsigned long cvlan_tag_pkt;
unsigned long dvlan_ocvlan_icvlan_pkt;
unsigned long dvlan_osvlan_isvlan_pkt;
unsigned long dvlan_osvlan_icvlan_pkt;
unsigned long dvan_ocvlan_icvlan_pkt;
/* L3/L4 Pkt type */
unsigned long not_ip_pkt;
unsigned long ip4_tcp_pkt;
unsigned long ip4_udp_pkt;
unsigned long ip4_icmp_pkt;
unsigned long ip4_unknown_pkt;
unsigned long ip6_tcp_pkt;
unsigned long ip6_udp_pkt;
unsigned long ip6_icmp_pkt;
unsigned long ip6_unknown_pkt;
/* Filter specific */
unsigned long vlan_filter_match;
unsigned long sa_filter_fail;
unsigned long da_filter_fail;
unsigned long hash_filter_pass;
unsigned long l3_filter_match;
unsigned long l4_filter_match;
/* RX context specific */
unsigned long timestamp_dropped;
unsigned long rx_msg_type_no_ptp;
unsigned long rx_ptp_type_sync;
unsigned long rx_ptp_type_follow_up;
unsigned long rx_ptp_type_delay_req;
unsigned long rx_ptp_type_delay_resp;
unsigned long rx_ptp_type_pdelay_req;
unsigned long rx_ptp_type_pdelay_resp;
unsigned long rx_ptp_type_pdelay_follow_up;
unsigned long rx_ptp_announce;
unsigned long rx_ptp_mgmt;
unsigned long rx_ptp_signal;
unsigned long rx_ptp_resv_msg_type;
};
struct mac_link {
int port;
int duplex;
int speed;
};
struct mii_regs {
unsigned int addr;
/* MII Address */
unsigned int data;
/* MII Data */
};
struct sxgbe_core_ops {
/* MAC core initialization */
void (*core_init)(
void __iomem *ioaddr);
/* Dump MAC registers */
void (*dump_regs)(
void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
int (*host_irq_status)(
void __iomem *ioaddr,
struct sxgbe_extra_stats *x);
/* Set power management mode (e.g. magic frame) */
void (*pmt)(
void __iomem *ioaddr,
unsigned long mode);
/* Set/Get Unicast MAC addresses */
void (*set_umac_addr)(
void __iomem *ioaddr,
const unsigned char *addr,
unsigned int reg_n);
void (*get_umac_addr)(
void __iomem *ioaddr,
unsigned char *addr,
unsigned int reg_n);
void (*enable_rx)(
void __iomem *ioaddr,
bool enable);
void (*enable_tx)(
void __iomem *ioaddr,
bool enable);
/* controller version specific operations */
int (*get_controller_version)(
void __iomem *ioaddr);
/* If supported then get the optional core features */
unsigned int (*get_hw_feature)(
void __iomem *ioaddr,
unsigned char feature_index);
/* adjust SXGBE speed */
void (*set_speed)(
void __iomem *ioaddr,
unsigned char speed);
/* EEE-LPI specific operations */
void (*set_eee_mode)(
void __iomem *ioaddr);
void (*reset_eee_mode)(
void __iomem *ioaddr);
void (*set_eee_timer)(
void __iomem *ioaddr,
const int ls,
const int tw);
void (*set_eee_pls)(
void __iomem *ioaddr,
const int link);
/* Enable disable checksum offload operations */
void (*enable_rx_csum)(
void __iomem *ioaddr);
void (*disable_rx_csum)(
void __iomem *ioaddr);
void (*enable_rxqueue)(
void __iomem *ioaddr,
int queue_num);
void (*disable_rxqueue)(
void __iomem *ioaddr,
int queue_num);
};
const struct sxgbe_core_ops *sxgbe_get_core_ops(
void);
struct sxgbe_ops {
const struct sxgbe_core_ops *mac;
const struct sxgbe_desc_ops *desc;
const struct sxgbe_dma_ops *dma;
const struct sxgbe_mtl_ops *mtl;
struct mii_regs mii;
/* MII register Addresses */
struct mac_link link;
unsigned int ctrl_uid;
unsigned int ctrl_id;
};
/* SXGBE private data structures */
struct sxgbe_tx_queue {
unsigned int irq_no;
struct sxgbe_priv_data *priv_ptr;
struct sxgbe_tx_norm_desc *dma_tx;
dma_addr_t dma_tx_phy;
dma_addr_t *tx_skbuff_dma;
struct sk_buff **tx_skbuff;
struct timer_list txtimer;
unsigned int cur_tx;
unsigned int dirty_tx;
u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
int hwts_tx_en;
u16 prev_mss;
u8 queue_no;
};
struct sxgbe_rx_queue {
struct sxgbe_priv_data *priv_ptr;
struct sxgbe_rx_norm_desc *dma_rx;
struct sk_buff **rx_skbuff;
unsigned int cur_rx;
unsigned int dirty_rx;
unsigned int irq_no;
u32 rx_riwt;
dma_addr_t *rx_skbuff_dma;
dma_addr_t dma_rx_phy;
u8 queue_no;
};
/* SXGBE HW capabilities */
struct sxgbe_hw_features {
/****** CAP [0] *******/
unsigned int pmt_remote_wake_up;
unsigned int pmt_magic_frame;
/* IEEE 1588-2008 */
unsigned int atime_stamp;
unsigned int eee;
unsigned int tx_csum_offload;
unsigned int rx_csum_offload;
unsigned int multi_macaddr;
unsigned int tstamp_srcselect;
unsigned int sa_vlan_insert;
/****** CAP [1] *******/
unsigned int rxfifo_size;
unsigned int txfifo_size;
unsigned int atstmap_hword;
unsigned int dcb_enable;
unsigned int splithead_enable;
unsigned int tcpseg_offload;
unsigned int debug_mem;
unsigned int rss_enable;
unsigned int hash_tsize;
unsigned int l3l4_filer_size;
/* This value is in bytes and
* as mentioned in HW features
* of SXGBE data book
*/
unsigned int rx_mtl_qsize;
unsigned int tx_mtl_qsize;
/****** CAP [2] *******/
/* TX and RX number of channels */
unsigned int rx_mtl_queues;
unsigned int tx_mtl_queues;
unsigned int rx_dma_channels;
unsigned int tx_dma_channels;
unsigned int pps_output_count;
unsigned int aux_input_count;
};
struct sxgbe_priv_data {
/* DMA descriptos */
struct sxgbe_tx_queue *txq[SXGBE_TX_QUEUES];
struct sxgbe_rx_queue *rxq[SXGBE_RX_QUEUES];
u8 cur_rx_qnum;
unsigned int dma_tx_size;
unsigned int dma_rx_size;
unsigned int dma_buf_sz;
u32 rx_riwt;
struct napi_struct napi;
void __iomem *ioaddr;
struct net_device *dev;
struct device *device;
struct sxgbe_ops *hw;
/* sxgbe specific ops */
int no_csum_insertion;
int irq;
int rxcsum_insertion;
spinlock_t stats_lock;
/* lock for tx/rx statatics */
int oldlink;
int speed;
int oldduplex;
struct mii_bus *mii;
int mii_irq[PHY_MAX_ADDR];
u8 rx_pause;
u8 tx_pause;
struct sxgbe_extra_stats xstats;
struct sxgbe_plat_data *plat;
struct sxgbe_hw_features hw_cap;
u32 msg_enable;
struct clk *sxgbe_clk;
int clk_csr;
unsigned int mode;
unsigned int default_addend;
/* advanced time stamp support */
u32 adv_ts;
int use_riwt;
struct ptp_clock *ptp_clock;
/* tc control */
int tx_tc;
int rx_tc;
/* EEE-LPI specific members */
struct timer_list eee_ctrl_timer;
bool tx_path_in_lpi_mode;
int lpi_irq;
int eee_enabled;
int tx_lpi_timer;
};
/* Function prototypes */
struct sxgbe_priv_data *sxgbe_drv_probe(
struct device *device,
struct sxgbe_plat_data *plat_dat,
void __iomem *addr);
void sxgbe_drv_remove(
struct net_device *ndev);
void sxgbe_set_ethtool_ops(
struct net_device *netdev);
int sxgbe_mdio_unregister(
struct net_device *ndev);
int sxgbe_mdio_register(
struct net_device *ndev);
int sxgbe_register_platform(
void);
void sxgbe_unregister_platform(
void);
#ifdef CONFIG_PM
int sxgbe_suspend(
struct net_device *ndev);
int sxgbe_resume(
struct net_device *ndev);
int sxgbe_freeze(
struct net_device *ndev);
int sxgbe_restore(
struct net_device *ndev);
#endif /* CONFIG_PM */
const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(
void);
void sxgbe_disable_eee_mode(
struct sxgbe_priv_data *
const priv);
bool sxgbe_eee_init(
struct sxgbe_priv_data *
const priv);
#endif /* __SXGBE_COMMON_H__ */