// SPDX-License-Identifier: GPL-2.0-or-later /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver * Copyright (C) 2004 Advanced Micro Devices * * Copyright 2001,2002 Jeff Garzik <[email protected]> [ 8139cp.c,tg3.c ] * Copyright (C) 2001, 2002 David S. Miller ([email protected])[ tg3.c] * Copyright 1996-1999 Thomas Bogendoerfer [ pcnet32.c ] * Derived from the lance driver written 1993,1994,1995 by Donald Becker. * Copyright 1993 United States Government as represented by the * Director, National Security Agency.[ pcnet32.c ] * Carsten Langgaard, [email protected] [ pcnet32.c ] * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * Module Name: amd8111e.c Abstract: AMD8111 based 10/100 Ethernet Controller Driver. Environment: Kernel Mode Revision History: 3.0.0 Initial Revision. 3.0.1 1. Dynamic interrupt coalescing. 2. Removed prev_stats. 3. MII support. 4. Dynamic IPG support 3.0.2 05/29/2003 1. Bug fix: Fixed failure to send jumbo packets larger than 4k. 2. Bug fix: Fixed VLAN support failure. 3. Bug fix: Fixed receive interrupt coalescing bug. 4. Dynamic IPG support is disabled by default. 3.0.3 06/05/2003 1. Bug fix: Fixed failure to close the interface if SMP is enabled. 3.0.4 12/09/2003 1. Added set_mac_address routine for bonding driver support. 2. Tested the driver for bonding support 3. Bug fix: Fixed mismach in actual receive buffer length and length indicated to the h/w. 4. Modified amd8111e_rx() routine to receive all the received packets in the first interrupt. 5. Bug fix: Corrected rx_errors reported in get_stats() function. 3.0.5 03/22/2004 1. Added NAPI support */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/compiler.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/if_vlan.h> #include <linux/ctype.h> #include <linux/crc32.h> #include <linux/dma-mapping.h> #include <asm/io.h> #include <asm/byteorder.h> #include <linux/uaccess.h> #if IS_ENABLED(CONFIG_VLAN_8021Q) #define AMD8111E_VLAN_TAG_USED … #else #define AMD8111E_VLAN_TAG_USED … #endif #include "amd8111e.h" #define MODULE_NAME … MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; module_param_array(…); MODULE_PARM_DESC(…) …; module_param_array(…); MODULE_PARM_DESC(…) …; module_param_array(…); MODULE_PARM_DESC(…) …; /* This function will read the PHY registers. */ static int amd8111e_read_phy(struct amd8111e_priv *lp, int phy_id, int reg, u32 *val) { … } /* This function will write into PHY registers. */ static int amd8111e_write_phy(struct amd8111e_priv *lp, int phy_id, int reg, u32 val) { … } /* This is the mii register read function provided to the mii interface. */ static int amd8111e_mdio_read(struct net_device *dev, int phy_id, int reg_num) { … } /* This is the mii register write function provided to the mii interface. */ static void amd8111e_mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) { … } /* This function will set PHY speed. During initialization sets * the original speed to 100 full */ static void amd8111e_set_ext_phy(struct net_device *dev) { … } /* This function will unmap skb->data space and will free * all transmit and receive skbuffs. */ static int amd8111e_free_skbs(struct net_device *dev) { … } /* This will set the receive buffer length corresponding * to the mtu size of networkinterface. */ static inline void amd8111e_set_rx_buff_len(struct net_device *dev) { … } /* This function will free all the previously allocated buffers, * determine new receive buffer length and will allocate new receive buffers. * This function also allocates and initializes both the transmitter * and receive hardware descriptors. */ static int amd8111e_init_ring(struct net_device *dev) { … } /* This function will set the interrupt coalescing according * to the input arguments */ static int amd8111e_set_coalesce(struct net_device *dev, enum coal_mode cmod) { … } /* This function initializes the device registers and starts the device. */ static int amd8111e_restart(struct net_device *dev) { … } /* This function clears necessary the device registers. */ static void amd8111e_init_hw_default(struct amd8111e_priv *lp) { … } /* This function disables the interrupt and clears all the pending * interrupts in INT0 */ static void amd8111e_disable_interrupt(struct amd8111e_priv *lp) { … } /* This function stops the chip. */ static void amd8111e_stop_chip(struct amd8111e_priv *lp) { … } /* This function frees the transmiter and receiver descriptor rings. */ static void amd8111e_free_ring(struct amd8111e_priv *lp) { … } /* This function will free all the transmit skbs that are actually * transmitted by the device. It will check the ownership of the * skb before freeing the skb. */ static int amd8111e_tx(struct net_device *dev) { … } /* This function handles the driver receive operation in polling mode */ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) { … } /* This function will indicate the link status to the kernel. */ static int amd8111e_link_change(struct net_device *dev) { … } /* This function reads the mib counters. */ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER) { … } /* This function reads the mib registers and returns the hardware statistics. * It updates previous internal driver statistics with new values. */ static struct net_device_stats *amd8111e_get_stats(struct net_device *dev) { … } /* This function recalculate the interrupt coalescing mode on every interrupt * according to the datarate and the packet rate. */ static int amd8111e_calc_coalesce(struct net_device *dev) { … } /* This is device interrupt function. It handles transmit, * receive,link change and hardware timer interrupts. */ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id) { … } #ifdef CONFIG_NET_POLL_CONTROLLER static void amd8111e_poll(struct net_device *dev) { … } #endif /* This function closes the network interface and updates * the statistics so that most recent statistics will be * available after the interface is down. */ static int amd8111e_close(struct net_device *dev) { … } /* This function opens new interface.It requests irq for the device, * initializes the device,buffers and descriptors, and starts the device. */ static int amd8111e_open(struct net_device *dev) { … } /* This function checks if there is any transmit descriptors * available to queue more packet. */ static int amd8111e_tx_queue_avail(struct amd8111e_priv *lp) { … } /* This function will queue the transmit packets to the * descriptors and will trigger the send operation. It also * initializes the transmit descriptors with buffer physical address, * byte count, ownership to hardware etc. */ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb, struct net_device *dev) { … } /* This function returns all the memory mapped registers of the device. */ static void amd8111e_read_regs(struct amd8111e_priv *lp, u32 *buf) { … } /* This function sets promiscuos mode, all-multi mode or the multicast address * list to the device. */ static void amd8111e_set_multicast_list(struct net_device *dev) { … } static void amd8111e_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { … } static int amd8111e_get_regs_len(struct net_device *dev) { … } static void amd8111e_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) { … } static int amd8111e_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *cmd) { … } static int amd8111e_set_link_ksettings(struct net_device *dev, const struct ethtool_link_ksettings *cmd) { … } static int amd8111e_nway_reset(struct net_device *dev) { … } static u32 amd8111e_get_link(struct net_device *dev) { … } static void amd8111e_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol_info) { … } static int amd8111e_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol_info) { … } static const struct ethtool_ops ops = …; /* This function handles all the ethtool ioctls. It gives driver info, * gets/sets driver speed, gets memory mapped register values, forces * auto negotiation, sets/gets WOL options for ethtool application. */ static int amd8111e_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { … } static int amd8111e_set_mac_address(struct net_device *dev, void *p) { … } /* This function changes the mtu of the device. It restarts the device to * initialize the descriptor with new receive buffers. */ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu) { … } static int amd8111e_enable_magicpkt(struct amd8111e_priv *lp) { … } static int amd8111e_enable_link_change(struct amd8111e_priv *lp) { … } /* This function is called when a packet transmission fails to complete * within a reasonable period, on the assumption that an interrupt have * failed or the interface is locked up. This function will reinitialize * the hardware. */ static void amd8111e_tx_timeout(struct net_device *dev, unsigned int txqueue) { … } static int __maybe_unused amd8111e_suspend(struct device *dev_d) { … } static int __maybe_unused amd8111e_resume(struct device *dev_d) { … } static void amd8111e_config_ipg(struct timer_list *t) { … } static void amd8111e_probe_ext_phy(struct net_device *dev) { … } static const struct net_device_ops amd8111e_netdev_ops = …; static int amd8111e_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) { … } static void amd8111e_remove_one(struct pci_dev *pdev) { … } static const struct pci_device_id amd8111e_pci_tbl[] = …; MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl); static SIMPLE_DEV_PM_OPS(amd8111e_pm_ops, amd8111e_suspend, amd8111e_resume); static struct pci_driver amd8111e_driver = …; module_pci_driver(…) …;