diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec.h')
| -rw-r--r-- | drivers/net/ethernet/freescale/fec.h | 151 |
1 files changed, 115 insertions, 36 deletions
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 2e002e4b4b4a..fd9a93d02f8e 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -14,14 +14,17 @@ #define FEC_H /****************************************************************************/ +#include <dt-bindings/firmware/imx/rsrc.h> +#include <linux/bpf.h> #include <linux/clocksource.h> +#include <linux/firmware/imx/sci.h> #include <linux/net_tstamp.h> +#include <linux/pm_qos.h> #include <linux/ptp_clock_kernel.h> #include <linux/timecounter.h> +#include <net/xdp.h> -#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \ - defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST) +#if !defined(CONFIG_M5272) || defined(CONFIG_COMPILE_TEST) /* * Just figures, Motorola would have to change the offsets for * registers in the same peripheral device on different models @@ -77,6 +80,8 @@ #define FEC_R_DES_ACTIVE_2 0x1e8 /* Rx descriptor active for ring 2 */ #define FEC_X_DES_ACTIVE_2 0x1ec /* Tx descriptor active for ring 2 */ #define FEC_QOS_SCHEME 0x1f0 /* Set multi queues Qos scheme */ +#define FEC_LPI_SLEEP 0x1f4 /* Set IEEE802.3az LPI Sleep Ts time */ +#define FEC_LPI_WAKE 0x1f8 /* Set IEEE802.3az LPI Wake Tw time */ #define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ #define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ @@ -108,7 +113,7 @@ #define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ #define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ #define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */ -#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ +#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excessive collisions */ #define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ #define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ #define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */ @@ -187,6 +192,8 @@ #define FEC_RXIC0 0xfff #define FEC_RXIC1 0xfff #define FEC_RXIC2 0xfff +#define FEC_LPI_SLEEP 0xfff +#define FEC_LPI_WAKE 0xfff #endif /* CONFIG_M5272 */ @@ -233,23 +240,6 @@ struct bufdesc_ex { __fec16 res0[4]; }; -/* - * The following definitions courtesy of commproc.h, which where - * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). - */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ -#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ -#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ -#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ -#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */ -#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ -#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ -#define BD_SC_BR ((ushort)0x0020) /* Break received */ -#define BD_SC_FR ((ushort)0x0010) /* Framing error */ -#define BD_SC_PR ((ushort)0x0008) /* Parity error */ -#define BD_SC_OV ((ushort)0x0002) /* Overrun */ -#define BD_SC_CD ((ushort)0x0001) /* ?? */ - /* Buffer descriptor control/status used by Ethernet receive. */ #define BD_ENET_RX_EMPTY ((ushort)0x8000) @@ -333,19 +323,22 @@ struct bufdesc_ex { #define FEC_TX_BD_FTYPE(X) (((X) & 0xf) << 20) /* The number of Tx and Rx buffers. These are allocated from the page - * pool. The code may assume these are power of two, so it it best + * pool. The code may assume these are power of two, so it is best * to keep them that size. * We don't need to allocate pages for the transmitter. We just use * the skbuffer directly. */ +#define FEC_DRV_RESERVE_SPACE (XDP_PACKET_HEADROOM + \ + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +#define FEC_ENET_XDP_HEADROOM (XDP_PACKET_HEADROOM) #define FEC_ENET_RX_PAGES 256 -#define FEC_ENET_RX_FRSIZE 2048 +#define FEC_ENET_RX_FRSIZE (PAGE_SIZE - FEC_DRV_RESERVE_SPACE) #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE) #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) #define FEC_ENET_TX_FRSIZE 2048 #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE) -#define TX_RING_SIZE 512 /* Must be power of two */ +#define TX_RING_SIZE 1024 /* Must be power of two */ #define TX_RING_MOD_MASK 511 /* for this to work */ #define BD_ENET_RX_INT 0x00800000 @@ -373,12 +366,18 @@ struct bufdesc_ex { #define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */ #define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2) #define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2) +#define FEC_ENET_RXF_GET(X) (((X) == 0) ? FEC_ENET_RXF_0 : \ + (((X) == 1) ? FEC_ENET_RXF_1 : \ + FEC_ENET_RXF_2)) #define FEC_ENET_TS_AVAIL ((uint)0x00010000) #define FEC_ENET_TS_TIMER ((uint)0x00008000) #define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF) #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF)) +#define FEC_ENET_TXC_DLY ((uint)0x00010000) +#define FEC_ENET_RXC_DLY ((uint)0x00020000) + /* ENET interrupt coalescing macro define */ #define FEC_ITR_CLK_SEL (0x1 << 30) #define FEC_ITR_EN (0x1 << 31) @@ -443,7 +442,7 @@ struct bufdesc_ex { #define FEC_QUIRK_SINGLE_MDIO (1 << 11) /* Controller supports RACC register */ #define FEC_QUIRK_HAS_RACC (1 << 12) -/* Controller supports interrupt coalesc */ +/* Controller supports interrupt coalesce */ #define FEC_QUIRK_HAS_COALESCE (1 << 13) /* Interrupt doesn't wake CPU from deep idle */ #define FEC_QUIRK_ERR006687 (1 << 14) @@ -472,6 +471,33 @@ struct bufdesc_ex { */ #define FEC_QUIRK_HAS_MULTI_QUEUES (1 << 19) +/* i.MX8MQ ENET IP version add new feature to support IEEE 802.3az EEE + * standard. For the transmission, MAC supply two user registers to set + * Sleep (TS) and Wake (TW) time. + */ +#define FEC_QUIRK_HAS_EEE (1 << 20) + +/* i.MX8QM ENET IP version add new feature to generate delayed TXC/RXC + * as an alternative option to make sure it works well with various PHYs. + * For the implementation of delayed clock, ENET takes synchronized 250MHz + * clocks to generate 2ns delay. + */ +#define FEC_QUIRK_DELAYED_CLKS_SUPPORT (1 << 21) + +/* i.MX8MQ SoC integration mix wakeup interrupt signal into "int2" interrupt line. */ +#define FEC_QUIRK_WAKEUP_FROM_INT2 (1 << 22) + +/* i.MX6Q adds pm_qos support */ +#define FEC_QUIRK_HAS_PMQOS BIT(23) + +/* Not all FEC hardware block MDIOs support accesses in C45 mode. + * Older blocks in the ColdFire parts do not support it. + */ +#define FEC_QUIRK_HAS_MDIO_C45 BIT(24) + +/* Jumbo Frame support */ +#define FEC_QUIRK_JUMBO_FRAME BIT(25) + struct bufdesc_prop { int qid; /* Address of Rx and Tx buffers */ @@ -485,10 +511,34 @@ struct bufdesc_prop { unsigned char dsize_log2; }; +enum { + RX_XDP_REDIRECT = 0, + RX_XDP_PASS, + RX_XDP_DROP, + RX_XDP_TX, + RX_XDP_TX_ERRORS, + TX_XDP_XMIT, + TX_XDP_XMIT_ERRORS, + + /* The following must be the last one */ + XDP_STATS_TOTAL, +}; + +enum fec_txbuf_type { + FEC_TXBUF_T_SKB, + FEC_TXBUF_T_XDP_NDO, + FEC_TXBUF_T_XDP_TX, +}; + +struct fec_tx_buffer { + void *buf_p; + enum fec_txbuf_type type; +}; + struct fec_enet_priv_tx_q { struct bufdesc_prop bd; unsigned char *tx_bounce[TX_RING_SIZE]; - struct sk_buff *tx_skbuff[TX_RING_SIZE]; + struct fec_tx_buffer tx_buf[TX_RING_SIZE]; unsigned short tx_stop_threshold; unsigned short tx_wake_threshold; @@ -500,7 +550,15 @@ struct fec_enet_priv_tx_q { struct fec_enet_priv_rx_q { struct bufdesc_prop bd; - struct sk_buff *rx_skbuff[RX_RING_SIZE]; + struct page *rx_buf[RX_RING_SIZE]; + + /* page_pool */ + struct page_pool *page_pool; + struct xdp_rxq_info xdp_rxq; + u32 stats[XDP_STATS_TOTAL]; + + /* rx queue number, in the range 0-7 */ + u8 id; }; struct fec_stop_mode_gpr { @@ -528,18 +586,21 @@ struct fec_enet_private { struct clk *clk_ref; struct clk *clk_enet_out; struct clk *clk_ptp; + struct clk *clk_2x_txclk; bool ptp_clk_on; struct mutex ptp_clk_mutex; unsigned int num_tx_queues; unsigned int num_rx_queues; - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct fec_enet_priv_tx_q *tx_queue[FEC_ENET_MAX_TX_QS]; struct fec_enet_priv_rx_q *rx_queue[FEC_ENET_MAX_RX_QS]; unsigned int total_tx_ring_size; unsigned int total_rx_ring_size; + unsigned int max_buf_size; + unsigned int pagepool_order; + unsigned int rx_frame_size; struct platform_device *pdev; @@ -550,6 +611,9 @@ struct fec_enet_private { uint phy_speed; phy_interface_t phy_interface; struct device_node *phy_node; + bool rgmii_txc_dly; + bool rgmii_rxc_dly; + bool rpm_active; int link; int full_duplex; int speed; @@ -557,6 +621,7 @@ struct fec_enet_private { bool bufdesc_ex; int pause_flag; int wol_flag; + int wake_irq; u32 quirks; struct napi_struct napi; @@ -566,21 +631,18 @@ struct fec_enet_private { struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_caps; - unsigned long last_overflow_check; spinlock_t tmreg_lock; struct cyclecounter cc; struct timecounter tc; - int rx_hwtstamp_filter; - u32 base_incval; u32 cycle_speed; int hwts_rx_en; int hwts_tx_en; struct delayed_work time_keep; struct regulator *reg_phy; struct fec_stop_mode_gpr stop_gpr; + struct pm_qos_request pm_qos_req; unsigned int tx_align; - unsigned int rx_align; /* hw interrupt coalesce */ unsigned int rx_pkts_itr; @@ -589,7 +651,7 @@ struct fec_enet_private { unsigned int tx_time_itr; unsigned int itr_clk_rate; - u32 rx_copybreak; + unsigned int clk_ref_rate; /* ptp clock period in ns*/ unsigned int ptp_inc; @@ -599,16 +661,33 @@ struct fec_enet_private { unsigned int reload_period; int pps_enable; unsigned int next_counter; + bool perout_enable; + struct hrtimer perout_timer; + u64 perout_stime; + + struct imx_sc_ipc *ipc_handle; + + /* XDP BPF Program */ + struct bpf_prog *xdp_prog; + + struct { + int pps_enable; + u64 ns_sys, ns_phc; + u32 at_corr; + u8 at_inc_corr; + } ptp_saved_state; u64 ethtool_stats[]; }; void fec_ptp_init(struct platform_device *pdev, int irq_idx); +void fec_ptp_restore_state(struct fec_enet_private *fep); +void fec_ptp_save_state(struct fec_enet_private *fep); void fec_ptp_stop(struct platform_device *pdev); void fec_ptp_start_cyclecounter(struct net_device *ndev); -void fec_ptp_disable_hwts(struct net_device *ndev); -int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); -int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); +int fec_ptp_set(struct net_device *ndev, struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack); +void fec_ptp_get(struct net_device *ndev, struct kernel_hwtstamp_config *config); /****************************************************************************/ #endif /* FEC_H */ |
