// SPDX-License-Identifier: GPL-2.0-only /* * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver * * Copyright (c) 2009-2010 Micrel, Inc. * Tristram Ha <[email protected]> */ #define pr_fmt(fmt) … #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/ioport.h> #include <linux/pci.h> #include <linux/proc_fs.h> #include <linux/mii.h> #include <linux/platform_device.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/in.h> #include <linux/ip.h> #include <linux/if_vlan.h> #include <linux/crc32.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/micrel_phy.h> /* DMA Registers */ #define KS_DMA_TX_CTRL … #define DMA_TX_ENABLE … #define DMA_TX_CRC_ENABLE … #define DMA_TX_PAD_ENABLE … #define DMA_TX_LOOPBACK … #define DMA_TX_FLOW_ENABLE … #define DMA_TX_CSUM_IP … #define DMA_TX_CSUM_TCP … #define DMA_TX_CSUM_UDP … #define DMA_TX_BURST_SIZE … #define KS_DMA_RX_CTRL … #define DMA_RX_ENABLE … #define KS884X_DMA_RX_MULTICAST … #define DMA_RX_PROMISCUOUS … #define DMA_RX_ERROR … #define DMA_RX_UNICAST … #define DMA_RX_ALL_MULTICAST … #define DMA_RX_BROADCAST … #define DMA_RX_FLOW_ENABLE … #define DMA_RX_CSUM_IP … #define DMA_RX_CSUM_TCP … #define DMA_RX_CSUM_UDP … #define DMA_RX_BURST_SIZE … #define DMA_BURST_SHIFT … #define DMA_BURST_DEFAULT … #define KS_DMA_TX_START … #define KS_DMA_RX_START … #define DMA_START … #define KS_DMA_TX_ADDR … #define KS_DMA_RX_ADDR … #define DMA_ADDR_LIST_MASK … #define DMA_ADDR_LIST_SHIFT … /* MTR0 */ #define KS884X_MULTICAST_0_OFFSET … #define KS884X_MULTICAST_1_OFFSET … #define KS884X_MULTICAST_2_OFFSET … #define KS884x_MULTICAST_3_OFFSET … /* MTR1 */ #define KS884X_MULTICAST_4_OFFSET … #define KS884X_MULTICAST_5_OFFSET … #define KS884X_MULTICAST_6_OFFSET … #define KS884X_MULTICAST_7_OFFSET … /* Interrupt Registers */ /* INTEN */ #define KS884X_INTERRUPTS_ENABLE … /* INTST */ #define KS884X_INTERRUPTS_STATUS … #define KS884X_INT_RX_STOPPED … #define KS884X_INT_TX_STOPPED … #define KS884X_INT_RX_OVERRUN … #define KS884X_INT_TX_EMPTY … #define KS884X_INT_RX … #define KS884X_INT_TX … #define KS884X_INT_PHY … #define KS884X_INT_RX_MASK … #define KS884X_INT_TX_MASK … #define KS884X_INT_MASK … /* MAC Additional Station Address */ /* MAAL0 */ #define KS_ADD_ADDR_0_LO … /* MAAH0 */ #define KS_ADD_ADDR_0_HI … /* MAAL1 */ #define KS_ADD_ADDR_1_LO … /* MAAH1 */ #define KS_ADD_ADDR_1_HI … /* MAAL2 */ #define KS_ADD_ADDR_2_LO … /* MAAH2 */ #define KS_ADD_ADDR_2_HI … /* MAAL3 */ #define KS_ADD_ADDR_3_LO … /* MAAH3 */ #define KS_ADD_ADDR_3_HI … /* MAAL4 */ #define KS_ADD_ADDR_4_LO … /* MAAH4 */ #define KS_ADD_ADDR_4_HI … /* MAAL5 */ #define KS_ADD_ADDR_5_LO … /* MAAH5 */ #define KS_ADD_ADDR_5_HI … /* MAAL6 */ #define KS_ADD_ADDR_6_LO … /* MAAH6 */ #define KS_ADD_ADDR_6_HI … /* MAAL7 */ #define KS_ADD_ADDR_7_LO … /* MAAH7 */ #define KS_ADD_ADDR_7_HI … /* MAAL8 */ #define KS_ADD_ADDR_8_LO … /* MAAH8 */ #define KS_ADD_ADDR_8_HI … /* MAAL9 */ #define KS_ADD_ADDR_9_LO … /* MAAH9 */ #define KS_ADD_ADDR_9_HI … /* MAAL10 */ #define KS_ADD_ADDR_A_LO … /* MAAH10 */ #define KS_ADD_ADDR_A_HI … /* MAAL11 */ #define KS_ADD_ADDR_B_LO … /* MAAH11 */ #define KS_ADD_ADDR_B_HI … /* MAAL12 */ #define KS_ADD_ADDR_C_LO … /* MAAH12 */ #define KS_ADD_ADDR_C_HI … /* MAAL13 */ #define KS_ADD_ADDR_D_LO … /* MAAH13 */ #define KS_ADD_ADDR_D_HI … /* MAAL14 */ #define KS_ADD_ADDR_E_LO … /* MAAH14 */ #define KS_ADD_ADDR_E_HI … /* MAAL15 */ #define KS_ADD_ADDR_F_LO … /* MAAH15 */ #define KS_ADD_ADDR_F_HI … #define ADD_ADDR_HI_MASK … #define ADD_ADDR_ENABLE … #define ADD_ADDR_INCR … /* Miscellaneous Registers */ /* MARL */ #define KS884X_ADDR_0_OFFSET … #define KS884X_ADDR_1_OFFSET … /* MARM */ #define KS884X_ADDR_2_OFFSET … #define KS884X_ADDR_3_OFFSET … /* MARH */ #define KS884X_ADDR_4_OFFSET … #define KS884X_ADDR_5_OFFSET … /* OBCR */ #define KS884X_BUS_CTRL_OFFSET … #define BUS_SPEED_125_MHZ … #define BUS_SPEED_62_5_MHZ … #define BUS_SPEED_41_66_MHZ … #define BUS_SPEED_25_MHZ … /* EEPCR */ #define KS884X_EEPROM_CTRL_OFFSET … #define EEPROM_CHIP_SELECT … #define EEPROM_SERIAL_CLOCK … #define EEPROM_DATA_OUT … #define EEPROM_DATA_IN … #define EEPROM_ACCESS_ENABLE … /* MBIR */ #define KS884X_MEM_INFO_OFFSET … #define RX_MEM_TEST_FAILED … #define RX_MEM_TEST_FINISHED … #define TX_MEM_TEST_FAILED … #define TX_MEM_TEST_FINISHED … /* GCR */ #define KS884X_GLOBAL_CTRL_OFFSET … #define GLOBAL_SOFTWARE_RESET … #define KS8841_POWER_MANAGE_OFFSET … /* WFCR */ #define KS8841_WOL_CTRL_OFFSET … #define KS8841_WOL_MAGIC_ENABLE … #define KS8841_WOL_FRAME3_ENABLE … #define KS8841_WOL_FRAME2_ENABLE … #define KS8841_WOL_FRAME1_ENABLE … #define KS8841_WOL_FRAME0_ENABLE … /* WF0 */ #define KS8841_WOL_FRAME_CRC_OFFSET … #define KS8841_WOL_FRAME_BYTE0_OFFSET … #define KS8841_WOL_FRAME_BYTE2_OFFSET … /* IACR */ #define KS884X_IACR_P … #define KS884X_IACR_OFFSET … /* IADR1 */ #define KS884X_IADR1_P … #define KS884X_IADR2_P … #define KS884X_IADR3_P … #define KS884X_IADR4_P … #define KS884X_IADR5_P … #define KS884X_ACC_CTRL_SEL_OFFSET … #define KS884X_ACC_CTRL_INDEX_OFFSET … #define KS884X_ACC_DATA_0_OFFSET … #define KS884X_ACC_DATA_1_OFFSET … #define KS884X_ACC_DATA_2_OFFSET … #define KS884X_ACC_DATA_3_OFFSET … #define KS884X_ACC_DATA_4_OFFSET … #define KS884X_ACC_DATA_5_OFFSET … #define KS884X_ACC_DATA_6_OFFSET … #define KS884X_ACC_DATA_7_OFFSET … #define KS884X_ACC_DATA_8_OFFSET … /* P1MBCR */ #define KS884X_P1MBCR_P … #define KS884X_P1MBSR_P … #define KS884X_PHY1ILR_P … #define KS884X_PHY1IHR_P … #define KS884X_P1ANAR_P … #define KS884X_P1ANLPR_P … /* P2MBCR */ #define KS884X_P2MBCR_P … #define KS884X_P2MBSR_P … #define KS884X_PHY2ILR_P … #define KS884X_PHY2IHR_P … #define KS884X_P2ANAR_P … #define KS884X_P2ANLPR_P … #define KS884X_PHY_1_CTRL_OFFSET … #define PHY_CTRL_INTERVAL … #define KS884X_PHY_CTRL_OFFSET … #define KS884X_PHY_STATUS_OFFSET … #define KS884X_PHY_ID_1_OFFSET … #define KS884X_PHY_ID_2_OFFSET … #define KS884X_PHY_AUTO_NEG_OFFSET … #define KS884X_PHY_REMOTE_CAP_OFFSET … /* P1VCT */ #define KS884X_P1VCT_P … #define KS884X_P1PHYCTRL_P … /* P2VCT */ #define KS884X_P2VCT_P … #define KS884X_P2PHYCTRL_P … #define KS884X_PHY_SPECIAL_OFFSET … #define PHY_SPECIAL_INTERVAL … #define KS884X_PHY_LINK_MD_OFFSET … #define PHY_START_CABLE_DIAG … #define PHY_CABLE_DIAG_RESULT … #define PHY_CABLE_STAT_NORMAL … #define PHY_CABLE_STAT_OPEN … #define PHY_CABLE_STAT_SHORT … #define PHY_CABLE_STAT_FAILED … #define PHY_CABLE_10M_SHORT … #define PHY_CABLE_FAULT_COUNTER … #define KS884X_PHY_PHY_CTRL_OFFSET … #define PHY_STAT_REVERSED_POLARITY … #define PHY_STAT_MDIX … #define PHY_FORCE_LINK … #define PHY_POWER_SAVING_DISABLE … #define PHY_REMOTE_LOOPBACK … /* SIDER */ #define KS884X_SIDER_P … #define KS884X_CHIP_ID_OFFSET … #define KS884X_FAMILY_ID_OFFSET … #define REG_FAMILY_ID … #define REG_CHIP_ID_41 … #define REG_CHIP_ID_42 … #define KS884X_CHIP_ID_MASK_41 … #define KS884X_CHIP_ID_MASK … #define KS884X_CHIP_ID_SHIFT … #define KS884X_REVISION_MASK … #define KS884X_REVISION_SHIFT … #define KS8842_START … #define CHIP_IP_41_M … #define CHIP_IP_42_M … #define CHIP_IP_61_M … #define CHIP_IP_62_M … #define CHIP_IP_41_P … #define CHIP_IP_42_P … #define CHIP_IP_61_P … #define CHIP_IP_62_P … /* SGCR1 */ #define KS8842_SGCR1_P … #define KS8842_SWITCH_CTRL_1_OFFSET … #define SWITCH_PASS_ALL … #define SWITCH_TX_FLOW_CTRL … #define SWITCH_RX_FLOW_CTRL … #define SWITCH_CHECK_LENGTH … #define SWITCH_AGING_ENABLE … #define SWITCH_FAST_AGING … #define SWITCH_AGGR_BACKOFF … #define SWITCH_PASS_PAUSE … #define SWITCH_LINK_AUTO_AGING … /* SGCR2 */ #define KS8842_SGCR2_P … #define KS8842_SWITCH_CTRL_2_OFFSET … #define SWITCH_VLAN_ENABLE … #define SWITCH_IGMP_SNOOP … #define IPV6_MLD_SNOOP_ENABLE … #define IPV6_MLD_SNOOP_OPTION … #define PRIORITY_SCHEME_SELECT … #define SWITCH_MIRROR_RX_TX … #define UNICAST_VLAN_BOUNDARY … #define MULTICAST_STORM_DISABLE … #define SWITCH_BACK_PRESSURE … #define FAIR_FLOW_CTRL … #define NO_EXC_COLLISION_DROP … #define SWITCH_HUGE_PACKET … #define SWITCH_LEGAL_PACKET … #define SWITCH_BUF_RESERVE … /* SGCR3 */ #define KS8842_SGCR3_P … #define KS8842_SWITCH_CTRL_3_OFFSET … #define BROADCAST_STORM_RATE_LO … #define SWITCH_REPEATER … #define SWITCH_HALF_DUPLEX … #define SWITCH_FLOW_CTRL … #define SWITCH_10_MBIT … #define SWITCH_REPLACE_NULL_VID … #define BROADCAST_STORM_RATE_HI … #define BROADCAST_STORM_RATE … /* SGCR4 */ #define KS8842_SGCR4_P … /* SGCR5 */ #define KS8842_SGCR5_P … #define KS8842_SWITCH_CTRL_5_OFFSET … #define LED_MODE … #define LED_SPEED_DUPLEX_ACT … #define LED_SPEED_DUPLEX_LINK_ACT … #define LED_DUPLEX_10_100 … /* SGCR6 */ #define KS8842_SGCR6_P … #define KS8842_SWITCH_CTRL_6_OFFSET … #define KS8842_PRIORITY_MASK … #define KS8842_PRIORITY_SHIFT … /* SGCR7 */ #define KS8842_SGCR7_P … #define KS8842_SWITCH_CTRL_7_OFFSET … #define SWITCH_UNK_DEF_PORT_ENABLE … #define SWITCH_UNK_DEF_PORT_3 … #define SWITCH_UNK_DEF_PORT_2 … #define SWITCH_UNK_DEF_PORT_1 … /* MACAR1 */ #define KS8842_MACAR1_P … #define KS8842_MACAR2_P … #define KS8842_MACAR3_P … #define KS8842_MAC_ADDR_1_OFFSET … #define KS8842_MAC_ADDR_0_OFFSET … #define KS8842_MAC_ADDR_3_OFFSET … #define KS8842_MAC_ADDR_2_OFFSET … #define KS8842_MAC_ADDR_5_OFFSET … #define KS8842_MAC_ADDR_4_OFFSET … /* TOSR1 */ #define KS8842_TOSR1_P … #define KS8842_TOSR2_P … #define KS8842_TOSR3_P … #define KS8842_TOSR4_P … #define KS8842_TOSR5_P … #define KS8842_TOSR6_P … #define KS8842_TOSR7_P … #define KS8842_TOSR8_P … #define KS8842_TOS_1_OFFSET … #define KS8842_TOS_2_OFFSET … #define KS8842_TOS_3_OFFSET … #define KS8842_TOS_4_OFFSET … #define KS8842_TOS_5_OFFSET … #define KS8842_TOS_6_OFFSET … #define KS8842_TOS_7_OFFSET … #define KS8842_TOS_8_OFFSET … /* P1CR1 */ #define KS8842_P1CR1_P … #define KS8842_P1CR2_P … #define KS8842_P1VIDR_P … #define KS8842_P1CR3_P … #define KS8842_P1IRCR_P … #define KS8842_P1ERCR_P … #define KS884X_P1SCSLMD_P … #define KS884X_P1CR4_P … #define KS884X_P1SR_P … /* P2CR1 */ #define KS8842_P2CR1_P … #define KS8842_P2CR2_P … #define KS8842_P2VIDR_P … #define KS8842_P2CR3_P … #define KS8842_P2IRCR_P … #define KS8842_P2ERCR_P … #define KS884X_P2SCSLMD_P … #define KS884X_P2CR4_P … #define KS884X_P2SR_P … /* P3CR1 */ #define KS8842_P3CR1_P … #define KS8842_P3CR2_P … #define KS8842_P3VIDR_P … #define KS8842_P3CR3_P … #define KS8842_P3IRCR_P … #define KS8842_P3ERCR_P … #define KS8842_PORT_1_CTRL_1 … #define KS8842_PORT_2_CTRL_1 … #define KS8842_PORT_3_CTRL_1 … #define PORT_CTRL_ADDR(port, addr) … #define KS8842_PORT_CTRL_1_OFFSET … #define PORT_BROADCAST_STORM … #define PORT_DIFFSERV_ENABLE … #define PORT_802_1P_ENABLE … #define PORT_BASED_PRIORITY_MASK … #define PORT_BASED_PRIORITY_BASE … #define PORT_BASED_PRIORITY_SHIFT … #define PORT_BASED_PRIORITY_0 … #define PORT_BASED_PRIORITY_1 … #define PORT_BASED_PRIORITY_2 … #define PORT_BASED_PRIORITY_3 … #define PORT_INSERT_TAG … #define PORT_REMOVE_TAG … #define PORT_PRIO_QUEUE_ENABLE … #define KS8842_PORT_CTRL_2_OFFSET … #define PORT_INGRESS_VLAN_FILTER … #define PORT_DISCARD_NON_VID … #define PORT_FORCE_FLOW_CTRL … #define PORT_BACK_PRESSURE … #define PORT_TX_ENABLE … #define PORT_RX_ENABLE … #define PORT_LEARN_DISABLE … #define PORT_MIRROR_SNIFFER … #define PORT_MIRROR_RX … #define PORT_MIRROR_TX … #define PORT_USER_PRIORITY_CEILING … #define PORT_VLAN_MEMBERSHIP … #define KS8842_PORT_CTRL_VID_OFFSET … #define PORT_DEFAULT_VID … #define KS8842_PORT_CTRL_3_OFFSET … #define PORT_INGRESS_LIMIT_MODE … #define PORT_INGRESS_ALL … #define PORT_INGRESS_UNICAST … #define PORT_INGRESS_MULTICAST … #define PORT_INGRESS_BROADCAST … #define PORT_COUNT_IFG … #define PORT_COUNT_PREAMBLE … #define KS8842_PORT_IN_RATE_OFFSET … #define KS8842_PORT_OUT_RATE_OFFSET … #define PORT_PRIORITY_RATE … #define PORT_PRIORITY_RATE_SHIFT … #define KS884X_PORT_LINK_MD … #define PORT_CABLE_10M_SHORT … #define PORT_CABLE_DIAG_RESULT … #define PORT_CABLE_STAT_NORMAL … #define PORT_CABLE_STAT_OPEN … #define PORT_CABLE_STAT_SHORT … #define PORT_CABLE_STAT_FAILED … #define PORT_START_CABLE_DIAG … #define PORT_FORCE_LINK … #define PORT_POWER_SAVING_DISABLE … #define PORT_PHY_REMOTE_LOOPBACK … #define PORT_CABLE_FAULT_COUNTER … #define KS884X_PORT_CTRL_4_OFFSET … #define PORT_LED_OFF … #define PORT_TX_DISABLE … #define PORT_AUTO_NEG_RESTART … #define PORT_REMOTE_FAULT_DISABLE … #define PORT_POWER_DOWN … #define PORT_AUTO_MDIX_DISABLE … #define PORT_FORCE_MDIX … #define PORT_LOOPBACK … #define PORT_AUTO_NEG_ENABLE … #define PORT_FORCE_100_MBIT … #define PORT_FORCE_FULL_DUPLEX … #define PORT_AUTO_NEG_SYM_PAUSE … #define PORT_AUTO_NEG_100BTX_FD … #define PORT_AUTO_NEG_100BTX … #define PORT_AUTO_NEG_10BT_FD … #define PORT_AUTO_NEG_10BT … #define KS884X_PORT_STATUS_OFFSET … #define PORT_HP_MDIX … #define PORT_REVERSED_POLARITY … #define PORT_RX_FLOW_CTRL … #define PORT_TX_FLOW_CTRL … #define PORT_STATUS_SPEED_100MBIT … #define PORT_STATUS_FULL_DUPLEX … #define PORT_REMOTE_FAULT … #define PORT_MDIX_STATUS … #define PORT_AUTO_NEG_COMPLETE … #define PORT_STATUS_LINK_GOOD … #define PORT_REMOTE_SYM_PAUSE … #define PORT_REMOTE_100BTX_FD … #define PORT_REMOTE_100BTX … #define PORT_REMOTE_10BT_FD … #define PORT_REMOTE_10BT … /* #define STATIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF #define STATIC_MAC_TABLE_FWD_PORTS 00-00070000-00000000 #define STATIC_MAC_TABLE_VALID 00-00080000-00000000 #define STATIC_MAC_TABLE_OVERRIDE 00-00100000-00000000 #define STATIC_MAC_TABLE_USE_FID 00-00200000-00000000 #define STATIC_MAC_TABLE_FID 00-03C00000-00000000 */ #define STATIC_MAC_TABLE_ADDR … #define STATIC_MAC_TABLE_FWD_PORTS … #define STATIC_MAC_TABLE_VALID … #define STATIC_MAC_TABLE_OVERRIDE … #define STATIC_MAC_TABLE_USE_FID … #define STATIC_MAC_TABLE_FID … #define STATIC_MAC_FWD_PORTS_SHIFT … #define STATIC_MAC_FID_SHIFT … /* #define VLAN_TABLE_VID 00-00000000-00000FFF #define VLAN_TABLE_FID 00-00000000-0000F000 #define VLAN_TABLE_MEMBERSHIP 00-00000000-00070000 #define VLAN_TABLE_VALID 00-00000000-00080000 */ #define VLAN_TABLE_VID … #define VLAN_TABLE_FID … #define VLAN_TABLE_MEMBERSHIP … #define VLAN_TABLE_VALID … #define VLAN_TABLE_FID_SHIFT … #define VLAN_TABLE_MEMBERSHIP_SHIFT … /* #define DYNAMIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF #define DYNAMIC_MAC_TABLE_FID 00-000F0000-00000000 #define DYNAMIC_MAC_TABLE_SRC_PORT 00-00300000-00000000 #define DYNAMIC_MAC_TABLE_TIMESTAMP 00-00C00000-00000000 #define DYNAMIC_MAC_TABLE_ENTRIES 03-FF000000-00000000 #define DYNAMIC_MAC_TABLE_MAC_EMPTY 04-00000000-00000000 #define DYNAMIC_MAC_TABLE_RESERVED 78-00000000-00000000 #define DYNAMIC_MAC_TABLE_NOT_READY 80-00000000-00000000 */ #define DYNAMIC_MAC_TABLE_ADDR … #define DYNAMIC_MAC_TABLE_FID … #define DYNAMIC_MAC_TABLE_SRC_PORT … #define DYNAMIC_MAC_TABLE_TIMESTAMP … #define DYNAMIC_MAC_TABLE_ENTRIES … #define DYNAMIC_MAC_TABLE_ENTRIES_H … #define DYNAMIC_MAC_TABLE_MAC_EMPTY … #define DYNAMIC_MAC_TABLE_RESERVED … #define DYNAMIC_MAC_TABLE_NOT_READY … #define DYNAMIC_MAC_FID_SHIFT … #define DYNAMIC_MAC_SRC_PORT_SHIFT … #define DYNAMIC_MAC_TIMESTAMP_SHIFT … #define DYNAMIC_MAC_ENTRIES_SHIFT … #define DYNAMIC_MAC_ENTRIES_H_SHIFT … /* #define MIB_COUNTER_VALUE 00-00000000-3FFFFFFF #define MIB_COUNTER_VALID 00-00000000-40000000 #define MIB_COUNTER_OVERFLOW 00-00000000-80000000 */ #define MIB_COUNTER_VALUE … #define MIB_COUNTER_VALID … #define MIB_COUNTER_OVERFLOW … #define MIB_PACKET_DROPPED … #define KS_MIB_PACKET_DROPPED_TX_0 … #define KS_MIB_PACKET_DROPPED_TX_1 … #define KS_MIB_PACKET_DROPPED_TX … #define KS_MIB_PACKET_DROPPED_RX_0 … #define KS_MIB_PACKET_DROPPED_RX_1 … #define KS_MIB_PACKET_DROPPED_RX … /* Change default LED mode. */ #define SET_DEFAULT_LED … #define MAC_ADDR_ORDER(i) … #define MAX_ETHERNET_BODY_SIZE … #define ETHERNET_HEADER_SIZE … #define MAX_ETHERNET_PACKET_SIZE … #define REGULAR_RX_BUF_SIZE … #define MAX_RX_BUF_SIZE … #define ADDITIONAL_ENTRIES … #define MAX_MULTICAST_LIST … #define HW_MULTICAST_SIZE … #define HW_TO_DEV_PORT(port) … enum { … }; enum { … }; /* * Hardware descriptor definitions */ #define DESC_ALIGNMENT … #define BUFFER_ALIGNMENT … #define NUM_OF_RX_DESC … #define NUM_OF_TX_DESC … #define KS_DESC_RX_FRAME_LEN … #define KS_DESC_RX_FRAME_TYPE … #define KS_DESC_RX_ERROR_CRC … #define KS_DESC_RX_ERROR_RUNT … #define KS_DESC_RX_ERROR_TOO_LONG … #define KS_DESC_RX_ERROR_PHY … #define KS884X_DESC_RX_PORT_MASK … #define KS_DESC_RX_MULTICAST … #define KS_DESC_RX_ERROR … #define KS_DESC_RX_ERROR_CSUM_UDP … #define KS_DESC_RX_ERROR_CSUM_TCP … #define KS_DESC_RX_ERROR_CSUM_IP … #define KS_DESC_RX_LAST … #define KS_DESC_RX_FIRST … #define KS_DESC_RX_ERROR_COND … #define KS_DESC_HW_OWNED … #define KS_DESC_BUF_SIZE … #define KS884X_DESC_TX_PORT_MASK … #define KS_DESC_END_OF_RING … #define KS_DESC_TX_CSUM_GEN_UDP … #define KS_DESC_TX_CSUM_GEN_TCP … #define KS_DESC_TX_CSUM_GEN_IP … #define KS_DESC_TX_LAST … #define KS_DESC_TX_FIRST … #define KS_DESC_TX_INTERRUPT … #define KS_DESC_PORT_SHIFT … #define KS_DESC_RX_MASK … #define KS_DESC_TX_MASK … struct ksz_desc_rx_stat { … }; struct ksz_desc_tx_stat { … }; struct ksz_desc_rx_buf { … }; struct ksz_desc_tx_buf { … }; desc_stat; desc_buf; /** * struct ksz_hw_desc - Hardware descriptor data structure * @ctrl: Descriptor control value. * @buf: Descriptor buffer value. * @addr: Physical address of memory buffer. * @next: Pointer to next hardware descriptor. */ struct ksz_hw_desc { … }; /** * struct ksz_sw_desc - Software descriptor data structure * @ctrl: Descriptor control value. * @buf: Descriptor buffer value. * @buf_size: Current buffers size value in hardware descriptor. */ struct ksz_sw_desc { … }; /** * struct ksz_dma_buf - OS dependent DMA buffer data structure * @skb: Associated socket buffer. * @dma: Associated physical DMA address. * @len: Actual len used. */ struct ksz_dma_buf { … }; /** * struct ksz_desc - Descriptor structure * @phw: Hardware descriptor pointer to uncached physical memory. * @sw: Cached memory to hold hardware descriptor values for * manipulation. * @dma_buf: Operating system dependent data structure to hold physical * memory buffer allocation information. */ struct ksz_desc { … }; #define DMA_BUFFER(desc) … /** * struct ksz_desc_info - Descriptor information data structure * @ring: First descriptor in the ring. * @cur: Current descriptor being manipulated. * @ring_virt: First hardware descriptor in the ring. * @ring_phys: The physical address of the first descriptor of the ring. * @size: Size of hardware descriptor. * @alloc: Number of descriptors allocated. * @avail: Number of descriptors available for use. * @last: Index for last descriptor released to hardware. * @next: Index for next descriptor available for use. * @mask: Mask for index wrapping. */ struct ksz_desc_info { … }; /* * KSZ8842 switch definitions */ enum { … }; #define LEARNED_MAC_TABLE_ENTRIES … #define STATIC_MAC_TABLE_ENTRIES … /** * struct ksz_mac_table - Static MAC table data structure * @mac_addr: MAC address to filter. * @vid: VID value. * @fid: FID value. * @ports: Port membership. * @override: Override setting. * @use_fid: FID use setting. * @valid: Valid setting indicating the entry is being used. */ struct ksz_mac_table { … }; #define VLAN_TABLE_ENTRIES … /** * struct ksz_vlan_table - VLAN table data structure * @vid: VID value. * @fid: FID value. * @member: Port membership. */ struct ksz_vlan_table { … }; #define DIFFSERV_ENTRIES … #define PRIO_802_1P_ENTRIES … #define PRIO_QUEUES … #define SWITCH_PORT_NUM … #define TOTAL_PORT_NUM … #define HOST_MASK … #define PORT_MASK … #define MAIN_PORT … #define OTHER_PORT … #define HOST_PORT … #define PORT_COUNTER_NUM … #define TOTAL_PORT_COUNTER_NUM … #define MIB_COUNTER_RX_LO_PRIORITY … #define MIB_COUNTER_RX_HI_PRIORITY … #define MIB_COUNTER_RX_UNDERSIZE … #define MIB_COUNTER_RX_FRAGMENT … #define MIB_COUNTER_RX_OVERSIZE … #define MIB_COUNTER_RX_JABBER … #define MIB_COUNTER_RX_SYMBOL_ERR … #define MIB_COUNTER_RX_CRC_ERR … #define MIB_COUNTER_RX_ALIGNMENT_ERR … #define MIB_COUNTER_RX_CTRL_8808 … #define MIB_COUNTER_RX_PAUSE … #define MIB_COUNTER_RX_BROADCAST … #define MIB_COUNTER_RX_MULTICAST … #define MIB_COUNTER_RX_UNICAST … #define MIB_COUNTER_RX_OCTET_64 … #define MIB_COUNTER_RX_OCTET_65_127 … #define MIB_COUNTER_RX_OCTET_128_255 … #define MIB_COUNTER_RX_OCTET_256_511 … #define MIB_COUNTER_RX_OCTET_512_1023 … #define MIB_COUNTER_RX_OCTET_1024_1522 … #define MIB_COUNTER_TX_LO_PRIORITY … #define MIB_COUNTER_TX_HI_PRIORITY … #define MIB_COUNTER_TX_LATE_COLLISION … #define MIB_COUNTER_TX_PAUSE … #define MIB_COUNTER_TX_BROADCAST … #define MIB_COUNTER_TX_MULTICAST … #define MIB_COUNTER_TX_UNICAST … #define MIB_COUNTER_TX_DEFERRED … #define MIB_COUNTER_TX_TOTAL_COLLISION … #define MIB_COUNTER_TX_EXCESS_COLLISION … #define MIB_COUNTER_TX_SINGLE_COLLISION … #define MIB_COUNTER_TX_MULTI_COLLISION … #define MIB_COUNTER_RX_DROPPED_PACKET … #define MIB_COUNTER_TX_DROPPED_PACKET … /** * struct ksz_port_mib - Port MIB data structure * @cnt_ptr: Current pointer to MIB counter index. * @link_down: Indication the link has just gone down. * @state: Connection status of the port. * @mib_start: The starting counter index. Some ports do not start at 0. * @counter: 64-bit MIB counter value. * @dropped: Temporary buffer to remember last read packet dropped values. * * MIB counters needs to be read periodically so that counters do not get * overflowed and give incorrect values. A right balance is needed to * satisfy this condition and not waste too much CPU time. * * It is pointless to read MIB counters when the port is disconnected. The * @state provides the connection status so that MIB counters are read only * when the port is connected. The @link_down indicates the port is just * disconnected so that all MIB counters are read one last time to update the * information. */ struct ksz_port_mib { … }; /** * struct ksz_port_cfg - Port configuration data structure * @vid: VID value. * @member: Port membership. * @port_prio: Port priority. * @rx_rate: Receive priority rate. * @tx_rate: Transmit priority rate. * @stp_state: Current Spanning Tree Protocol state. */ struct ksz_port_cfg { … }; /** * struct ksz_switch - KSZ8842 switch data structure * @mac_table: MAC table entries information. * @vlan_table: VLAN table entries information. * @port_cfg: Port configuration information. * @diffserv: DiffServ priority settings. Possible values from 6-bit of ToS * (bit7 ~ bit2) field. * @p_802_1p: 802.1P priority settings. Possible values from 3-bit of 802.1p * Tag priority field. * @br_addr: Bridge address. Used for STP. * @other_addr: Other MAC address. Used for multiple network device mode. * @broad_per: Broadcast storm percentage. * @member: Current port membership. Used for STP. */ struct ksz_switch { … }; #define TX_RATE_UNIT … /** * struct ksz_port_info - Port information data structure * @state: Connection status of the port. * @tx_rate: Transmit rate divided by 10000 to get Mbit. * @duplex: Duplex mode. * @advertised: Advertised auto-negotiation setting. Used to determine link. * @partner: Auto-negotiation partner setting. Used to determine link. * @port_id: Port index to access actual hardware register. * @pdev: Pointer to OS dependent network device. */ struct ksz_port_info { … }; #define MAX_TX_HELD_SIZE … /* Hardware features and bug fixes. */ #define LINK_INT_WORKING … #define SMALL_PACKET_TX_BUG … #define HALF_DUPLEX_SIGNAL_BUG … #define RX_HUGE_FRAME … #define STP_SUPPORT … /* Software overrides. */ #define PAUSE_FLOW_CTRL … #define FAST_AGING … /** * struct ksz_hw - KSZ884X hardware data structure * @io: Virtual address assigned. * @ksz_switch: Pointer to KSZ8842 switch. * @port_info: Port information. * @port_mib: Port MIB information. * @dev_count: Number of network devices this hardware supports. * @dst_ports: Destination ports in switch for transmission. * @id: Hardware ID. Used for display only. * @mib_cnt: Number of MIB counters this hardware has. * @mib_port_cnt: Number of ports with MIB counters. * @tx_cfg: Cached transmit control settings. * @rx_cfg: Cached receive control settings. * @intr_mask: Current interrupt mask. * @intr_set: Current interrup set. * @intr_blocked: Interrupt blocked. * @rx_desc_info: Receive descriptor information. * @tx_desc_info: Transmit descriptor information. * @tx_int_cnt: Transmit interrupt count. Used for TX optimization. * @tx_int_mask: Transmit interrupt mask. Used for TX optimization. * @tx_size: Transmit data size. Used for TX optimization. * The maximum is defined by MAX_TX_HELD_SIZE. * @perm_addr: Permanent MAC address. * @override_addr: Overridden MAC address. * @address: Additional MAC address entries. * @addr_list_size: Additional MAC address list size. * @mac_override: Indication of MAC address overridden. * @promiscuous: Counter to keep track of promiscuous mode set. * @all_multi: Counter to keep track of all multicast mode set. * @multi_list: Multicast address entries. * @multi_bits: Cached multicast hash table settings. * @multi_list_size: Multicast address list size. * @enabled: Indication of hardware enabled. * @rx_stop: Indication of receive process stop. * @reserved2: none * @features: Hardware features to enable. * @overrides: Hardware features to override. * @parent: Pointer to parent, network device private structure. */ struct ksz_hw { … }; enum { … }; /** * struct ksz_port - Virtual port data structure * @duplex: Duplex mode setting. 1 for half duplex, 2 for full * duplex, and 0 for auto, which normally results in full * duplex. * @speed: Speed setting. 10 for 10 Mbit, 100 for 100 Mbit, and * 0 for auto, which normally results in 100 Mbit. * @force_link: Force link setting. 0 for auto-negotiation, and 1 for * force. * @flow_ctrl: Flow control setting. PHY_NO_FLOW_CTRL for no flow * control, and PHY_FLOW_CTRL for flow control. * PHY_TX_ONLY and PHY_RX_ONLY are not supported for 100 * Mbit PHY. * @first_port: Index of first port this port supports. * @mib_port_cnt: Number of ports with MIB counters. * @port_cnt: Number of ports this port supports. * @counter: Port statistics counter. * @hw: Pointer to hardware structure. * @linked: Pointer to port information linked to this port. */ struct ksz_port { … }; /** * struct ksz_timer_info - Timer information data structure * @timer: Kernel timer. * @cnt: Running timer counter. * @max: Number of times to run timer; -1 for infinity. * @period: Timer period in jiffies. */ struct ksz_timer_info { … }; /** * struct ksz_shared_mem - OS dependent shared memory data structure * @dma_addr: Physical DMA address allocated. * @alloc_size: Allocation size. * @phys: Actual physical address used. * @alloc_virt: Virtual address allocated. * @virt: Actual virtual address used. */ struct ksz_shared_mem { … }; /** * struct ksz_counter_info - OS dependent counter information data structure * @counter: Wait queue to wakeup after counters are read. * @time: Next time in jiffies to read counter. * @read: Indication of counters read in full or not. */ struct ksz_counter_info { … }; /** * struct dev_info - Network device information data structure * @dev: Pointer to network device. * @pdev: Pointer to PCI device. * @hw: Hardware structure. * @desc_pool: Physical memory used for descriptor pool. * @hwlock: Spinlock to prevent hardware from accessing. * @lock: Mutex lock to prevent device from accessing. * @dev_rcv: Receive process function used. * @last_skb: Socket buffer allocated for descriptor rx fragments. * @skb_index: Buffer index for receiving fragments. * @skb_len: Buffer length for receiving fragments. * @mib_read: Workqueue to read MIB counters. * @mib_timer_info: Timer to read MIB counters. * @counter: Used for MIB reading. * @mtu: Current MTU used. The default is REGULAR_RX_BUF_SIZE; * the maximum is MAX_RX_BUF_SIZE. * @opened: Counter to keep track of device open. * @rx_tasklet: Receive processing tasklet. * @tx_tasklet: Transmit processing tasklet. * @wol_enable: Wake-on-LAN enable set by ethtool. * @wol_support: Wake-on-LAN support used by ethtool. * @pme_wait: Used for KSZ8841 power management. */ struct dev_info { … }; /** * struct dev_priv - Network device private data structure * @adapter: Adapter device information. * @port: Port information. * @monitor_timer_info: Timer to monitor ports. * @proc_sem: Semaphore for proc accessing. * @id: Device ID. * @mii_if: MII interface information. * @advertising: Temporary variable to store advertised settings. * @msg_enable: The message flags controlling driver output. * @media_state: The connection status of the device. * @multicast: The all multicast state of the device. * @promiscuous: The promiscuous state of the device. */ struct dev_priv { … }; #define DRV_NAME … #define DEVICE_NAME … #define DRV_VERSION … #define DRV_RELDATE … static char version[] = …; static u8 DEFAULT_MAC_ADDRESS[] = …; /* * Interrupt processing primary routines */ static inline void hw_ack_intr(struct ksz_hw *hw, uint interrupt) { … } static inline void hw_dis_intr(struct ksz_hw *hw) { … } static inline void hw_set_intr(struct ksz_hw *hw, uint interrupt) { … } static inline void hw_ena_intr(struct ksz_hw *hw) { … } static inline void hw_dis_intr_bit(struct ksz_hw *hw, uint bit) { … } static inline void hw_turn_off_intr(struct ksz_hw *hw, uint interrupt) { … } /** * hw_turn_on_intr - turn on specified interrupts * @hw: The hardware instance. * @bit: The interrupt bits to be on. * * This routine turns on the specified interrupts in the interrupt mask so that * those interrupts will be enabled. */ static void hw_turn_on_intr(struct ksz_hw *hw, u32 bit) { … } static inline void hw_read_intr(struct ksz_hw *hw, uint *status) { … } static inline void hw_restore_intr(struct ksz_hw *hw, uint interrupt) { … } /** * hw_block_intr - block hardware interrupts * @hw: The hardware instance. * * This function blocks all interrupts of the hardware and returns the current * interrupt enable mask so that interrupts can be restored later. * * Return the current interrupt enable mask. */ static uint hw_block_intr(struct ksz_hw *hw) { … } /* * Hardware descriptor routines */ static inline void reset_desc(struct ksz_desc *desc, union desc_stat status) { … } static inline void release_desc(struct ksz_desc *desc) { … } static void get_rx_pkt(struct ksz_desc_info *info, struct ksz_desc **desc) { … } static inline void set_rx_buf(struct ksz_desc *desc, u32 addr) { … } static inline void set_rx_len(struct ksz_desc *desc, u32 len) { … } static inline void get_tx_pkt(struct ksz_desc_info *info, struct ksz_desc **desc) { … } static inline void set_tx_buf(struct ksz_desc *desc, u32 addr) { … } static inline void set_tx_len(struct ksz_desc *desc, u32 len) { … } /* Switch functions */ #define TABLE_READ … #define TABLE_SEL_SHIFT … #define HW_DELAY(hw, reg) … /** * sw_r_table - read 4 bytes of data from switch table * @hw: The hardware instance. * @table: The table selector. * @addr: The address of the table entry. * @data: Buffer to store the read data. * * This routine reads 4 bytes of data from the table of the switch. * Hardware interrupts are disabled to minimize corruption of read data. */ static void sw_r_table(struct ksz_hw *hw, int table, u16 addr, u32 *data) { … } /** * sw_w_table_64 - write 8 bytes of data to the switch table * @hw: The hardware instance. * @table: The table selector. * @addr: The address of the table entry. * @data_hi: The high part of data to be written (bit63 ~ bit32). * @data_lo: The low part of data to be written (bit31 ~ bit0). * * This routine writes 8 bytes of data to the table of the switch. * Hardware interrupts are disabled to minimize corruption of written data. */ static void sw_w_table_64(struct ksz_hw *hw, int table, u16 addr, u32 data_hi, u32 data_lo) { … } /** * sw_w_sta_mac_table - write to the static MAC table * @hw: The hardware instance. * @addr: The address of the table entry. * @mac_addr: The MAC address. * @ports: The port members. * @override: The flag to override the port receive/transmit settings. * @valid: The flag to indicate entry is valid. * @use_fid: The flag to indicate the FID is valid. * @fid: The FID value. * * This routine writes an entry of the static MAC table of the switch. It * calls sw_w_table_64() to write the data. */ static void sw_w_sta_mac_table(struct ksz_hw *hw, u16 addr, u8 *mac_addr, u8 ports, int override, int valid, int use_fid, u8 fid) { … } /** * sw_r_vlan_table - read from the VLAN table * @hw: The hardware instance. * @addr: The address of the table entry. * @vid: Buffer to store the VID. * @fid: Buffer to store the VID. * @member: Buffer to store the port membership. * * This function reads an entry of the VLAN table of the switch. It calls * sw_r_table() to get the data. * * Return 0 if the entry is valid; otherwise -1. */ static int sw_r_vlan_table(struct ksz_hw *hw, u16 addr, u16 *vid, u8 *fid, u8 *member) { … } /** * port_r_mib_cnt - read MIB counter * @hw: The hardware instance. * @port: The port index. * @addr: The address of the counter. * @cnt: Buffer to store the counter. * * This routine reads a MIB counter of the port. * Hardware interrupts are disabled to minimize corruption of read data. */ static void port_r_mib_cnt(struct ksz_hw *hw, int port, u16 addr, u64 *cnt) { … } /** * port_r_mib_pkt - read dropped packet counts * @hw: The hardware instance. * @port: The port index. * @last: last one * @cnt: Buffer to store the receive and transmit dropped packet counts. * * This routine reads the dropped packet counts of the port. * Hardware interrupts are disabled to minimize corruption of read data. */ static void port_r_mib_pkt(struct ksz_hw *hw, int port, u32 *last, u64 *cnt) { … } /** * port_r_cnt - read MIB counters periodically * @hw: The hardware instance. * @port: The port index. * * This routine is used to read the counters of the port periodically to avoid * counter overflow. The hardware should be acquired first before calling this * routine. * * Return non-zero when not all counters not read. */ static int port_r_cnt(struct ksz_hw *hw, int port) { … } /** * port_init_cnt - initialize MIB counter values * @hw: The hardware instance. * @port: The port index. * * This routine is used to initialize all counters to zero if the hardware * cannot do it after reset. */ static void port_init_cnt(struct ksz_hw *hw, int port) { … } /* * Port functions */ /** * port_cfg - set port register bits * @hw: The hardware instance. * @port: The port index. * @offset: The offset of the port register. * @bits: The data bits to set. * @set: The flag indicating whether the bits are to be set or not. * * This routine sets or resets the specified bits of the port register. */ static void port_cfg(struct ksz_hw *hw, int port, int offset, u16 bits, int set) { … } /** * port_r8 - read byte from port register * @hw: The hardware instance. * @port: The port index. * @offset: The offset of the port register. * @data: Buffer to store the data. * * This routine reads a byte from the port register. */ static void port_r8(struct ksz_hw *hw, int port, int offset, u8 *data) { … } /** * port_r16 - read word from port register. * @hw: The hardware instance. * @port: The port index. * @offset: The offset of the port register. * @data: Buffer to store the data. * * This routine reads a word from the port register. */ static void port_r16(struct ksz_hw *hw, int port, int offset, u16 *data) { … } /** * port_w16 - write word to port register. * @hw: The hardware instance. * @port: The port index. * @offset: The offset of the port register. * @data: Data to write. * * This routine writes a word to the port register. */ static void port_w16(struct ksz_hw *hw, int port, int offset, u16 data) { … } /** * sw_chk - check switch register bits * @hw: The hardware instance. * @addr: The address of the switch register. * @bits: The data bits to check. * * This function checks whether the specified bits of the switch register are * set or not. * * Return 0 if the bits are not set. */ static int sw_chk(struct ksz_hw *hw, u32 addr, u16 bits) { … } /** * sw_cfg - set switch register bits * @hw: The hardware instance. * @addr: The address of the switch register. * @bits: The data bits to set. * @set: The flag indicating whether the bits are to be set or not. * * This function sets or resets the specified bits of the switch register. */ static void sw_cfg(struct ksz_hw *hw, u32 addr, u16 bits, int set) { … } /* Bandwidth */ static inline void port_cfg_broad_storm(struct ksz_hw *hw, int p, int set) { … } /* Driver set switch broadcast storm protection at 10% rate. */ #define BROADCAST_STORM_PROTECTION_RATE … /* 148,800 frames * 67 ms / 100 */ #define BROADCAST_STORM_VALUE … /** * sw_cfg_broad_storm - configure broadcast storm threshold * @hw: The hardware instance. * @percent: Broadcast storm threshold in percent of transmit rate. * * This routine configures the broadcast storm threshold of the switch. */ static void sw_cfg_broad_storm(struct ksz_hw *hw, u8 percent) { … } /** * sw_get_broad_storm - get broadcast storm threshold * @hw: The hardware instance. * @percent: Buffer to store the broadcast storm threshold percentage. * * This routine retrieves the broadcast storm threshold of the switch. */ static void sw_get_broad_storm(struct ksz_hw *hw, u8 *percent) { … } /** * sw_dis_broad_storm - disable broadstorm * @hw: The hardware instance. * @port: The port index. * * This routine disables the broadcast storm limit function of the switch. */ static void sw_dis_broad_storm(struct ksz_hw *hw, int port) { … } /** * sw_ena_broad_storm - enable broadcast storm * @hw: The hardware instance. * @port: The port index. * * This routine enables the broadcast storm limit function of the switch. */ static void sw_ena_broad_storm(struct ksz_hw *hw, int port) { … } /** * sw_init_broad_storm - initialize broadcast storm * @hw: The hardware instance. * * This routine initializes the broadcast storm limit function of the switch. */ static void sw_init_broad_storm(struct ksz_hw *hw) { … } /** * hw_cfg_broad_storm - configure broadcast storm * @hw: The hardware instance. * @percent: Broadcast storm threshold in percent of transmit rate. * * This routine configures the broadcast storm threshold of the switch. * It is called by user functions. The hardware should be acquired first. */ static void hw_cfg_broad_storm(struct ksz_hw *hw, u8 percent) { … } /** * sw_dis_prio_rate - disable switch priority rate * @hw: The hardware instance. * @port: The port index. * * This routine disables the priority rate function of the switch. */ static void sw_dis_prio_rate(struct ksz_hw *hw, int port) { … } /** * sw_init_prio_rate - initialize switch prioirty rate * @hw: The hardware instance. * * This routine initializes the priority rate function of the switch. */ static void sw_init_prio_rate(struct ksz_hw *hw) { … } /* Communication */ static inline void port_cfg_back_pressure(struct ksz_hw *hw, int p, int set) { … } /* Mirroring */ static inline void port_cfg_mirror_sniffer(struct ksz_hw *hw, int p, int set) { … } static inline void port_cfg_mirror_rx(struct ksz_hw *hw, int p, int set) { … } static inline void port_cfg_mirror_tx(struct ksz_hw *hw, int p, int set) { … } static inline void sw_cfg_mirror_rx_tx(struct ksz_hw *hw, int set) { … } static void sw_init_mirror(struct ksz_hw *hw) { … } /* Priority */ static inline void port_cfg_diffserv(struct ksz_hw *hw, int p, int set) { … } static inline void port_cfg_802_1p(struct ksz_hw *hw, int p, int set) { … } static inline void port_cfg_replace_vid(struct ksz_hw *hw, int p, int set) { … } static inline void port_cfg_prio(struct ksz_hw *hw, int p, int set) { … } /** * sw_dis_diffserv - disable switch DiffServ priority * @hw: The hardware instance. * @port: The port index. * * This routine disables the DiffServ priority function of the switch. */ static void sw_dis_diffserv(struct ksz_hw *hw, int port) { … } /** * sw_dis_802_1p - disable switch 802.1p priority * @hw: The hardware instance. * @port: The port index. * * This routine disables the 802.1p priority function of the switch. */ static void sw_dis_802_1p(struct ksz_hw *hw, int port) { … } /** * sw_cfg_replace_null_vid - * @hw: The hardware instance. * @set: The flag to disable or enable. * */ static void sw_cfg_replace_null_vid(struct ksz_hw *hw, int set) { … } /** * sw_cfg_replace_vid - enable switch 802.10 priority re-mapping * @hw: The hardware instance. * @port: The port index. * @set: The flag to disable or enable. * * This routine enables the 802.1p priority re-mapping function of the switch. * That allows 802.1p priority field to be replaced with the port's default * tag's priority value if the ingress packet's 802.1p priority has a higher * priority than port's default tag's priority. */ static void sw_cfg_replace_vid(struct ksz_hw *hw, int port, int set) { … } /** * sw_cfg_port_based - configure switch port based priority * @hw: The hardware instance. * @port: The port index. * @prio: The priority to set. * * This routine configures the port based priority of the switch. */ static void sw_cfg_port_based(struct ksz_hw *hw, int port, u8 prio) { … } /** * sw_dis_multi_queue - disable transmit multiple queues * @hw: The hardware instance. * @port: The port index. * * This routine disables the transmit multiple queues selection of the switch * port. Only single transmit queue on the port. */ static void sw_dis_multi_queue(struct ksz_hw *hw, int port) { … } /** * sw_init_prio - initialize switch priority * @hw: The hardware instance. * * This routine initializes the switch QoS priority functions. */ static void sw_init_prio(struct ksz_hw *hw) { … } /** * port_get_def_vid - get port default VID. * @hw: The hardware instance. * @port: The port index. * @vid: Buffer to store the VID. * * This routine retrieves the default VID of the port. */ static void port_get_def_vid(struct ksz_hw *hw, int port, u16 *vid) { … } /** * sw_init_vlan - initialize switch VLAN * @hw: The hardware instance. * * This routine initializes the VLAN function of the switch. */ static void sw_init_vlan(struct ksz_hw *hw) { … } /** * sw_cfg_port_base_vlan - configure port-based VLAN membership * @hw: The hardware instance. * @port: The port index. * @member: The port-based VLAN membership. * * This routine configures the port-based VLAN membership of the port. */ static void sw_cfg_port_base_vlan(struct ksz_hw *hw, int port, u8 member) { … } /** * sw_set_addr - configure switch MAC address * @hw: The hardware instance. * @mac_addr: The MAC address. * * This function configures the MAC address of the switch. */ static void sw_set_addr(struct ksz_hw *hw, u8 *mac_addr) { … } /** * sw_set_global_ctrl - set switch global control * @hw: The hardware instance. * * This routine sets the global control of the switch function. */ static void sw_set_global_ctrl(struct ksz_hw *hw) { … } enum { … }; /** * port_set_stp_state - configure port spanning tree state * @hw: The hardware instance. * @port: The port index. * @state: The spanning tree state. * * This routine configures the spanning tree state of the port. */ static void port_set_stp_state(struct ksz_hw *hw, int port, int state) { … } #define STP_ENTRY … #define BROADCAST_ENTRY … #define BRIDGE_ADDR_ENTRY … #define IPV6_ADDR_ENTRY … /** * sw_clr_sta_mac_table - clear static MAC table * @hw: The hardware instance. * * This routine clears the static MAC table. */ static void sw_clr_sta_mac_table(struct ksz_hw *hw) { … } /** * sw_init_stp - initialize switch spanning tree support * @hw: The hardware instance. * * This routine initializes the spanning tree support of the switch. */ static void sw_init_stp(struct ksz_hw *hw) { … } /** * sw_block_addr - block certain packets from the host port * @hw: The hardware instance. * * This routine blocks certain packets from reaching to the host port. */ static void sw_block_addr(struct ksz_hw *hw) { … } static inline void hw_r_phy_ctrl(struct ksz_hw *hw, int phy, u16 *data) { … } static inline void hw_w_phy_ctrl(struct ksz_hw *hw, int phy, u16 data) { … } /** * hw_r_phy - read data from PHY register * @hw: The hardware instance. * @port: Port to read. * @reg: PHY register to read. * @val: Buffer to store the read data. * * This routine reads data from the PHY register. */ static void hw_r_phy(struct ksz_hw *hw, int port, u16 reg, u16 *val) { … } /** * hw_w_phy - write data to PHY register * @hw: The hardware instance. * @port: Port to write. * @reg: PHY register to write. * @val: Word data to write. * * This routine writes data to the PHY register. */ static void hw_w_phy(struct ksz_hw *hw, int port, u16 reg, u16 val) { … } /* * EEPROM access functions */ #define AT93C_CODE … #define AT93C_WR_OFF … #define AT93C_WR_ALL … #define AT93C_ER_ALL … #define AT93C_WR_ON … #define AT93C_WRITE … #define AT93C_READ … #define AT93C_ERASE … #define EEPROM_DELAY … static inline void drop_gpio(struct ksz_hw *hw, u8 gpio) { … } static inline void raise_gpio(struct ksz_hw *hw, u8 gpio) { … } static inline u8 state_gpio(struct ksz_hw *hw, u8 gpio) { … } static void eeprom_clk(struct ksz_hw *hw) { … } static u16 spi_r(struct ksz_hw *hw) { … } static void spi_w(struct ksz_hw *hw, u16 data) { … } static void spi_reg(struct ksz_hw *hw, u8 data, u8 reg) { … } #define EEPROM_DATA_RESERVED … #define EEPROM_DATA_MAC_ADDR_0 … #define EEPROM_DATA_MAC_ADDR_1 … #define EEPROM_DATA_MAC_ADDR_2 … #define EEPROM_DATA_SUBSYS_ID … #define EEPROM_DATA_SUBSYS_VEN_ID … #define EEPROM_DATA_PM_CAP … /* User defined EEPROM data */ #define EEPROM_DATA_OTHER_MAC_ADDR … /** * eeprom_read - read from AT93C46 EEPROM * @hw: The hardware instance. * @reg: The register offset. * * This function reads a word from the AT93C46 EEPROM. * * Return the data value. */ static u16 eeprom_read(struct ksz_hw *hw, u8 reg) { … } /** * eeprom_write - write to AT93C46 EEPROM * @hw: The hardware instance. * @reg: The register offset. * @data: The data value. * * This procedure writes a word to the AT93C46 EEPROM. */ static void eeprom_write(struct ksz_hw *hw, u8 reg, u16 data) { … } /* * Link detection routines */ static u16 advertised_flow_ctrl(struct ksz_port *port, u16 ctrl) { … } static void set_flow_ctrl(struct ksz_hw *hw, int rx, int tx) { … } static void determine_flow_ctrl(struct ksz_hw *hw, struct ksz_port *port, u16 local, u16 remote) { … } static inline void port_cfg_change(struct ksz_hw *hw, struct ksz_port *port, struct ksz_port_info *info, u16 link_status) { … } /** * port_get_link_speed - get current link status * @port: The port instance. * * This routine reads PHY registers to determine the current link status of the * switch ports. */ static void port_get_link_speed(struct ksz_port *port) { … } #define PHY_RESET_TIMEOUT … /** * port_set_link_speed - set port speed * @port: The port instance. * * This routine sets the link speed of the switch ports. */ static void port_set_link_speed(struct ksz_port *port) { … } /** * port_force_link_speed - force port speed * @port: The port instance. * * This routine forces the link speed of the switch ports. */ static void port_force_link_speed(struct ksz_port *port) { … } static void port_set_power_saving(struct ksz_port *port, int enable) { … } /* * KSZ8841 power management functions */ /** * hw_chk_wol_pme_status - check PMEN pin * @hw: The hardware instance. * * This function is used to check PMEN pin is asserted. * * Return 1 if PMEN pin is asserted; otherwise, 0. */ static int hw_chk_wol_pme_status(struct ksz_hw *hw) { … } /** * hw_clr_wol_pme_status - clear PMEN pin * @hw: The hardware instance. * * This routine is used to clear PME_Status to deassert PMEN pin. */ static void hw_clr_wol_pme_status(struct ksz_hw *hw) { … } /** * hw_cfg_wol_pme - enable or disable Wake-on-LAN * @hw: The hardware instance. * @set: The flag indicating whether to enable or disable. * * This routine is used to enable or disable Wake-on-LAN. */ static void hw_cfg_wol_pme(struct ksz_hw *hw, int set) { … } /** * hw_cfg_wol - configure Wake-on-LAN features * @hw: The hardware instance. * @frame: The pattern frame bit. * @set: The flag indicating whether to enable or disable. * * This routine is used to enable or disable certain Wake-on-LAN features. */ static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set) { … } /** * hw_set_wol_frame - program Wake-on-LAN pattern * @hw: The hardware instance. * @i: The frame index. * @mask_size: The size of the mask. * @mask: Mask to ignore certain bytes in the pattern. * @frame_size: The size of the frame. * @pattern: The frame data. * * This routine is used to program Wake-on-LAN pattern. */ static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, const u8 *mask, uint frame_size, const u8 *pattern) { … } /** * hw_add_wol_arp - add ARP pattern * @hw: The hardware instance. * @ip_addr: The IPv4 address assigned to the device. * * This routine is used to add ARP pattern for waking up the host. */ static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr) { … } /** * hw_add_wol_bcast - add broadcast pattern * @hw: The hardware instance. * * This routine is used to add broadcast pattern for waking up the host. */ static void hw_add_wol_bcast(struct ksz_hw *hw) { … } /** * hw_add_wol_mcast - add multicast pattern * @hw: The hardware instance. * * This routine is used to add multicast pattern for waking up the host. * * It is assumed the multicast packet is the ICMPv6 neighbor solicitation used * by IPv6 ping command. Note that multicast packets are filtred through the * multicast hash table, so not all multicast packets can wake up the host. */ static void hw_add_wol_mcast(struct ksz_hw *hw) { … } /** * hw_add_wol_ucast - add unicast pattern * @hw: The hardware instance. * * This routine is used to add unicast pattern to wakeup the host. * * It is assumed the unicast packet is directed to the device, as the hardware * can only receive them in normal case. */ static void hw_add_wol_ucast(struct ksz_hw *hw) { … } /** * hw_enable_wol - enable Wake-on-LAN * @hw: The hardware instance. * @wol_enable: The Wake-on-LAN settings. * @net_addr: The IPv4 address assigned to the device. * * This routine is used to enable Wake-on-LAN depending on driver settings. */ static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr) { … } /** * hw_init - check driver is correct for the hardware * @hw: The hardware instance. * * This function checks the hardware is correct for this driver and sets the * hardware up for proper initialization. * * Return number of ports or 0 if not right. */ static int hw_init(struct ksz_hw *hw) { … } /** * hw_reset - reset the hardware * @hw: The hardware instance. * * This routine resets the hardware. */ static void hw_reset(struct ksz_hw *hw) { … } /** * hw_setup - setup the hardware * @hw: The hardware instance. * * This routine setup the hardware for proper operation. */ static void hw_setup(struct ksz_hw *hw) { … } /** * hw_setup_intr - setup interrupt mask * @hw: The hardware instance. * * This routine setup the interrupt mask for proper operation. */ static void hw_setup_intr(struct ksz_hw *hw) { … } static void ksz_check_desc_num(struct ksz_desc_info *info) { … } static void hw_init_desc(struct ksz_desc_info *desc_info, int transmit) { … } /** * hw_set_desc_base - set descriptor base addresses * @hw: The hardware instance. * @tx_addr: The transmit descriptor base. * @rx_addr: The receive descriptor base. * * This routine programs the descriptor base addresses after reset. */ static void hw_set_desc_base(struct ksz_hw *hw, u32 tx_addr, u32 rx_addr) { … } static void hw_reset_pkts(struct ksz_desc_info *info) { … } static inline void hw_resume_rx(struct ksz_hw *hw) { … } /** * hw_start_rx - start receiving * @hw: The hardware instance. * * This routine starts the receive function of the hardware. */ static void hw_start_rx(struct ksz_hw *hw) { … } /** * hw_stop_rx - stop receiving * @hw: The hardware instance. * * This routine stops the receive function of the hardware. */ static void hw_stop_rx(struct ksz_hw *hw) { … } /** * hw_start_tx - start transmitting * @hw: The hardware instance. * * This routine starts the transmit function of the hardware. */ static void hw_start_tx(struct ksz_hw *hw) { … } /** * hw_stop_tx - stop transmitting * @hw: The hardware instance. * * This routine stops the transmit function of the hardware. */ static void hw_stop_tx(struct ksz_hw *hw) { … } /** * hw_disable - disable hardware * @hw: The hardware instance. * * This routine disables the hardware. */ static void hw_disable(struct ksz_hw *hw) { … } /** * hw_enable - enable hardware * @hw: The hardware instance. * * This routine enables the hardware. */ static void hw_enable(struct ksz_hw *hw) { … } /** * hw_alloc_pkt - allocate enough descriptors for transmission * @hw: The hardware instance. * @length: The length of the packet. * @physical: Number of descriptors required. * * This function allocates descriptors for transmission. * * Return 0 if not successful; 1 for buffer copy; or number of descriptors. */ static int hw_alloc_pkt(struct ksz_hw *hw, int length, int physical) { … } /** * hw_send_pkt - mark packet for transmission * @hw: The hardware instance. * * This routine marks the packet for transmission in PCI version. */ static void hw_send_pkt(struct ksz_hw *hw) { … } static int empty_addr(u8 *addr) { … } /** * hw_set_addr - set MAC address * @hw: The hardware instance. * * This routine programs the MAC address of the hardware when the address is * overridden. */ static void hw_set_addr(struct ksz_hw *hw) { … } /** * hw_read_addr - read MAC address * @hw: The hardware instance. * * This routine retrieves the MAC address of the hardware. */ static void hw_read_addr(struct ksz_hw *hw) { … } static void hw_ena_add_addr(struct ksz_hw *hw, int index, u8 *mac_addr) { … } static void hw_set_add_addr(struct ksz_hw *hw) { … } static int hw_add_addr(struct ksz_hw *hw, const u8 *mac_addr) { … } static int hw_del_addr(struct ksz_hw *hw, const u8 *mac_addr) { … } /** * hw_clr_multicast - clear multicast addresses * @hw: The hardware instance. * * This routine removes all multicast addresses set in the hardware. */ static void hw_clr_multicast(struct ksz_hw *hw) { … } /** * hw_set_grp_addr - set multicast addresses * @hw: The hardware instance. * * This routine programs multicast addresses for the hardware to accept those * addresses. */ static void hw_set_grp_addr(struct ksz_hw *hw) { … } /** * hw_set_multicast - enable or disable all multicast receiving * @hw: The hardware instance. * @multicast: To turn on or off the all multicast feature. * * This routine enables/disables the hardware to accept all multicast packets. */ static void hw_set_multicast(struct ksz_hw *hw, u8 multicast) { … } /** * hw_set_promiscuous - enable or disable promiscuous receiving * @hw: The hardware instance. * @prom: To turn on or off the promiscuous feature. * * This routine enables/disables the hardware to accept all packets. */ static void hw_set_promiscuous(struct ksz_hw *hw, u8 prom) { … } /** * sw_enable - enable the switch * @hw: The hardware instance. * @enable: The flag to enable or disable the switch * * This routine is used to enable/disable the switch in KSZ8842. */ static void sw_enable(struct ksz_hw *hw, int enable) { … } /** * sw_setup - setup the switch * @hw: The hardware instance. * * This routine setup the hardware switch engine for default operation. */ static void sw_setup(struct ksz_hw *hw) { … } /** * ksz_start_timer - start kernel timer * @info: Kernel timer information. * @time: The time tick. * * This routine starts the kernel timer after the specified time tick. */ static void ksz_start_timer(struct ksz_timer_info *info, int time) { … } /** * ksz_stop_timer - stop kernel timer * @info: Kernel timer information. * * This routine stops the kernel timer. */ static void ksz_stop_timer(struct ksz_timer_info *info) { … } static void ksz_init_timer(struct ksz_timer_info *info, int period, void (*function)(struct timer_list *)) { … } static void ksz_update_timer(struct ksz_timer_info *info) { … } /** * ksz_alloc_soft_desc - allocate software descriptors * @desc_info: Descriptor information structure. * @transmit: Indication that descriptors are for transmit. * * This local function allocates software descriptors for manipulation in * memory. * * Return 0 if successful. */ static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) { … } /** * ksz_alloc_desc - allocate hardware descriptors * @adapter: Adapter information structure. * * This local function allocates hardware descriptors for receiving and * transmitting. * * Return 0 if successful. */ static int ksz_alloc_desc(struct dev_info *adapter) { … } /** * free_dma_buf - release DMA buffer resources * @adapter: Adapter information structure. * @dma_buf: pointer to buf * @direction: to or from device * * This routine is just a helper function to release the DMA buffer resources. */ static void free_dma_buf(struct dev_info *adapter, struct ksz_dma_buf *dma_buf, int direction) { … } /** * ksz_init_rx_buffers - initialize receive descriptors * @adapter: Adapter information structure. * * This routine initializes DMA buffers for receiving. */ static void ksz_init_rx_buffers(struct dev_info *adapter) { … } /** * ksz_alloc_mem - allocate memory for hardware descriptors * @adapter: Adapter information structure. * * This function allocates memory for use by hardware descriptors for receiving * and transmitting. * * Return 0 if successful. */ static int ksz_alloc_mem(struct dev_info *adapter) { … } /** * ksz_free_desc - free software and hardware descriptors * @adapter: Adapter information structure. * * This local routine frees the software and hardware descriptors allocated by * ksz_alloc_desc(). */ static void ksz_free_desc(struct dev_info *adapter) { … } /** * ksz_free_buffers - free buffers used in the descriptors * @adapter: Adapter information structure. * @desc_info: Descriptor information structure. * @direction: to or from device * * This local routine frees buffers used in the DMA buffers. */ static void ksz_free_buffers(struct dev_info *adapter, struct ksz_desc_info *desc_info, int direction) { … } /** * ksz_free_mem - free all resources used by descriptors * @adapter: Adapter information structure. * * This local routine frees all the resources allocated by ksz_alloc_mem(). */ static void ksz_free_mem(struct dev_info *adapter) { … } static void get_mib_counters(struct ksz_hw *hw, int first, int cnt, u64 *counter) { … } /** * send_packet - send packet * @skb: Socket buffer. * @dev: Network device. * * This routine is used to send a packet out to the network. */ static void send_packet(struct sk_buff *skb, struct net_device *dev) { … } /** * transmit_cleanup - clean up transmit descriptors * @hw_priv: Network device. * @normal: break if owned * * This routine is called to clean up the transmitted buffers. */ static void transmit_cleanup(struct dev_info *hw_priv, int normal) { … } /** * tx_done - transmit done processing * @hw_priv: Network device. * * This routine is called when the transmit interrupt is triggered, indicating * either a packet is sent successfully or there are transmit errors. */ static void tx_done(struct dev_info *hw_priv) { … } static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb) { … } /** * netdev_tx - send out packet * @skb: Socket buffer. * @dev: Network device. * * This function is used by the upper network layer to send out a packet. * * Return 0 if successful; otherwise an error code indicating failure. */ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) { … } /** * netdev_tx_timeout - transmit timeout processing * @dev: Network device. * @txqueue: index of hanging queue * * This routine is called when the transmit timer expires. That indicates the * hardware is not running correctly because transmit interrupts are not * triggered to free up resources so that the transmit routine can continue * sending out packets. The hardware is reset to correct the problem. */ static void netdev_tx_timeout(struct net_device *dev, unsigned int txqueue) { … } static inline void csum_verified(struct sk_buff *skb) { … } static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw, struct ksz_desc *desc, union desc_stat status) { … } static int dev_rcv_packets(struct dev_info *hw_priv) { … } static int port_rcv_packets(struct dev_info *hw_priv) { … } static int dev_rcv_special(struct dev_info *hw_priv) { … } static void rx_proc_task(struct tasklet_struct *t) { … } static void tx_proc_task(struct tasklet_struct *t) { … } static inline void handle_rx_stop(struct ksz_hw *hw) { … } /** * netdev_intr - interrupt handling * @irq: Interrupt number. * @dev_id: Network device. * * This function is called by upper network layer to signal interrupt. * * Return IRQ_HANDLED if interrupt is handled. */ static irqreturn_t netdev_intr(int irq, void *dev_id) { … } /* * Linux network device functions */ #ifdef CONFIG_NET_POLL_CONTROLLER static void netdev_netpoll(struct net_device *dev) { … } #endif static void bridge_change(struct ksz_hw *hw) { … } /** * netdev_close - close network device * @dev: Network device. * * This function process the close operation of network device. This is caused * by the user command "ifconfig ethX down." * * Return 0 if successful; otherwise an error code indicating failure. */ static int netdev_close(struct net_device *dev) { … } static void hw_cfg_huge_frame(struct dev_info *hw_priv, struct ksz_hw *hw) { … } static int prepare_hardware(struct net_device *dev) { … } static void set_media_state(struct net_device *dev, int media_state) { … } /** * netdev_open - open network device * @dev: Network device. * * This function process the open operation of network device. This is caused * by the user command "ifconfig ethX up." * * Return 0 if successful; otherwise an error code indicating failure. */ static int netdev_open(struct net_device *dev) { … } /* RX errors = rx_errors */ /* RX dropped = rx_dropped */ /* RX overruns = rx_fifo_errors */ /* RX frame = rx_crc_errors + rx_frame_errors + rx_length_errors */ /* TX errors = tx_errors */ /* TX dropped = tx_dropped */ /* TX overruns = tx_fifo_errors */ /* TX carrier = tx_aborted_errors + tx_carrier_errors + tx_window_errors */ /* collisions = collisions */ /** * netdev_query_statistics - query network device statistics * @dev: Network device. * * This function returns the statistics of the network device. The device * needs not be opened. * * Return network device statistics. */ static struct net_device_stats *netdev_query_statistics(struct net_device *dev) { … } /** * netdev_set_mac_address - set network device MAC address * @dev: Network device. * @addr: Buffer of MAC address. * * This function is used to set the MAC address of the network device. * * Return 0 to indicate success. */ static int netdev_set_mac_address(struct net_device *dev, void *addr) { … } static void dev_set_promiscuous(struct net_device *dev, struct dev_priv *priv, struct ksz_hw *hw, int promiscuous) { … } static void dev_set_multicast(struct dev_priv *priv, struct ksz_hw *hw, int multicast) { … } /** * netdev_set_rx_mode * @dev: Network device. * * This routine is used to set multicast addresses or put the network device * into promiscuous mode. */ static void netdev_set_rx_mode(struct net_device *dev) { … } static int netdev_change_mtu(struct net_device *dev, int new_mtu) { … } /** * netdev_ioctl - I/O control processing * @dev: Network device. * @ifr: Interface request structure. * @cmd: I/O control code. * * This function is used to process I/O control calls. * * Return 0 to indicate success. */ static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { … } /* * MII support */ /** * mdio_read - read PHY register * @dev: Network device. * @phy_id: The PHY id. * @reg_num: The register number. * * This function returns the PHY register value. * * Return the register value. */ static int mdio_read(struct net_device *dev, int phy_id, int reg_num) { … } /** * mdio_write - set PHY register * @dev: Network device. * @phy_id: The PHY id. * @reg_num: The register number. * @val: The register value. * * This procedure sets the PHY register value. */ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) { … } /* * ethtool support */ #define EEPROM_SIZE … static u16 eeprom_data[EEPROM_SIZE] = …; #define ADVERTISED_ALL … /* These functions use the MII functions in mii.c. */ /** * netdev_get_link_ksettings - get network device settings * @dev: Network device. * @cmd: Ethtool command. * * This function queries the PHY and returns its state in the ethtool command. * * Return 0 if successful; otherwise an error code. */ static int netdev_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *cmd) { … } /** * netdev_set_link_ksettings - set network device settings * @dev: Network device. * @cmd: Ethtool command. * * This function sets the PHY according to the ethtool command. * * Return 0 if successful; otherwise an error code. */ static int netdev_set_link_ksettings(struct net_device *dev, const struct ethtool_link_ksettings *cmd) { … } /** * netdev_nway_reset - restart auto-negotiation * @dev: Network device. * * This function restarts the PHY for auto-negotiation. * * Return 0 if successful; otherwise an error code. */ static int netdev_nway_reset(struct net_device *dev) { … } /** * netdev_get_link - get network device link status * @dev: Network device. * * This function gets the link status from the PHY. * * Return true if PHY is linked and false otherwise. */ static u32 netdev_get_link(struct net_device *dev) { … } /** * netdev_get_drvinfo - get network driver information * @dev: Network device. * @info: Ethtool driver info data structure. * * This procedure returns the driver information. */ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { … } static struct hw_regs { … } hw_regs_range[] = …; /** * netdev_get_regs_len - get length of register dump * @dev: Network device. * * This function returns the length of the register dump. * * Return length of the register dump. */ static int netdev_get_regs_len(struct net_device *dev) { … } /** * netdev_get_regs - get register dump * @dev: Network device. * @regs: Ethtool registers data structure. * @ptr: Buffer to store the register values. * * This procedure dumps the register values in the provided buffer. */ static void netdev_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *ptr) { … } #define WOL_SUPPORT … /** * netdev_get_wol - get Wake-on-LAN support * @dev: Network device. * @wol: Ethtool Wake-on-LAN data structure. * * This procedure returns Wake-on-LAN support. */ static void netdev_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { … } /** * netdev_set_wol - set Wake-on-LAN support * @dev: Network device. * @wol: Ethtool Wake-on-LAN data structure. * * This function sets Wake-on-LAN support. * * Return 0 if successful; otherwise an error code. */ static int netdev_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { … } /** * netdev_get_msglevel - get debug message level * @dev: Network device. * * This function returns current debug message level. * * Return current debug message flags. */ static u32 netdev_get_msglevel(struct net_device *dev) { … } /** * netdev_set_msglevel - set debug message level * @dev: Network device. * @value: Debug message flags. * * This procedure sets debug message level. */ static void netdev_set_msglevel(struct net_device *dev, u32 value) { … } /** * netdev_get_eeprom_len - get EEPROM length * @dev: Network device. * * This function returns the length of the EEPROM. * * Return length of the EEPROM. */ static int netdev_get_eeprom_len(struct net_device *dev) { … } #define EEPROM_MAGIC … /** * netdev_get_eeprom - get EEPROM data * @dev: Network device. * @eeprom: Ethtool EEPROM data structure. * @data: Buffer to store the EEPROM data. * * This function dumps the EEPROM data in the provided buffer. * * Return 0 if successful; otherwise an error code. */ static int netdev_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { … } /** * netdev_set_eeprom - write EEPROM data * @dev: Network device. * @eeprom: Ethtool EEPROM data structure. * @data: Data buffer. * * This function modifies the EEPROM data one byte at a time. * * Return 0 if successful; otherwise an error code. */ static int netdev_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { … } /** * netdev_get_pauseparam - get flow control parameters * @dev: Network device. * @pause: Ethtool PAUSE settings data structure. * * This procedure returns the PAUSE control flow settings. */ static void netdev_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) { … } /** * netdev_set_pauseparam - set flow control parameters * @dev: Network device. * @pause: Ethtool PAUSE settings data structure. * * This function sets the PAUSE control flow settings. * Not implemented yet. * * Return 0 if successful; otherwise an error code. */ static int netdev_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) { … } /** * netdev_get_ringparam - get tx/rx ring parameters * @dev: Network device. * @ring: Ethtool RING settings data structure. * @kernel_ring: Ethtool external RING settings data structure. * @extack: Netlink handle. * * This procedure returns the TX/RX ring settings. */ static void netdev_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, struct kernel_ethtool_ringparam *kernel_ring, struct netlink_ext_ack *extack) { … } #define STATS_LEN … static struct { … } ethtool_stats_keys[STATS_LEN] = …; /** * netdev_get_strings - get statistics identity strings * @dev: Network device. * @stringset: String set identifier. * @buf: Buffer to store the strings. * * This procedure returns the strings used to identify the statistics. */ static void netdev_get_strings(struct net_device *dev, u32 stringset, u8 *buf) { … } /** * netdev_get_sset_count - get statistics size * @dev: Network device. * @sset: The statistics set number. * * This function returns the size of the statistics to be reported. * * Return size of the statistics to be reported. */ static int netdev_get_sset_count(struct net_device *dev, int sset) { … } /** * netdev_get_ethtool_stats - get network device statistics * @dev: Network device. * @stats: Ethtool statistics data structure. * @data: Buffer to store the statistics. * * This procedure returns the statistics. */ static void netdev_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { … } /** * netdev_set_features - set receive checksum support * @dev: Network device. * @features: New device features (offloads). * * This function sets receive checksum support setting. * * Return 0 if successful; otherwise an error code. */ static int netdev_set_features(struct net_device *dev, netdev_features_t features) { … } static const struct ethtool_ops netdev_ethtool_ops = …; /* * Hardware monitoring */ static void update_link(struct net_device *dev, struct dev_priv *priv, struct ksz_port *port) { … } static void mib_read_work(struct work_struct *work) { … } static void mib_monitor(struct timer_list *t) { … } /** * dev_monitor - periodic monitoring * @t: timer list containing a network device pointer. * * This routine is run in a kernel timer to monitor the network device. */ static void dev_monitor(struct timer_list *t) { … } /* * Linux network device interface functions */ /* Driver exported variables */ static int msg_enable; static char *macaddr = …; static char *mac1addr = …; /* * This enables multiple network device mode for KSZ8842, which contains a * switch with two physical ports. Some users like to take control of the * ports for running Spanning Tree Protocol. The driver will create an * additional eth? device for the other port. * * Some limitations are the network devices cannot have different MTU and * multicast hash tables. */ static int multi_dev; /* * As most users select multiple network device mode to use Spanning Tree * Protocol, this enables a feature in which most unicast and multicast packets * are forwarded inside the switch and not passed to the host. Only packets * that need the host's attention are passed to it. This prevents the host * wasting CPU time to examine each and every incoming packets and do the * forwarding itself. * * As the hack requires the private bridge header, the driver cannot compile * with just the kernel headers. * * Enabling STP support also turns on multiple network device mode. */ static int stp; /* * This enables fast aging in the KSZ8842 switch. Not sure what situation * needs that. However, fast aging is used to flush the dynamic MAC table when * STP support is enabled. */ static int fast_aging; /** * netdev_init - initialize network device. * @dev: Network device. * * This function initializes the network device. * * Return 0 if successful; otherwise an error code indicating failure. */ static int __init netdev_init(struct net_device *dev) { … } static const struct net_device_ops netdev_ops = …; static void netdev_free(struct net_device *dev) { … } struct platform_info { … }; static int net_device_present; static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) { … } #define KS884X_DMA_MASK … static void read_other_addr(struct ksz_hw *hw) { … } #ifndef PCI_VENDOR_ID_MICREL_KS #define PCI_VENDOR_ID_MICREL_KS … #endif static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) { … } static void pcidev_exit(struct pci_dev *pdev) { … } static int __maybe_unused pcidev_resume(struct device *dev_d) { … } static int __maybe_unused pcidev_suspend(struct device *dev_d) { … } static char pcidev_name[] = …; static const struct pci_device_id pcidev_table[] = …; MODULE_DEVICE_TABLE(pci, pcidev_table); static SIMPLE_DEV_PM_OPS(pcidev_pm_ops, pcidev_suspend, pcidev_resume); static struct pci_driver pci_device_driver = …; module_pci_driver(…) …; MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; module_param_named(message, msg_enable, int, 0); MODULE_PARM_DESC(…) …; module_param(macaddr, charp, 0); module_param(mac1addr, charp, 0); module_param(fast_aging, int, 0); module_param(multi_dev, int, 0); module_param(stp, int, 0); MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …;