mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
534 lines
15 KiB
534 lines
15 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* 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 |
|
*/ |
|
|
|
#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) |
|
|
|
/* SGMII PCS register addresses |
|
*/ |
|
#define SGMII_PCS_SCRATCH 0x10 |
|
#define SGMII_PCS_REV 0x11 |
|
#define SGMII_PCS_LINK_TIMER_0 0x12 |
|
#define SGMII_PCS_LINK_TIMER_1 0x13 |
|
#define SGMII_PCS_IF_MODE 0x14 |
|
#define SGMII_PCS_DIS_READ_TO 0x15 |
|
#define SGMII_PCS_READ_TO 0x16 |
|
#define SGMII_PCS_SW_RESET_TIMEOUT 100 /* usecs */ |
|
|
|
/* 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; |
|
|
|
/* 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; |
|
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__ */
|
|
|