| /* Altera Triple-Speed Ethernet MAC driver | |
| * Copyright (C) 2008-2014 Altera Corporation. All rights reserved | |
| * | |
| * Contributors: | |
| * Dalon Westergreen | |
| * Thomas Chou | |
| * Ian Abbott | |
| * Yuriy Kozlov | |
| * Tobias Klauser | |
| * Andriy Smolskyy | |
| * Roman Bulgakov | |
| * Dmytro Mytarchuk | |
| * Matthew Gerlach | |
| * | |
| * Original driver contributed by SLS. | |
| * Major updates contributed by GlobalLogic | |
| * | |
| * This program is free software; you can redistribute it and/or modify it | |
| * under the terms and conditions of the GNU General Public License, | |
| * version 2, as published by the Free Software Foundation. | |
| * | |
| * This program is distributed in the hope it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| * more details. | |
| * | |
| * You should have received a copy of the GNU General Public License along with | |
| * this program. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #ifndef __ALTERA_TSE_H__ | |
| #define __ALTERA_TSE_H__ | |
| #define ALTERA_TSE_RESOURCE_NAME "altera_tse" | |
| #include <linux/bitops.h> | |
| #include <linux/if_vlan.h> | |
| #include <linux/list.h> | |
| #include <linux/netdevice.h> | |
| #include <linux/phy.h> | |
| #define ALTERA_TSE_SW_RESET_WATCHDOG_CNTR 10000 | |
| #define ALTERA_TSE_MAC_FIFO_WIDTH 4 /* TX/RX FIFO width in | |
| * bytes | |
| */ | |
| /* Rx FIFO default settings */ | |
| #define ALTERA_TSE_RX_SECTION_EMPTY 16 | |
| #define ALTERA_TSE_RX_SECTION_FULL 0 | |
| #define ALTERA_TSE_RX_ALMOST_EMPTY 8 | |
| #define ALTERA_TSE_RX_ALMOST_FULL 8 | |
| /* Tx FIFO default settings */ | |
| #define ALTERA_TSE_TX_SECTION_EMPTY 16 | |
| #define ALTERA_TSE_TX_SECTION_FULL 0 | |
| #define ALTERA_TSE_TX_ALMOST_EMPTY 8 | |
| #define ALTERA_TSE_TX_ALMOST_FULL 3 | |
| /* MAC function configuration default settings */ | |
| #define ALTERA_TSE_TX_IPG_LENGTH 12 | |
| #define ALTERA_TSE_PAUSE_QUANTA 0xffff | |
| #define GET_BIT_VALUE(v, bit) (((v) >> (bit)) & 0x1) | |
| /* MAC Command_Config Register Bit Definitions | |
| */ | |
| #define MAC_CMDCFG_TX_ENA BIT(0) | |
| #define MAC_CMDCFG_RX_ENA BIT(1) | |
| #define MAC_CMDCFG_XON_GEN BIT(2) | |
| #define MAC_CMDCFG_ETH_SPEED BIT(3) | |
| #define MAC_CMDCFG_PROMIS_EN BIT(4) | |
| #define MAC_CMDCFG_PAD_EN BIT(5) | |
| #define MAC_CMDCFG_CRC_FWD BIT(6) | |
| #define MAC_CMDCFG_PAUSE_FWD BIT(7) | |
| #define MAC_CMDCFG_PAUSE_IGNORE BIT(8) | |
| #define MAC_CMDCFG_TX_ADDR_INS BIT(9) | |
| #define MAC_CMDCFG_HD_ENA BIT(10) | |
| #define MAC_CMDCFG_EXCESS_COL BIT(11) | |
| #define MAC_CMDCFG_LATE_COL BIT(12) | |
| #define MAC_CMDCFG_SW_RESET BIT(13) | |
| #define MAC_CMDCFG_MHASH_SEL BIT(14) | |
| #define MAC_CMDCFG_LOOP_ENA BIT(15) | |
| #define MAC_CMDCFG_TX_ADDR_SEL(v) (((v) & 0x7) << 16) | |
| #define MAC_CMDCFG_MAGIC_ENA BIT(19) | |
| #define MAC_CMDCFG_SLEEP BIT(20) | |
| #define MAC_CMDCFG_WAKEUP BIT(21) | |
| #define MAC_CMDCFG_XOFF_GEN BIT(22) | |
| #define MAC_CMDCFG_CNTL_FRM_ENA BIT(23) | |
| #define MAC_CMDCFG_NO_LGTH_CHECK BIT(24) | |
| #define MAC_CMDCFG_ENA_10 BIT(25) | |
| #define MAC_CMDCFG_RX_ERR_DISC BIT(26) | |
| #define MAC_CMDCFG_DISABLE_READ_TIMEOUT BIT(27) | |
| #define MAC_CMDCFG_CNT_RESET BIT(31) | |
| #define MAC_CMDCFG_TX_ENA_GET(v) GET_BIT_VALUE(v, 0) | |
| #define MAC_CMDCFG_RX_ENA_GET(v) GET_BIT_VALUE(v, 1) | |
| #define MAC_CMDCFG_XON_GEN_GET(v) GET_BIT_VALUE(v, 2) | |
| #define MAC_CMDCFG_ETH_SPEED_GET(v) GET_BIT_VALUE(v, 3) | |
| #define MAC_CMDCFG_PROMIS_EN_GET(v) GET_BIT_VALUE(v, 4) | |
| #define MAC_CMDCFG_PAD_EN_GET(v) GET_BIT_VALUE(v, 5) | |
| #define MAC_CMDCFG_CRC_FWD_GET(v) GET_BIT_VALUE(v, 6) | |
| #define MAC_CMDCFG_PAUSE_FWD_GET(v) GET_BIT_VALUE(v, 7) | |
| #define MAC_CMDCFG_PAUSE_IGNORE_GET(v) GET_BIT_VALUE(v, 8) | |
| #define MAC_CMDCFG_TX_ADDR_INS_GET(v) GET_BIT_VALUE(v, 9) | |
| #define MAC_CMDCFG_HD_ENA_GET(v) GET_BIT_VALUE(v, 10) | |
| #define MAC_CMDCFG_EXCESS_COL_GET(v) GET_BIT_VALUE(v, 11) | |
| #define MAC_CMDCFG_LATE_COL_GET(v) GET_BIT_VALUE(v, 12) | |
| #define MAC_CMDCFG_SW_RESET_GET(v) GET_BIT_VALUE(v, 13) | |
| #define MAC_CMDCFG_MHASH_SEL_GET(v) GET_BIT_VALUE(v, 14) | |
| #define MAC_CMDCFG_LOOP_ENA_GET(v) GET_BIT_VALUE(v, 15) | |
| #define MAC_CMDCFG_TX_ADDR_SEL_GET(v) (((v) >> 16) & 0x7) | |
| #define MAC_CMDCFG_MAGIC_ENA_GET(v) GET_BIT_VALUE(v, 19) | |
| #define MAC_CMDCFG_SLEEP_GET(v) GET_BIT_VALUE(v, 20) | |
| #define MAC_CMDCFG_WAKEUP_GET(v) GET_BIT_VALUE(v, 21) | |
| #define MAC_CMDCFG_XOFF_GEN_GET(v) GET_BIT_VALUE(v, 22) | |
| #define MAC_CMDCFG_CNTL_FRM_ENA_GET(v) GET_BIT_VALUE(v, 23) | |
| #define MAC_CMDCFG_NO_LGTH_CHECK_GET(v) GET_BIT_VALUE(v, 24) | |
| #define MAC_CMDCFG_ENA_10_GET(v) GET_BIT_VALUE(v, 25) | |
| #define MAC_CMDCFG_RX_ERR_DISC_GET(v) GET_BIT_VALUE(v, 26) | |
| #define MAC_CMDCFG_DISABLE_READ_TIMEOUT_GET(v) GET_BIT_VALUE(v, 27) | |
| #define MAC_CMDCFG_CNT_RESET_GET(v) GET_BIT_VALUE(v, 31) | |
| /* MDIO registers within MAC register Space | |
| */ | |
| struct altera_tse_mdio { | |
| u32 control; /* PHY device operation control register */ | |
| u32 status; /* PHY device operation status register */ | |
| u32 phy_id1; /* Bits 31:16 of PHY identifier */ | |
| u32 phy_id2; /* Bits 15:0 of PHY identifier */ | |
| u32 auto_negotiation_advertisement; /* Auto-negotiation | |
| * advertisement | |
| * register | |
| */ | |
| u32 remote_partner_base_page_ability; | |
| u32 reg6; | |
| u32 reg7; | |
| u32 reg8; | |
| u32 reg9; | |
| u32 rega; | |
| u32 regb; | |
| u32 regc; | |
| u32 regd; | |
| u32 rege; | |
| u32 regf; | |
| u32 reg10; | |
| u32 reg11; | |
| u32 reg12; | |
| u32 reg13; | |
| u32 reg14; | |
| u32 reg15; | |
| u32 reg16; | |
| u32 reg17; | |
| u32 reg18; | |
| u32 reg19; | |
| u32 reg1a; | |
| u32 reg1b; | |
| u32 reg1c; | |
| u32 reg1d; | |
| u32 reg1e; | |
| u32 reg1f; | |
| }; | |
| /* MAC register Space. Note that some of these registers may or may not be | |
| * present depending upon options chosen by the user when the core was | |
| * configured and built. Please consult the Altera Triple Speed Ethernet User | |
| * Guide for details. | |
| */ | |
| struct altera_tse_mac { | |
| /* Bits 15:0: MegaCore function revision (0x0800). Bit 31:16: Customer | |
| * specific revision | |
| */ | |
| u32 megacore_revision; | |
| /* Provides a memory location for user applications to test the device | |
| * memory operation. | |
| */ | |
| u32 scratch_pad; | |
| /* The host processor uses this register to control and configure the | |
| * MAC block | |
| */ | |
| u32 command_config; | |
| /* 32-bit primary MAC address word 0 bits 0 to 31 of the primary | |
| * MAC address | |
| */ | |
| u32 mac_addr_0; | |
| /* 32-bit primary MAC address word 1 bits 32 to 47 of the primary | |
| * MAC address | |
| */ | |
| u32 mac_addr_1; | |
| /* 14-bit maximum frame length. The MAC receive logic */ | |
| u32 frm_length; | |
| /* The pause quanta is used in each pause frame sent to a remote | |
| * Ethernet device, in increments of 512 Ethernet bit times | |
| */ | |
| u32 pause_quanta; | |
| /* 12-bit receive FIFO section-empty threshold */ | |
| u32 rx_section_empty; | |
| /* 12-bit receive FIFO section-full threshold */ | |
| u32 rx_section_full; | |
| /* 12-bit transmit FIFO section-empty threshold */ | |
| u32 tx_section_empty; | |
| /* 12-bit transmit FIFO section-full threshold */ | |
| u32 tx_section_full; | |
| /* 12-bit receive FIFO almost-empty threshold */ | |
| u32 rx_almost_empty; | |
| /* 12-bit receive FIFO almost-full threshold */ | |
| u32 rx_almost_full; | |
| /* 12-bit transmit FIFO almost-empty threshold */ | |
| u32 tx_almost_empty; | |
| /* 12-bit transmit FIFO almost-full threshold */ | |
| u32 tx_almost_full; | |
| /* MDIO address of PHY Device 0. Bits 0 to 4 hold a 5-bit PHY address */ | |
| u32 mdio_phy0_addr; | |
| /* MDIO address of PHY Device 1. Bits 0 to 4 hold a 5-bit PHY address */ | |
| u32 mdio_phy1_addr; | |
| /* Bit[15:0]—16-bit holdoff quanta */ | |
| u32 holdoff_quant; | |
| /* only if 100/1000 BaseX PCS, reserved otherwise */ | |
| u32 reserved1[5]; | |
| /* Minimum IPG between consecutive transmit frame in terms of bytes */ | |
| u32 tx_ipg_length; | |
| /* IEEE 802.3 oEntity Managed Object Support */ | |
| /* The MAC addresses */ | |
| u32 mac_id_1; | |
| u32 mac_id_2; | |
| /* Number of frames transmitted without error including pause frames */ | |
| u32 frames_transmitted_ok; | |
| /* Number of frames received without error including pause frames */ | |
| u32 frames_received_ok; | |
| /* Number of frames received with a CRC error */ | |
| u32 frames_check_sequence_errors; | |
| /* Frame received with an alignment error */ | |
| u32 alignment_errors; | |
| /* Sum of payload and padding octets of frames transmitted without | |
| * error | |
| */ | |
| u32 octets_transmitted_ok; | |
| /* Sum of payload and padding octets of frames received without error */ | |
| u32 octets_received_ok; | |
| /* IEEE 802.3 oPausedEntity Managed Object Support */ | |
| /* Number of transmitted pause frames */ | |
| u32 tx_pause_mac_ctrl_frames; | |
| /* Number of Received pause frames */ | |
| u32 rx_pause_mac_ctrl_frames; | |
| /* IETF MIB (MIB-II) Object Support */ | |
| /* Number of frames received with error */ | |
| u32 if_in_errors; | |
| /* Number of frames transmitted with error */ | |
| u32 if_out_errors; | |
| /* Number of valid received unicast frames */ | |
| u32 if_in_ucast_pkts; | |
| /* Number of valid received multicasts frames (without pause) */ | |
| u32 if_in_multicast_pkts; | |
| /* Number of valid received broadcast frames */ | |
| u32 if_in_broadcast_pkts; | |
| u32 if_out_discards; | |
| /* The number of valid unicast frames transmitted */ | |
| u32 if_out_ucast_pkts; | |
| /* The number of valid multicast frames transmitted, | |
| * excluding pause frames | |
| */ | |
| u32 if_out_multicast_pkts; | |
| u32 if_out_broadcast_pkts; | |
| /* IETF RMON MIB Object Support */ | |
| /* Counts the number of dropped packets due to internal errors | |
| * of the MAC client. | |
| */ | |
| u32 ether_stats_drop_events; | |
| /* Total number of bytes received. Good and bad frames. */ | |
| u32 ether_stats_octets; | |
| /* Total number of packets received. Counts good and bad packets. */ | |
| u32 ether_stats_pkts; | |
| /* Number of packets received with less than 64 bytes. */ | |
| u32 ether_stats_undersize_pkts; | |
| /* The number of frames received that are longer than the | |
| * value configured in the frm_length register | |
| */ | |
| u32 ether_stats_oversize_pkts; | |
| /* Number of received packet with 64 bytes */ | |
| u32 ether_stats_pkts_64_octets; | |
| /* Frames (good and bad) with 65 to 127 bytes */ | |
| u32 ether_stats_pkts_65to127_octets; | |
| /* Frames (good and bad) with 128 to 255 bytes */ | |
| u32 ether_stats_pkts_128to255_octets; | |
| /* Frames (good and bad) with 256 to 511 bytes */ | |
| u32 ether_stats_pkts_256to511_octets; | |
| /* Frames (good and bad) with 512 to 1023 bytes */ | |
| u32 ether_stats_pkts_512to1023_octets; | |
| /* Frames (good and bad) with 1024 to 1518 bytes */ | |
| u32 ether_stats_pkts_1024to1518_octets; | |
| /* Any frame length from 1519 to the maximum length configured in the | |
| * frm_length register, if it is greater than 1518 | |
| */ | |
| u32 ether_stats_pkts_1519tox_octets; | |
| /* Too long frames with CRC error */ | |
| u32 ether_stats_jabbers; | |
| /* Too short frames with CRC error */ | |
| u32 ether_stats_fragments; | |
| u32 reserved2; | |
| /* FIFO control register */ | |
| u32 tx_cmd_stat; | |
| u32 rx_cmd_stat; | |
| /* Extended Statistics Counters */ | |
| u32 msb_octets_transmitted_ok; | |
| u32 msb_octets_received_ok; | |
| u32 msb_ether_stats_octets; | |
| u32 reserved3; | |
| /* Multicast address resolution table, mapped in the controller address | |
| * space | |
| */ | |
| u32 hash_table[64]; | |
| /* Registers 0 to 31 within PHY device 0/1 connected to the MDIO PHY | |
| * management interface | |
| */ | |
| struct altera_tse_mdio mdio_phy0; | |
| struct altera_tse_mdio mdio_phy1; | |
| /* 4 Supplemental MAC Addresses */ | |
| u32 supp_mac_addr_0_0; | |
| u32 supp_mac_addr_0_1; | |
| u32 supp_mac_addr_1_0; | |
| u32 supp_mac_addr_1_1; | |
| u32 supp_mac_addr_2_0; | |
| u32 supp_mac_addr_2_1; | |
| u32 supp_mac_addr_3_0; | |
| u32 supp_mac_addr_3_1; | |
| u32 reserved4[8]; | |
| /* IEEE 1588v2 Feature */ | |
| u32 tx_period; | |
| u32 tx_adjust_fns; | |
| u32 tx_adjust_ns; | |
| u32 rx_period; | |
| u32 rx_adjust_fns; | |
| u32 rx_adjust_ns; | |
| u32 reserved5[42]; | |
| }; | |
| #define tse_csroffs(a) (offsetof(struct altera_tse_mac, a)) | |
| /* Transmit and Receive Command Registers Bit Definitions | |
| */ | |
| #define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC BIT(17) | |
| #define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 BIT(18) | |
| #define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 BIT(25) | |
| /* Wrapper around a pointer to a socket buffer, | |
| * so a DMA handle can be stored along with the buffer | |
| */ | |
| struct tse_buffer { | |
| struct list_head lh; | |
| struct sk_buff *skb; | |
| dma_addr_t dma_addr; | |
| u32 len; | |
| int mapped_as_page; | |
| }; | |
| struct altera_tse_private; | |
| #define ALTERA_DTYPE_SGDMA 1 | |
| #define ALTERA_DTYPE_MSGDMA 2 | |
| /* standard DMA interface for SGDMA and MSGDMA */ | |
| struct altera_dmaops { | |
| int altera_dtype; | |
| int dmamask; | |
| void (*reset_dma)(struct altera_tse_private *); | |
| void (*enable_txirq)(struct altera_tse_private *); | |
| void (*enable_rxirq)(struct altera_tse_private *); | |
| void (*disable_txirq)(struct altera_tse_private *); | |
| void (*disable_rxirq)(struct altera_tse_private *); | |
| void (*clear_txirq)(struct altera_tse_private *); | |
| void (*clear_rxirq)(struct altera_tse_private *); | |
| int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *); | |
| u32 (*tx_completions)(struct altera_tse_private *); | |
| void (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *); | |
| u32 (*get_rx_status)(struct altera_tse_private *); | |
| int (*init_dma)(struct altera_tse_private *); | |
| void (*uninit_dma)(struct altera_tse_private *); | |
| void (*start_rxdma)(struct altera_tse_private *); | |
| }; | |
| /* This structure is private to each device. | |
| */ | |
| struct altera_tse_private { | |
| struct net_device *dev; | |
| struct device *device; | |
| struct napi_struct napi; | |
| /* MAC address space */ | |
| struct altera_tse_mac __iomem *mac_dev; | |
| /* TSE Revision */ | |
| u32 revision; | |
| /* mSGDMA Rx Dispatcher address space */ | |
| void __iomem *rx_dma_csr; | |
| void __iomem *rx_dma_desc; | |
| void __iomem *rx_dma_resp; | |
| /* mSGDMA Tx Dispatcher address space */ | |
| void __iomem *tx_dma_csr; | |
| void __iomem *tx_dma_desc; | |
| /* Rx buffers queue */ | |
| struct tse_buffer *rx_ring; | |
| u32 rx_cons; | |
| u32 rx_prod; | |
| u32 rx_ring_size; | |
| u32 rx_dma_buf_sz; | |
| /* Tx ring buffer */ | |
| struct tse_buffer *tx_ring; | |
| u32 tx_prod; | |
| u32 tx_cons; | |
| u32 tx_ring_size; | |
| /* Interrupts */ | |
| u32 tx_irq; | |
| u32 rx_irq; | |
| /* RX/TX MAC FIFO configs */ | |
| u32 tx_fifo_depth; | |
| u32 rx_fifo_depth; | |
| u32 max_mtu; | |
| /* Hash filter settings */ | |
| u32 hash_filter; | |
| u32 added_unicast; | |
| /* Descriptor memory info for managing SGDMA */ | |
| u32 txdescmem; | |
| u32 rxdescmem; | |
| dma_addr_t rxdescmem_busaddr; | |
| dma_addr_t txdescmem_busaddr; | |
| u32 txctrlreg; | |
| u32 rxctrlreg; | |
| dma_addr_t rxdescphys; | |
| dma_addr_t txdescphys; | |
| struct list_head txlisthd; | |
| struct list_head rxlisthd; | |
| /* MAC command_config register protection */ | |
| spinlock_t mac_cfg_lock; | |
| /* Tx path protection */ | |
| spinlock_t tx_lock; | |
| /* Rx DMA & interrupt control protection */ | |
| spinlock_t rxdma_irq_lock; | |
| /* PHY */ | |
| int phy_addr; /* PHY's MDIO address, -1 for autodetection */ | |
| phy_interface_t phy_iface; | |
| struct mii_bus *mdio; | |
| struct phy_device *phydev; | |
| int oldspeed; | |
| int oldduplex; | |
| int oldlink; | |
| /* ethtool msglvl option */ | |
| u32 msg_enable; | |
| struct altera_dmaops *dmaops; | |
| }; | |
| /* Function prototypes | |
| */ | |
| void altera_tse_set_ethtool_ops(struct net_device *); | |
| static inline | |
| u32 csrrd32(void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| return readl(paddr); | |
| } | |
| static inline | |
| u16 csrrd16(void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| return readw(paddr); | |
| } | |
| static inline | |
| u8 csrrd8(void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| return readb(paddr); | |
| } | |
| static inline | |
| void csrwr32(u32 val, void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| writel(val, paddr); | |
| } | |
| static inline | |
| void csrwr16(u16 val, void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| writew(val, paddr); | |
| } | |
| static inline | |
| void csrwr8(u8 val, void __iomem *mac, size_t offs) | |
| { | |
| void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs); | |
| writeb(val, paddr); | |
| } | |
| #endif /* __ALTERA_TSE_H__ */ |