linux/drivers/net/usb/lan78xx.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Microchip Technology
 */
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/if_vlan.h>
#include <linux/uaccess.h>
#include <linux/linkmode.h>
#include <linux/list.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <net/ip6_checksum.h>
#include <net/vxlan.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/microchipphy.h>
#include <linux/phy_fixed.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "lan78xx.h"

#define DRIVER_AUTHOR
#define DRIVER_DESC
#define DRIVER_NAME

#define TX_TIMEOUT_JIFFIES
#define THROTTLE_JIFFIES
#define UNLINK_TIMEOUT_MS

#define RX_MAX_QUEUE_MEMORY

#define SS_USB_PKT_SIZE
#define HS_USB_PKT_SIZE
#define FS_USB_PKT_SIZE

#define MAX_RX_FIFO_SIZE
#define MAX_TX_FIFO_SIZE

#define FLOW_THRESHOLD(n)
#define FLOW_CTRL_THRESHOLD(on, off)

/* Flow control turned on when Rx FIFO level rises above this level (bytes) */
#define FLOW_ON_SS
#define FLOW_ON_HS

/* Flow control turned off when Rx FIFO level falls below this level (bytes) */
#define FLOW_OFF_SS
#define FLOW_OFF_HS

#define DEFAULT_BURST_CAP_SIZE
#define DEFAULT_BULK_IN_DELAY
#define MAX_SINGLE_PACKET_SIZE
#define DEFAULT_TX_CSUM_ENABLE
#define DEFAULT_RX_CSUM_ENABLE
#define DEFAULT_TSO_CSUM_ENABLE
#define DEFAULT_VLAN_FILTER_ENABLE
#define DEFAULT_VLAN_RX_OFFLOAD
#define TX_ALIGNMENT
#define RXW_PADDING

#define LAN78XX_USB_VENDOR_ID
#define LAN7800_USB_PRODUCT_ID
#define LAN7850_USB_PRODUCT_ID
#define LAN7801_USB_PRODUCT_ID
#define LAN78XX_EEPROM_MAGIC
#define LAN78XX_OTP_MAGIC
#define AT29M2AF_USB_VENDOR_ID
#define AT29M2AF_USB_PRODUCT_ID

#define MII_READ
#define MII_WRITE

#define EEPROM_INDICATOR
#define EEPROM_MAC_OFFSET
#define MAX_EEPROM_SIZE
#define OTP_INDICATOR_1
#define OTP_INDICATOR_2

#define WAKE_ALL

#define TX_URB_NUM
#define TX_SS_URB_NUM
#define TX_HS_URB_NUM
#define TX_FS_URB_NUM

/* A single URB buffer must be large enough to hold a complete jumbo packet
 */
#define TX_SS_URB_SIZE
#define TX_HS_URB_SIZE
#define TX_FS_URB_SIZE

#define RX_SS_URB_NUM
#define RX_HS_URB_NUM
#define RX_FS_URB_NUM
#define RX_SS_URB_SIZE
#define RX_HS_URB_SIZE
#define RX_FS_URB_SIZE

#define SS_BURST_CAP_SIZE
#define SS_BULK_IN_DELAY
#define HS_BURST_CAP_SIZE
#define HS_BULK_IN_DELAY
#define FS_BURST_CAP_SIZE
#define FS_BULK_IN_DELAY

#define TX_CMD_LEN
#define TX_SKB_MIN_LEN
#define LAN78XX_TSO_SIZE(dev)

#define RX_CMD_LEN
#define RX_SKB_MIN_LEN
#define RX_MAX_FRAME_LEN(mtu)

/* USB related defines */
#define BULK_IN_PIPE
#define BULK_OUT_PIPE

/* default autosuspend delay (mSec)*/
#define DEFAULT_AUTOSUSPEND_DELAY

/* statistic update interval (mSec) */
#define STAT_UPDATE_TIMER

/* time to wait for MAC or FCT to stop (jiffies) */
#define HW_DISABLE_TIMEOUT

