linux/drivers/net/ethernet/atheros/atlx/atl1.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
 * Copyright(c) 2006 - 2007 Chris Snook <[email protected]>
 * Copyright(c) 2006 - 2008 Jay Cliburn <[email protected]>
 *
 * Derived from Intel e1000 driver
 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
 *
 * Contact Information:
 * Xiong Huang <[email protected]>
 * Jie Yang <[email protected]>
 * Chris Snook <[email protected]>
 * Jay Cliburn <[email protected]>
 *
 * This version is adapted from the Attansic reference driver.
 *
 * TODO:
 * Add more ethtool functions.
 * Fix abstruse irq enable/disable condition described here:
 *	http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
 *
 * NEEDS TESTING:
 * VLAN
 * multicast
 * promiscuous mode
 * interrupt coalescing
 * SMP torture testing
 */

#include <linux/atomic.h>
#include <asm/byteorder.h>

#include <linux/compiler.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/hardirq.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/in.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/irqflags.h>
#include <linux/irqreturn.h>
#include <linux/jiffies.h>
#include <linux/mii.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/pm.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/tcp.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include <net/checksum.h>

#include "atl1.h"

MODULE_AUTHOR();
MODULE_LICENSE();

/* Temporary hack for merging atl1 and atl2 */
#include "atlx.c"

static const struct ethtool_ops atl1_ethtool_ops;

/*
 * This is the only thing that needs to be changed to adjust the
 * maximum number of ports that the driver can manage.
 */
#define ATL1_MAX_NIC

#define OPTION_UNSET
#define OPTION_DISABLED
#define OPTION_ENABLED

#define ATL1_PARAM_INIT

/*
 * Interrupt Moderate Timer in units of 2 us
 *
 * Valid Range: 10-65535
 *
 * Default Value: 100 (200us)
 */
static int int_mod_timer[ATL1_MAX_NIC+1] =;
static unsigned int num_int_mod_timer;
module_param_array_named();
MODULE_PARM_DESC();

#define DEFAULT_INT_MOD_CNT
#define MAX_INT_MOD_CNT
#define MIN_INT_MOD_CNT

struct atl1_option {};

static int atl1_validate_option(int *value, struct atl1_option *opt,
				struct pci_dev *pdev)
{}

/**
 * atl1_check_options - Range Checking for Command Line Parameters
 * @adapter: board private structure
 *
 * This routine checks all command line parameters for valid user
 * input.  If an invalid value is given, or if no user specified
 * value exists, a default value is used.  The final value is stored
 * in a variable in the adapter structure.
 */
static void atl1_check_options(struct atl1_adapter *adapter)
{}

/*
 * atl1_pci_tbl - PCI Device ID Table
 */
static const struct pci_device_id atl1_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);

static const u32 atl1_default_msg =;

static int debug =;
module_param(debug, int, 0);
MODULE_PARM_DESC();

/*
 * Reset the transmit and receive units; mask and clear all interrupts.
 * hw - Struct containing variables accessed by shared code
 * return : 0  or  idle status (if error)
 */
static s32 atl1_reset_hw(struct atl1_hw *hw)
{}

/* function about EEPROM
 *
 * check_eeprom_exist
 * return 0 if eeprom exist
 */
static int atl1_check_eeprom_exist(struct atl1_hw *hw)
{}

static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
{}

/*
 * Reads the value from a PHY register
 * hw - Struct containing variables accessed by shared code
 * reg_addr - address of the PHY register to read
 */
static s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
{}

#define CUSTOM_SPI_CS_SETUP
#define CUSTOM_SPI_CLK_HI
#define CUSTOM_SPI_CLK_LO
#define CUSTOM_SPI_CS_HOLD
#define CUSTOM_SPI_CS_HI

static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
{}

/*
 * get_permanent_address
 * return 0 if get valid mac address,
 */
static int atl1_get_permanent_address(struct atl1_hw *hw)
{}

/*
 * Reads the adapter's MAC address from the EEPROM
 * hw - Struct containing variables accessed by shared code
 */
static s32 atl1_read_mac_addr(struct atl1_hw *hw)
{}

/*
 * Hashes an address to determine its location in the multicast table
 * hw - Struct containing variables accessed by shared code
 * mc_addr - the multicast address to hash
 *
 * atl1_hash_mc_addr
 *  purpose
 *      set hash value for a multicast address
 *      hash calcu processing :
 *          1. calcu 32bit CRC for multicast address
 *          2. reverse crc with MSB to LSB
 */
static u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
{}

/*
 * Sets the bit in the multicast table corresponding to the hash value.
 * hw - Struct containing variables accessed by shared code
 * hash_value - Multicast address hash value
 */
static void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
{}

/*
 * Writes a value to a PHY register
 * hw - Struct containing variables accessed by shared code
 * reg_addr - address of the PHY register to write
 * data - data to write to the PHY
 */
