/* 10G controller driver for Samsung SoCs * * Copyright (C) 2013 Samsung Electronics Co., Ltd. * http://www.samsung.com * * Author: Siva Reddy Kallam * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #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, 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; spinlock_t tx_lock; /* lock for tx queues */ 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 */ struct phy_device *phydev; 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 eee_active; 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); int 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__ */