/* time to wait between polling MAC or FCT state (ms) */
#define HW_DISABLE_DELAY_MS

/* defines interrupts from interrupt EP */
#define MAX_INT_EP
#define INT_EP_INTEP
#define INT_EP_OTP_WR_DONE
#define INT_EP_EEE_TX_LPI_START
#define INT_EP_EEE_TX_LPI_STOP
#define INT_EP_EEE_RX_LPI
#define INT_EP_MAC_RESET_TIMEOUT
#define INT_EP_RDFO
#define INT_EP_TXE
#define INT_EP_USB_STATUS
#define INT_EP_TX_DIS
#define INT_EP_RX_DIS
#define INT_EP_PHY
#define INT_EP_DP
#define INT_EP_MAC_ERR
#define INT_EP_TDFU
#define INT_EP_TDFO
#define INT_EP_UTX
#define INT_EP_GPIO_11
#define INT_EP_GPIO_10
#define INT_EP_GPIO_9
#define INT_EP_GPIO_8
#define INT_EP_GPIO_7
#define INT_EP_GPIO_6
#define INT_EP_GPIO_5
#define INT_EP_GPIO_4
#define INT_EP_GPIO_3
#define INT_EP_GPIO_2
#define INT_EP_GPIO_1
#define INT_EP_GPIO_0

static const char lan78xx_gstrings[][ETH_GSTRING_LEN] =;

struct lan78xx_statstage {};

struct lan78xx_statstage64 {};

static u32 lan78xx_regs[] =;

#define PHY_REG_SIZE

struct lan78xx_net;

struct lan78xx_priv {};

enum skb_state {};

struct skb_data {};

#define EVENT_TX_HALT
#define EVENT_RX_HALT
#define EVENT_RX_MEMORY
#define EVENT_STS_SPLIT
#define EVENT_LINK_RESET
#define EVENT_RX_PAUSED
#define EVENT_DEV_WAKING
#define EVENT_DEV_ASLEEP
#define EVENT_DEV_OPEN
#define EVENT_STAT_UPDATE
#define EVENT_DEV_DISCONNECT

struct statstage {};

struct irq_domain_data {};

struct lan78xx_net {};

/* define external phy id */
#define PHY_LAN8835
#define PHY_KSZ9031RNX

/* use ethtool to change the level for any given device */
static int msg_level =;
module_param(msg_level, int, 0);
MODULE_PARM_DESC();

static struct sk_buff *lan78xx_get_buf(struct sk_buff_head *buf_pool)
{}

static void lan78xx_release_buf(struct sk_buff_head *buf_pool,
				struct sk_buff *buf)
{}

static void lan78xx_free_buf_pool(struct sk_buff_head *buf_pool)
{}

static int lan78xx_alloc_buf_pool(struct sk_buff_head *buf_pool,
				  size_t n_urbs, size_t urb_size,
				  struct lan78xx_net *dev)
{}

static struct sk_buff *lan78xx_get_rx_buf(struct lan78xx_net *dev)
{}

static void lan78xx_release_rx_buf(struct lan78xx_net *dev,
				   struct sk_buff *rx_buf)
{}

static void lan78xx_free_rx_resources(struct lan78xx_net *dev)
{}

static int lan78xx_alloc_rx_resources(struct lan78xx_net *dev)
{}

static struct sk_buff *lan78xx_get_tx_buf(struct lan78xx_net *dev)
{}

static void lan78xx_release_tx_buf(struct lan78xx_net *dev,
				   struct sk_buff *tx_buf)
{}

static void lan78xx_free_tx_resources(struct lan78xx_net *dev)
{}

static int lan78xx_alloc_tx_resources(struct lan78xx_net *dev)
{}

static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data)
{}

static int lan78xx_write_reg(struct lan78xx_net *dev, u32 index, u32 data)
{}

static int lan78xx_update_reg(struct lan78xx_net *dev, u32 reg, u32 mask,
			      u32 data)
{}

static int lan78xx_read_stats(struct lan78xx_net *dev,
			      struct lan78xx_statstage *data)
{}