static s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data)
{}

/*
 * Make L001's PHY out of Power Saving State (bug)
 * hw - Struct containing variables accessed by shared code
 * when power on, L001's PHY always on Power saving State
 * (Gigabit Link forbidden)
 */
static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
{}

/*
 * Resets the PHY and make all config validate
 * hw - Struct containing variables accessed by shared code
 *
 * Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
 */
static s32 atl1_phy_reset(struct atl1_hw *hw)
{}

/*
 * Configures PHY autoneg and flow control advertisement settings
 * hw - Struct containing variables accessed by shared code
 */
static s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
{}

/*
 * Configures link settings.
 * hw - Struct containing variables accessed by shared code
 * Assumes the hardware has previously been reset and the
 * transmitter and receiver are not enabled.
 */
static s32 atl1_setup_link(struct atl1_hw *hw)
{}

static void atl1_init_flash_opcode(struct atl1_hw *hw)
{}

/*
 * Performs basic configuration of the adapter.
 * hw - Struct containing variables accessed by shared code
 * Assumes that the controller has previously been reset and is in a
 * post-reset uninitialized state. Initializes multicast table,
 * and  Calls routines to setup link
 * Leaves the transmit and receive units disabled and uninitialized.
 */
static s32 atl1_init_hw(struct atl1_hw *hw)
{}

/*
 * Detects the current speed and duplex settings of the hardware.
 * hw - Struct containing variables accessed by shared code
 * speed - Speed of the connection
 * duplex - Duplex setting of the connection
 */
static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
{}

static void atl1_set_mac_addr(struct atl1_hw *hw)
{}

/**
 * atl1_sw_init - Initialize general software structures (struct atl1_adapter)
 * @adapter: board private structure to initialize
 *
 * atl1_sw_init initializes the Adapter private data structure.
 * Fields are initialized based on PCI device information and
 * OS network device settings (MTU size).
 */
static int atl1_sw_init(struct atl1_adapter *adapter)
{}

static int mdio_read(struct net_device *netdev, int phy_id, int reg_num)
{}

static void mdio_write(struct net_device *netdev, int phy_id, int reg_num,
	int val)
{}

static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{}

/**
 * atl1_setup_ring_resources - allocate Tx / RX descriptor resources
 * @adapter: board private structure
 *
 * Return 0 on success, negative on failure
 */
static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
{}

static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
{}

/**
 * atl1_clean_rx_ring - Free RFD Buffers
 * @adapter: board private structure
 */
static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
{}

/**
 * atl1_clean_tx_ring - Free Tx Buffers
 * @adapter: board private structure
 */
static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
{}

/**
 * atl1_free_ring_resources - Free Tx / RX descriptor Resources
 * @adapter: board private structure
 *
 * Free all transmit software resources
 */
static void atl1_free_ring_resources(struct atl1_adapter *adapter)
{}

static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
{}

static u32 atl1_check_link(struct atl1_adapter *adapter)
{}

static void set_flow_ctrl_old(struct atl1_adapter *adapter)
{}

static void set_flow_ctrl_new(struct atl1_hw *hw)
{}

/**
 * atl1_configure - Configure Transmit&Receive Unit after Reset
 * @adapter: board private structure
 *
 * Configure the Tx /Rx unit of the MAC after a reset.
 */
static u32 atl1_configure(struct atl1_adapter *adapter)
{}

/*
 * atl1_pcie_patch - Patch for PCIE module
 */
static void atl1_pcie_patch(struct atl1_adapter *adapter)
{}

/*
 * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400
 * on PCI Command register is disable.
 * The function enable this bit.
 * Brackett, 2006/03/15
 */
static void atl1_via_workaround(struct atl1_adapter *adapter)
{}

static void atl1_inc_smb(struct atl1_adapter *adapter)
{}

static void atl1_update_mailbox(struct atl1_adapter *adapter)
{}

static void atl1_clean_alloc_flag(struct atl1_adapter *adapter,
	struct rx_return_desc *rrd, u16 offset)
{}

static void atl1_update_rfd_index(struct atl1_adapter *adapter,
	struct rx_return_desc *rrd)
{}

static void atl1_rx_checksum(struct atl1_adapter *adapter,
	struct rx_return_desc *rrd, struct sk_buff *skb)
{}

/**
 * atl1_alloc_rx_buffers - Replace used receive buffers
 * @adapter: address of board private structure
 */
static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
{}

static int atl1_intr_rx(struct atl1_adapter *adapter, int budget)
{}

static int atl1_intr_tx(struct atl1_adapter *adapter)
{}

static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
{}

static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
		    struct tx_packet_desc *ptpd)
{}

static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
	struct tx_packet_desc *ptpd)
{}

static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
	struct tx_packet_desc *ptpd)
{}

static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
       struct tx_packet_desc *ptpd)
{}

static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
					 struct net_device *netdev)
{}

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

