#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/pm_runtime.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <net/page_pool/helpers.h>
#include <net/selftests.h>
#include <net/tso.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/fec.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/regulator/consumer.h>
#include <linux/if_vlan.h>
#include <linux/pinctrl/consumer.h>
#include <linux/gpio/consumer.h>
#include <linux/prefetch.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <soc/imx/cpuidle.h>
#include <linux/filter.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <asm/cacheflush.h>
#include "fec.h"
static void set_multicast_list(struct net_device *ndev);
static void fec_enet_itr_coal_set(struct net_device *ndev);
static int fec_enet_xdp_tx_xmit(struct fec_enet_private *fep,
int cpu, struct xdp_buff *xdp,
u32 dma_sync_len);
#define DRIVER_NAME …
static const u16 fec_enet_vlan_pri_to_queue[8] = …;
#define FEC_ENET_RSEM_V …
#define FEC_ENET_RSFL_V …
#define FEC_ENET_RAEM_V …
#define FEC_ENET_RAFL_V …
#define FEC_ENET_OPD_V …
#define FEC_MDIO_PM_TIMEOUT …
#define FEC_ENET_XDP_PASS …
#define FEC_ENET_XDP_CONSUMED …
#define FEC_ENET_XDP_TX …
#define FEC_ENET_XDP_REDIR …
struct fec_devinfo { … };
static const struct fec_devinfo fec_imx25_info = …;
static const struct fec_devinfo fec_imx27_info = …;
static const struct fec_devinfo fec_imx28_info = …;
static const struct fec_devinfo fec_imx6q_info = …;
static const struct fec_devinfo fec_mvf600_info = …;
static const struct fec_devinfo fec_imx6x_info = …;
static const struct fec_devinfo fec_imx6ul_info = …;
static const struct fec_devinfo fec_imx8mq_info = …;
static const struct fec_devinfo fec_imx8qm_info = …;
static const struct fec_devinfo fec_s32v234_info = …;
static struct platform_device_id fec_devtype[] = …;
MODULE_DEVICE_TABLE(platform, fec_devtype);
static const struct of_device_id fec_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, fec_dt_ids);
static unsigned char macaddr[ETH_ALEN];
module_param_array(…);
MODULE_PARM_DESC(…) …;
#if defined(CONFIG_M5272)
#if defined(CONFIG_NETtel)
#define FEC_FLASHMAC …
#elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES)
#define FEC_FLASHMAC …
#elif defined(CONFIG_CANCam)
#define FEC_FLASHMAC …
#elif defined (CONFIG_M5272C3)
#define FEC_FLASHMAC …
#elif defined(CONFIG_MOD5272)
#define FEC_FLASHMAC …
#else
#define FEC_FLASHMAC …
#endif
#endif
#define PKT_MAXBUF_SIZE …
#define PKT_MINBUF_SIZE …
#define FEC_RACC_IPDIS …
#define FEC_RACC_PRODIS …
#define FEC_RACC_SHIFT16 …
#define FEC_RACC_OPTIONS …
#define FEC_MIB_CTRLSTAT_DISABLE …
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
defined(CONFIG_ARM64)
#define OPT_FRAME_SIZE …
#else
#define OPT_FRAME_SIZE …
#endif
#define FEC_MMFR_ST …
#define FEC_MMFR_ST_C45 …
#define FEC_MMFR_OP_READ …
#define FEC_MMFR_OP_READ_C45 …
#define FEC_MMFR_OP_WRITE …
#define FEC_MMFR_OP_ADDR_WRITE …
#define FEC_MMFR_PA(v) …
#define FEC_MMFR_RA(v) …
#define FEC_MMFR_TA …
#define FEC_MMFR_DATA(v) …
#define FEC_ECR_RESET …
#define FEC_ECR_ETHEREN …
#define FEC_ECR_MAGICEN …
#define FEC_ECR_SLEEP …
#define FEC_ECR_EN1588 …
#define FEC_ECR_BYTESWP …
#define FEC_RCR_LOOP …
#define FEC_RCR_HALFDPX …
#define FEC_RCR_MII …
#define FEC_RCR_PROMISC …
#define FEC_RCR_BC_REJ …
#define FEC_RCR_FLOWCTL …
#define FEC_RCR_RMII …
#define FEC_RCR_10BASET …
#define FEC_TXWMRK_STRFWD …
#define FEC_MII_TIMEOUT …
#define TX_TIMEOUT …
#define FEC_PAUSE_FLAG_AUTONEG …
#define FEC_PAUSE_FLAG_ENABLE …
#define FEC_WOL_HAS_MAGIC_PACKET …
#define FEC_WOL_FLAG_ENABLE …
#define FEC_WOL_FLAG_SLEEP_ON …
#define FEC_MAX_TSO_SEGS …
#define FEC_MAX_SKB_DESCS …
#define IS_TSO_HEADER(txq, addr) …
static int mii_cnt;
static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp,
struct bufdesc_prop *bd)
{ … }
static struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp,
struct bufdesc_prop *bd)
{ … }
static int fec_enet_get_bd_index(struct bufdesc *bdp,
struct bufdesc_prop *bd)
{ … }
static int fec_enet_get_free_txdesc_num(struct fec_enet_priv_tx_q *txq)
{ … }
static void swap_buffer(void *bufaddr, int len)
{ … }
static void fec_dump(struct net_device *ndev)
{ … }
#if defined(CONFIG_COLDFIRE) && !defined(CONFIG_COLDFIRE_COHERENT_DMA)
static void *fec_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp)
{
return dma_alloc_noncoherent(dev, size, handle, DMA_BIDIRECTIONAL, gfp);
}
static void fec_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle)
{
dma_free_noncoherent(dev, size, cpu_addr, handle, DMA_BIDIRECTIONAL);
}
#else
static void *fec_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp)
{ … }
static void fec_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle)
{ … }
#endif
struct fec_dma_devres { … };
static void fec_dmam_release(struct device *dev, void *res)
{ … }
static void *fec_dmam_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp)
{ … }
static inline bool is_ipv4_pkt(struct sk_buff *skb)
{ … }
static int
fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
{ … }
static int
fec_enet_create_page_pool(struct fec_enet_private *fep,
struct fec_enet_priv_rx_q *rxq, int size)
{ … }
static struct bufdesc *
fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
struct sk_buff *skb,
struct net_device *ndev)
{ … }
static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
struct sk_buff *skb, struct net_device *ndev)
{ … }
static int
fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
struct net_device *ndev,
struct bufdesc *bdp, int index, char *data,
int size, bool last_tcp, bool is_last)
{ … }
static int
fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
struct sk_buff *skb, struct net_device *ndev,
struct bufdesc *bdp, int index)
{ … }
static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
struct sk_buff *skb,
struct net_device *ndev)
{ … }
static netdev_tx_t
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{ … }
static void fec_enet_bd_init(struct net_device *dev)
{ … }
static void fec_enet_active_rxring(struct net_device *ndev)
{ … }
static void fec_enet_enable_ring(struct net_device *ndev)
{ … }
static void
fec_restart(struct net_device *ndev)
{ … }
static int fec_enet_ipc_handle_init(struct fec_enet_private *fep)
{ … }
static void fec_enet_ipg_stop_set(struct fec_enet_private *fep, bool enabled)
{ … }
static void fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
{ … }
static void fec_irqs_disable(struct net_device *ndev)
{ … }
static void fec_irqs_disable_except_wakeup(struct net_device *ndev)
{ … }
static void
fec_stop(struct net_device *ndev)
{ … }
static void
fec_timeout(struct net_device *ndev, unsigned int txqueue)
{ … }
static void fec_enet_timeout_work(struct work_struct *work)
{ … }
static void
fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
struct skb_shared_hwtstamps *hwtstamps)
{ … }
static void
fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
{ … }
static void fec_enet_tx(struct net_device *ndev, int budget)
{ … }
static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
struct bufdesc *bdp, int index)
{ … }
static u32
fec_enet_run_xdp(struct fec_enet_private *fep, struct bpf_prog *prog,
struct xdp_buff *xdp, struct fec_enet_priv_rx_q *rxq, int cpu)
{ … }
static int
fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
{ … }
static int fec_enet_rx(struct net_device *ndev, int budget)
{ … }
static bool fec_enet_collect_events(struct fec_enet_private *fep)
{ … }
static irqreturn_t
fec_enet_interrupt(int irq, void *dev_id)
{ … }
static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
{ … }
static int fec_get_mac(struct net_device *ndev)
{ … }
static int fec_enet_us_to_tx_cycle(struct net_device *ndev, int us)
{ … }
static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
{ … }
static void fec_enet_adjust_link(struct net_device *ndev)
{ … }
static int fec_enet_mdio_wait(struct fec_enet_private *fep)
{ … }
static int fec_enet_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
{ … }
static int fec_enet_mdio_read_c45(struct mii_bus *bus, int mii_id,
int devad, int regnum)
{ … }
static int fec_enet_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
u16 value)
{ … }
static int fec_enet_mdio_write_c45(struct mii_bus *bus, int mii_id,
int devad, int regnum, u16 value)
{ … }
static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
{ … }
static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
{ … }
static int fec_enet_parse_rgmii_delay(struct fec_enet_private *fep,
struct device_node *np)
{ … }
static int fec_enet_mii_probe(struct net_device *ndev)
{ … }
static int fec_enet_mii_init(struct platform_device *pdev)
{ … }
static void fec_enet_mii_remove(struct fec_enet_private *fep)
{ … }
static void fec_enet_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{ … }
static int fec_enet_get_regs_len(struct net_device *ndev)
{ … }
#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)
static __u32 fec_enet_register_version = …;
static u32 fec_enet_register_offset[] = …;
static u32 fec_enet_register_offset_6ul[] = …;
#else
static __u32 fec_enet_register_version = 1;
static u32 fec_enet_register_offset[] = {
FEC_ECNTRL, FEC_IEVENT, FEC_IMASK, FEC_IVEC, FEC_R_DES_ACTIVE_0,
FEC_R_DES_ACTIVE_1, FEC_R_DES_ACTIVE_2, FEC_X_DES_ACTIVE_0,
FEC_X_DES_ACTIVE_1, FEC_X_DES_ACTIVE_2, FEC_MII_DATA, FEC_MII_SPEED,
FEC_R_BOUND, FEC_R_FSTART, FEC_X_WMRK, FEC_X_FSTART, FEC_R_CNTRL,
FEC_MAX_FRM_LEN, FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH,
FEC_GRP_HASH_TABLE_HIGH, FEC_GRP_HASH_TABLE_LOW, FEC_R_DES_START_0,
FEC_R_DES_START_1, FEC_R_DES_START_2, FEC_X_DES_START_0,
FEC_X_DES_START_1, FEC_X_DES_START_2, FEC_R_BUFF_SIZE_0,
FEC_R_BUFF_SIZE_1, FEC_R_BUFF_SIZE_2
};
#endif
static void fec_enet_get_regs(struct net_device *ndev,
struct ethtool_regs *regs, void *regbuf)
{ … }
static int fec_enet_get_ts_info(struct net_device *ndev,
struct kernel_ethtool_ts_info *info)
{ … }
#if !defined(CONFIG_M5272)
static void fec_enet_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{ … }
static int fec_enet_set_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{ … }
static const struct fec_stat { … } fec_stats[] = …;
#define FEC_STATS_SIZE …
static const char *fec_xdp_stat_strs[XDP_STATS_TOTAL] = …;
static void fec_enet_update_ethtool_stats(struct net_device *dev)
{ … }
static void fec_enet_get_xdp_stats(struct fec_enet_private *fep, u64 *data)
{ … }
static void fec_enet_page_pool_stats(struct fec_enet_private *fep, u64 *data)
{ … }
static void fec_enet_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{ … }
static void fec_enet_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{ … }
static int fec_enet_get_sset_count(struct net_device *dev, int sset)
{ … }
static void fec_enet_clear_ethtool_stats(struct net_device *dev)
{ … }
#else
#define FEC_STATS_SIZE …
static inline void fec_enet_update_ethtool_stats(struct net_device *dev)
{
}
static inline void fec_enet_clear_ethtool_stats(struct net_device *dev)
{
}
#endif
static int fec_enet_us_to_itr_clock(struct net_device *ndev, int us)
{ … }
static void fec_enet_itr_coal_set(struct net_device *ndev)
{ … }
static int fec_enet_get_coalesce(struct net_device *ndev,
struct ethtool_coalesce *ec,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{ … }
static int fec_enet_set_coalesce(struct net_device *ndev,
struct ethtool_coalesce *ec,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
{ … }
static int
fec_enet_get_eee(struct net_device *ndev, struct ethtool_keee *edata)
{ … }
static int
fec_enet_set_eee(struct net_device *ndev, struct ethtool_keee *edata)
{ … }
static void
fec_enet_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{ … }
static int
fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{ … }
static const struct ethtool_ops fec_enet_ethtool_ops = …;
static void fec_enet_free_buffers(struct net_device *ndev)
{ … }
static void fec_enet_free_queue(struct net_device *ndev)
{ … }
static int fec_enet_alloc_queue(struct net_device *ndev)
{ … }
static int
fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
{ … }
static int
fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
{ … }
static int fec_enet_alloc_buffers(struct net_device *ndev)
{ … }
static int
fec_enet_open(struct net_device *ndev)
{ … }
static int
fec_enet_close(struct net_device *ndev)
{ … }
#define FEC_HASH_BITS …
static void set_multicast_list(struct net_device *ndev)
{ … }
static int
fec_set_mac_address(struct net_device *ndev, void *p)
{ … }
static inline void fec_enet_set_netdev_features(struct net_device *netdev,
netdev_features_t features)
{ … }
static int fec_set_features(struct net_device *netdev,
netdev_features_t features)
{ … }
static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb,
struct net_device *sb_dev)
{ … }
static int fec_enet_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{ … }
static int
fec_enet_xdp_get_tx_queue(struct fec_enet_private *fep, int index)
{ … }
static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
struct fec_enet_priv_tx_q *txq,
void *frame, u32 dma_sync_len,
bool ndo_xmit)
{ … }
static int fec_enet_xdp_tx_xmit(struct fec_enet_private *fep,
int cpu, struct xdp_buff *xdp,
u32 dma_sync_len)
{ … }
static int fec_enet_xdp_xmit(struct net_device *dev,
int num_frames,
struct xdp_frame **frames,
u32 flags)
{ … }
static int fec_hwtstamp_get(struct net_device *ndev,
struct kernel_hwtstamp_config *config)
{ … }
static int fec_hwtstamp_set(struct net_device *ndev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{ … }
static const struct net_device_ops fec_netdev_ops = …;
static const unsigned short offset_des_active_rxq[] = …;
static const unsigned short offset_des_active_txq[] = …;
static int fec_enet_init(struct net_device *ndev)
{ … }
static void fec_enet_deinit(struct net_device *ndev)
{ … }
#ifdef CONFIG_OF
static int fec_reset_phy(struct platform_device *pdev)
{ … }
#else
static int fec_reset_phy(struct platform_device *pdev)
{
return 0;
}
#endif
static void
fec_enet_get_queue_num(struct platform_device *pdev, int *num_tx, int *num_rx)
{ … }
static int fec_enet_get_irq_cnt(struct platform_device *pdev)
{ … }
static void fec_enet_get_wakeup_irq(struct platform_device *pdev)
{ … }
static int fec_enet_init_stop_mode(struct fec_enet_private *fep,
struct device_node *np)
{ … }
static int
fec_probe(struct platform_device *pdev)
{ … }
static void
fec_drv_remove(struct platform_device *pdev)
{ … }
static int fec_suspend(struct device *dev)
{ … }
static int fec_resume(struct device *dev)
{ … }
static int fec_runtime_suspend(struct device *dev)
{ … }
static int fec_runtime_resume(struct device *dev)
{ … }
static const struct dev_pm_ops fec_pm_ops = …;
static struct platform_driver fec_driver = …;
module_platform_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;