#define check_counter_rollover(struct1, dev_stats, member)

static void lan78xx_check_stat_rollover(struct lan78xx_net *dev,
					struct lan78xx_statstage *stats)
{}

static void lan78xx_update_stats(struct lan78xx_net *dev)
{}

/* Loop until the read is completed with timeout called with phy_mutex held */
static int lan78xx_phy_wait_not_busy(struct lan78xx_net *dev)
{}

static inline u32 mii_access(int id, int index, int read)
{}

static int lan78xx_wait_eeprom(struct lan78xx_net *dev)
{}

static int lan78xx_eeprom_confirm_not_busy(struct lan78xx_net *dev)
{}

static int lan78xx_read_raw_eeprom(struct lan78xx_net *dev, u32 offset,
				   u32 length, u8 *data)
{}

static int lan78xx_read_eeprom(struct lan78xx_net *dev, u32 offset,
			       u32 length, u8 *data)
{}

static int lan78xx_write_raw_eeprom(struct lan78xx_net *dev, u32 offset,
				    u32 length, u8 *data)
{}

static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,
				u32 length, u8 *data)
{}

static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset,
				 u32 length, u8 *data)
{}

static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset,
			    u32 length, u8 *data)
{}

static int lan78xx_dataport_wait_not_busy(struct lan78xx_net *dev)
{}

static int lan78xx_dataport_write(struct lan78xx_net *dev, u32 ram_select,
				  u32 addr, u32 length, u32 *buf)
{}

static void lan78xx_set_addr_filter(struct lan78xx_priv *pdata,
				    int index, u8 addr[ETH_ALEN])
{}

/* returns hash bit number for given MAC address */
static inline u32 lan78xx_hash(char addr[ETH_ALEN])
{}

static void lan78xx_deferred_multicast_write(struct work_struct *param)
{}

static void lan78xx_set_multicast(struct net_device *netdev)
{}

static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex,
				      u16 lcladv, u16 rmtadv)
{}

static void lan78xx_rx_urb_submit_all(struct lan78xx_net *dev);

static int lan78xx_mac_reset(struct lan78xx_net *dev)
{}

static int lan78xx_link_reset(struct lan78xx_net *dev)
{}

/* some work can't be done in tasklets, so we use keventd
 *
 * NOTE:  annoying asymmetry:  if it's active, schedule_work() fails,
 * but tasklet_schedule() doesn't.	hope the failure is rare.
 */
static void lan78xx_defer_kevent(struct lan78xx_net *dev, int work)
{}

static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb)
{}

static int lan78xx_ethtool_get_eeprom_len(struct net_device *netdev)
{}

static int lan78xx_ethtool_get_eeprom(struct net_device *netdev,
				      struct ethtool_eeprom *ee, u8 *data)
{}

static int lan78xx_ethtool_set_eeprom(struct net_device *netdev,
				      struct ethtool_eeprom *ee, u8 *data)
{}

static void lan78xx_get_strings(struct net_device *netdev, u32 stringset,
				u8 *data)
{}

static int lan78xx_get_sset_count(struct net_device *netdev, int sset)
{}

static void lan78xx_get_stats(struct net_device *netdev,
			      struct ethtool_stats *stats, u64 *data)
{}

static void lan78xx_get_wol(struct net_device *netdev,
			    struct ethtool_wolinfo *wol)
{}

static int lan78xx_set_wol(struct net_device *netdev,
			   struct ethtool_wolinfo *wol)
{}

static int lan78xx_get_eee(struct net_device *net, struct ethtool_keee *edata)
{}

static int lan78xx_set_eee(struct net_device *net, struct ethtool_keee *edata)
{}

static u32 lan78xx_get_link(struct net_device *net)
{}

static void lan78xx_get_drvinfo(struct net_device *net,
				struct ethtool_drvinfo *info)
{}

static u32 lan78xx_get_msglevel(struct net_device *net)
{}

static void lan78xx_set_msglevel(struct net_device *net, u32 level)
{}