static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter)
{}

/**
 * atl1_intr - Interrupt Handler
 * @irq: interrupt number
 * @data: pointer to a network interface device structure
 */
static irqreturn_t atl1_intr(int irq, void *data)
{}


/**
 * atl1_phy_config - Timer Call-back
 * @t: timer_list containing pointer to netdev cast into an unsigned long
 */
static void atl1_phy_config(struct timer_list *t)
{}

/*
 * Orphaned vendor comment left intact here:
 * <vendor comment>
 * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
 * will assert. We do soft reset <0x1400=1> according
 * with the SPEC. BUT, it seemes that PCIE or DMA
 * state-machine will not be reset. DMAR_TO_INT will
 * assert again and again.
 * </vendor comment>
 */

static int atl1_reset(struct atl1_adapter *adapter)
{}

static s32 atl1_up(struct atl1_adapter *adapter)
{}

static void atl1_down(struct atl1_adapter *adapter)
{}

static void atl1_reset_dev_task(struct work_struct *work)
{}

/**
 * atl1_change_mtu - Change the Maximum Transfer Unit
 * @netdev: network interface device structure
 * @new_mtu: new value for maximum frame size
 *
 * Returns 0 on success, negative on failure
 */
static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
{}

/**
 * atl1_open - Called when a network interface is made active
 * @netdev: network interface device structure
 *
 * Returns 0 on success, negative value on failure
 *
 * The open entry point is called when a network interface is made
 * active by the system (IFF_UP).  At this point all resources needed
 * for transmit and receive operations are allocated, the interrupt
 * handler is registered with the OS, the watchdog timer is started,
 * and the stack is notified that the interface is ready.
 */
static int atl1_open(struct net_device *netdev)
{}

/**
 * atl1_close - Disables a network interface
 * @netdev: network interface device structure
 *
 * Returns 0, this is not allowed to fail
 *
 * The close entry point is called when an interface is de-activated
 * by the OS.  The hardware is still under the drivers control, but
 * needs to be disabled.  A global MAC reset is issued to stop the
 * hardware, and all transmit and receive resources are freed.
 */
static int atl1_close(struct net_device *netdev)
{}

#ifdef CONFIG_PM_SLEEP
static int atl1_suspend(struct device *dev)
{}

static int atl1_resume(struct device *dev)
{}
#endif

static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume);

static void atl1_shutdown(struct pci_dev *pdev)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void atl1_poll_controller(struct net_device *netdev)
{}
#endif

static const struct net_device_ops atl1_netdev_ops =;

/**
 * atl1_probe - Device Initialization Routine
 * @pdev: PCI device information struct
 * @ent: entry in atl1_pci_tbl
 *
 * Returns 0 on success, negative on failure
 *
 * atl1_probe initializes an adapter identified by a pci_dev structure.
 * The OS initialization, configuring of the adapter private structure,
 * and a hardware reset occur.
 */
static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{}

/**
 * atl1_remove - Device Removal Routine
 * @pdev: PCI device information struct
 *
 * atl1_remove is called by the PCI subsystem to alert the driver
 * that it should release a PCI device.  The could be caused by a
 * Hot-Plug event, or because the driver is going to be removed from
 * memory.
 */
static void atl1_remove(struct pci_dev *pdev)
{}

static struct pci_driver atl1_driver =;

struct atl1_stats {};

#define ATL1_STAT(m)

static struct atl1_stats atl1_gstrings_stats[] =;

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

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

static int atl1_get_link_ksettings(struct net_device *netdev,
				   struct ethtool_link_ksettings *cmd)
{}

static int atl1_set_link_ksettings(struct net_device *netdev,
				   const struct ethtool_link_ksettings *cmd)
{}

static void atl1_get_drvinfo(struct net_device *netdev,
	struct ethtool_drvinfo *drvinfo)
{}

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

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

static u32 atl1_get_msglevel(struct net_device *netdev)
{}

static void atl1_set_msglevel(struct net_device *netdev, u32 value)
{}

static int atl1_get_regs_len(struct net_device *netdev)
{}

static void atl1_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
	void *p)
{}

static void atl1_get_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring,
			       struct kernel_ethtool_ringparam *kernel_ring,
			       struct netlink_ext_ack *extack)
{}

static int atl1_set_ringparam(struct net_device *netdev,
			      struct ethtool_ringparam *ring,
			      struct kernel_ethtool_ringparam *kernel_ring,
			      struct netlink_ext_ack *extack)
{}

static void atl1_get_pauseparam(struct net_device *netdev,
	struct ethtool_pauseparam *epause)
{}

static int atl1_set_pauseparam(struct net_device *netdev,
	struct ethtool_pauseparam *epause)
{}

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

static int atl1_nway_reset(struct net_device *netdev)
{}

static const struct ethtool_ops atl1_ethtool_ops =;

module_pci_driver();