static int lan78xx_get_link_ksettings(struct net_device *net,
				      struct ethtool_link_ksettings *cmd)
{}

static int lan78xx_set_link_ksettings(struct net_device *net,
				      const struct ethtool_link_ksettings *cmd)
{}

static void lan78xx_get_pause(struct net_device *net,
			      struct ethtool_pauseparam *pause)
{}

static int lan78xx_set_pause(struct net_device *net,
			     struct ethtool_pauseparam *pause)
{}

static int lan78xx_get_regs_len(struct net_device *netdev)
{}

static void
lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
		 void *buf)
{}

static const struct ethtool_ops lan78xx_ethtool_ops =;

static void lan78xx_init_mac_address(struct lan78xx_net *dev)
{}

/* MDIO read and write wrappers for phylib */
static int lan78xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)
{}

static int lan78xx_mdiobus_write(struct mii_bus *bus, int phy_id, int idx,
				 u16 regval)
{}

static int lan78xx_mdio_init(struct lan78xx_net *dev)
{}

static void lan78xx_remove_mdio(struct lan78xx_net *dev)
{}

static void lan78xx_link_status_change(struct net_device *net)
{}

static int irq_map(struct irq_domain *d, unsigned int irq,
		   irq_hw_number_t hwirq)
{}

static void irq_unmap(struct irq_domain *d, unsigned int irq)
{}

static const struct irq_domain_ops chip_domain_ops =;

static void lan78xx_irq_mask(struct irq_data *irqd)
{}

static void lan78xx_irq_unmask(struct irq_data *irqd)
{}

static void lan78xx_irq_bus_lock(struct irq_data *irqd)
{}

static void lan78xx_irq_bus_sync_unlock(struct irq_data *irqd)
{}

static struct irq_chip lan78xx_irqchip =;

static int lan78xx_setup_irq_domain(struct lan78xx_net *dev)
{}

static void lan78xx_remove_irq_domain(struct lan78xx_net *dev)
{}

static int lan8835_fixup(struct phy_device *phydev)
{}

static int ksz9031rnx_fixup(struct phy_device *phydev)
{}

static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev)
{}

static int lan78xx_phy_init(struct lan78xx_net *dev)
{}

static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size)
{}

static int unlink_urbs(struct lan78xx_net *dev, struct sk_buff_head *q)
{}

static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu)
{}

static int lan78xx_set_mac_addr(struct net_device *netdev, void *p)
{}

/* Enable or disable Rx checksum offload engine */
static int lan78xx_set_features(struct net_device *netdev,
				netdev_features_t features)
{}

static void lan78xx_deferred_vlan_write(struct work_struct *param)
{}

static int lan78xx_vlan_rx_add_vid(struct net_device *netdev,
				   __be16 proto, u16 vid)
{}

static int lan78xx_vlan_rx_kill_vid(struct net_device *netdev,
				    __be16 proto, u16 vid)
{}

static void lan78xx_init_ltm(struct lan78xx_net *dev)
{}

static int lan78xx_urb_config_init(struct lan78xx_net *dev)
{}

static int lan78xx_start_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enable)
{}

static int lan78xx_stop_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enabled,
			   u32 hw_disabled)
{}

static int lan78xx_flush_fifo(struct lan78xx_net *dev, u32 reg, u32 fifo_flush)
{}

static int lan78xx_start_tx_path(struct lan78xx_net *dev)
{}

static int lan78xx_stop_tx_path(struct lan78xx_net *dev)
{}

/* The caller must ensure the Tx path is stopped before calling
 * lan78xx_flush_tx_fifo().
 */
static int lan78xx_flush_tx_fifo(struct lan78xx_net *dev)
{}

static int lan78xx_start_rx_path(struct lan78xx_net *dev)
{}

static int lan78xx_stop_rx_path(struct lan78xx_net *dev)
{}

/* The caller must ensure the Rx path is stopped before calling
 * lan78xx_flush_rx_fifo().
 */
static int lan78xx_flush_rx_fifo(struct lan78xx_net *dev)
{}

static int lan78xx_reset(struct lan78xx_net *dev)
{}

static void lan78xx_init_stats(struct lan78xx_net *dev)
{}

static int lan78xx_open(struct net_device *net)
{}

static void lan78xx_terminate_urbs(struct lan78xx_net *dev)
{}

static int lan78xx_stop(struct net_device *net)
{}

static enum skb_state defer_bh(struct lan78xx_net *dev, struct sk_buff *skb,
			       struct sk_buff_head *list, enum skb_state state)
{}

static void tx_complete(struct urb *urb)
{}

static void lan78xx_queue_skb(struct sk_buff_head *list,
			      struct sk_buff *newsk, enum skb_state state)
{}

static unsigned int lan78xx_tx_urb_space(struct lan78xx_net *dev)
{}

static unsigned int lan78xx_tx_pend_data_len(struct lan78xx_net *dev)
{}

static void lan78xx_tx_pend_skb_add(struct lan78xx_net *dev,
				    struct sk_buff *skb,
				    unsigned int *tx_pend_data_len)
{}

static void lan78xx_tx_pend_skb_head_add(struct lan78xx_net *dev,
					 struct sk_buff *skb,
					 unsigned int *tx_pend_data_len)
{}

static void lan78xx_tx_pend_skb_get(struct lan78xx_net *dev,
				    struct sk_buff **skb,
				    unsigned int *tx_pend_data_len)
{}

static netdev_tx_t
lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net)
{}

static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
{}

static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf)
{}

static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
				    struct sk_buff *skb,
				    u32 rx_cmd_a, u32 rx_cmd_b)
{}

static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
				    struct sk_buff *skb,
				    u32 rx_cmd_a, u32 rx_cmd_b)
{}

static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
{}

static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb,
		      int budget, int *work_done)
{}

static inline void rx_process(struct lan78xx_net *dev, struct sk_buff *skb,
			      int budget, int *work_done)
{}

static void rx_complete(struct urb *urb)
{}

static int rx_submit(struct lan78xx_net *dev, struct sk_buff *skb, gfp_t flags)
{}

static void lan78xx_rx_urb_submit_all(struct lan78xx_net *dev)
{}

static void lan78xx_rx_urb_resubmit(struct lan78xx_net *dev,
				    struct sk_buff *rx_buf)
{}

static void lan78xx_fill_tx_cmd_words(struct sk_buff *skb, u8 *buffer)
{}

static struct skb_data *lan78xx_tx_buf_fill(struct lan78xx_net *dev,
					    struct sk_buff *tx_buf)
{}

static void lan78xx_tx_bh(struct lan78xx_net *dev)
{}

static int lan78xx_bh(struct lan78xx_net *dev, int budget)
{}

static int lan78xx_poll(struct napi_struct *napi, int budget)
{}

static void lan78xx_delayedwork(struct work_struct *work)
{}

static void intr_complete(struct urb *urb)
{}

static void lan78xx_disconnect(struct usb_interface *intf)
{}

static void lan78xx_tx_timeout(struct net_device *net, unsigned int txqueue)
{}

static netdev_features_t lan78xx_features_check(struct sk_buff *skb,
						struct net_device *netdev,
						netdev_features_t features)
{}

static const struct net_device_ops lan78xx_netdev_ops =;

static void lan78xx_stat_monitor(struct timer_list *t)
{}

static int lan78xx_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{}

static u16 lan78xx_wakeframe_crc16(const u8 *buf, int len)
{}

static int lan78xx_set_auto_suspend(struct lan78xx_net *dev)
{}

static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
{}

static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
{}

static bool lan78xx_submit_deferred_urbs(struct lan78xx_net *dev)
{}

static int lan78xx_resume(struct usb_interface *intf)
{}

static int lan78xx_reset_resume(struct usb_interface *intf)
{}

static const struct usb_device_id products[] =;
MODULE_DEVICE_TABLE(usb, products);

static struct usb_driver lan78xx_driver =;

module_usb_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();