^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2009-2010 Micrel, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Tristram Ha <Tristram.Ha@micrel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* DMA Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define KS_DMA_TX_CTRL 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DMA_TX_ENABLE 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DMA_TX_CRC_ENABLE 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DMA_TX_PAD_ENABLE 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DMA_TX_LOOPBACK 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DMA_TX_FLOW_ENABLE 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define DMA_TX_CSUM_IP 0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DMA_TX_CSUM_TCP 0x00020000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DMA_TX_CSUM_UDP 0x00040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DMA_TX_BURST_SIZE 0x3F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define KS_DMA_RX_CTRL 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DMA_RX_ENABLE 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define KS884X_DMA_RX_MULTICAST 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DMA_RX_PROMISCUOUS 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DMA_RX_ERROR 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DMA_RX_UNICAST 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DMA_RX_ALL_MULTICAST 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DMA_RX_BROADCAST 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DMA_RX_FLOW_ENABLE 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DMA_RX_CSUM_IP 0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DMA_RX_CSUM_TCP 0x00020000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DMA_RX_CSUM_UDP 0x00040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DMA_RX_BURST_SIZE 0x3F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DMA_BURST_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DMA_BURST_DEFAULT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define KS_DMA_TX_START 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define KS_DMA_RX_START 0x000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DMA_START 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define KS_DMA_TX_ADDR 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define KS_DMA_RX_ADDR 0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define DMA_ADDR_LIST_MASK 0xFFFFFFFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DMA_ADDR_LIST_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* MTR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define KS884X_MULTICAST_0_OFFSET 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define KS884X_MULTICAST_1_OFFSET 0x0021
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define KS884X_MULTICAST_2_OFFSET 0x0022
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define KS884x_MULTICAST_3_OFFSET 0x0023
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* MTR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define KS884X_MULTICAST_4_OFFSET 0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define KS884X_MULTICAST_5_OFFSET 0x0025
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define KS884X_MULTICAST_6_OFFSET 0x0026
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define KS884X_MULTICAST_7_OFFSET 0x0027
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Interrupt Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* INTEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define KS884X_INTERRUPTS_ENABLE 0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* INTST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define KS884X_INTERRUPTS_STATUS 0x002C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define KS884X_INT_RX_STOPPED 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define KS884X_INT_TX_STOPPED 0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define KS884X_INT_RX_OVERRUN 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define KS884X_INT_TX_EMPTY 0x10000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define KS884X_INT_RX 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define KS884X_INT_TX 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define KS884X_INT_PHY 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define KS884X_INT_RX_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (KS884X_INT_RX | KS884X_INT_RX_OVERRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define KS884X_INT_TX_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (KS884X_INT_TX | KS884X_INT_TX_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define KS884X_INT_MASK (KS884X_INT_RX | KS884X_INT_TX | KS884X_INT_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* MAC Additional Station Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* MAAL0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define KS_ADD_ADDR_0_LO 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* MAAH0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define KS_ADD_ADDR_0_HI 0x0084
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* MAAL1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define KS_ADD_ADDR_1_LO 0x0088
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* MAAH1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define KS_ADD_ADDR_1_HI 0x008C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* MAAL2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define KS_ADD_ADDR_2_LO 0x0090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* MAAH2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define KS_ADD_ADDR_2_HI 0x0094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* MAAL3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define KS_ADD_ADDR_3_LO 0x0098
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* MAAH3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define KS_ADD_ADDR_3_HI 0x009C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* MAAL4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define KS_ADD_ADDR_4_LO 0x00A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* MAAH4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define KS_ADD_ADDR_4_HI 0x00A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* MAAL5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define KS_ADD_ADDR_5_LO 0x00A8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* MAAH5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define KS_ADD_ADDR_5_HI 0x00AC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* MAAL6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define KS_ADD_ADDR_6_LO 0x00B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* MAAH6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define KS_ADD_ADDR_6_HI 0x00B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* MAAL7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define KS_ADD_ADDR_7_LO 0x00B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* MAAH7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define KS_ADD_ADDR_7_HI 0x00BC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* MAAL8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define KS_ADD_ADDR_8_LO 0x00C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* MAAH8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define KS_ADD_ADDR_8_HI 0x00C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* MAAL9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define KS_ADD_ADDR_9_LO 0x00C8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* MAAH9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define KS_ADD_ADDR_9_HI 0x00CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* MAAL10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define KS_ADD_ADDR_A_LO 0x00D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* MAAH10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define KS_ADD_ADDR_A_HI 0x00D4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* MAAL11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define KS_ADD_ADDR_B_LO 0x00D8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* MAAH11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define KS_ADD_ADDR_B_HI 0x00DC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* MAAL12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define KS_ADD_ADDR_C_LO 0x00E0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* MAAH12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define KS_ADD_ADDR_C_HI 0x00E4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* MAAL13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define KS_ADD_ADDR_D_LO 0x00E8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* MAAH13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define KS_ADD_ADDR_D_HI 0x00EC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* MAAL14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define KS_ADD_ADDR_E_LO 0x00F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* MAAH14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define KS_ADD_ADDR_E_HI 0x00F4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* MAAL15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define KS_ADD_ADDR_F_LO 0x00F8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* MAAH15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define KS_ADD_ADDR_F_HI 0x00FC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define ADD_ADDR_HI_MASK 0x0000FFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define ADD_ADDR_ENABLE 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define ADD_ADDR_INCR 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Miscellaneous Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* MARL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define KS884X_ADDR_0_OFFSET 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define KS884X_ADDR_1_OFFSET 0x0201
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* MARM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define KS884X_ADDR_2_OFFSET 0x0202
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define KS884X_ADDR_3_OFFSET 0x0203
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* MARH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define KS884X_ADDR_4_OFFSET 0x0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define KS884X_ADDR_5_OFFSET 0x0205
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* OBCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define KS884X_BUS_CTRL_OFFSET 0x0210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define BUS_SPEED_125_MHZ 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define BUS_SPEED_62_5_MHZ 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define BUS_SPEED_41_66_MHZ 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define BUS_SPEED_25_MHZ 0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* EEPCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define KS884X_EEPROM_CTRL_OFFSET 0x0212
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define EEPROM_CHIP_SELECT 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define EEPROM_SERIAL_CLOCK 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define EEPROM_DATA_OUT 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define EEPROM_DATA_IN 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define EEPROM_ACCESS_ENABLE 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* MBIR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define KS884X_MEM_INFO_OFFSET 0x0214
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define RX_MEM_TEST_FAILED 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define RX_MEM_TEST_FINISHED 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define TX_MEM_TEST_FAILED 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define TX_MEM_TEST_FINISHED 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* GCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define KS884X_GLOBAL_CTRL_OFFSET 0x0216
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define GLOBAL_SOFTWARE_RESET 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define KS8841_POWER_MANAGE_OFFSET 0x0218
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* WFCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define KS8841_WOL_CTRL_OFFSET 0x021A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define KS8841_WOL_MAGIC_ENABLE 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define KS8841_WOL_FRAME3_ENABLE 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define KS8841_WOL_FRAME2_ENABLE 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define KS8841_WOL_FRAME1_ENABLE 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define KS8841_WOL_FRAME0_ENABLE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* WF0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define KS8841_WOL_FRAME_CRC_OFFSET 0x0220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define KS8841_WOL_FRAME_BYTE0_OFFSET 0x0224
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define KS8841_WOL_FRAME_BYTE2_OFFSET 0x0228
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* IACR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define KS884X_IACR_P 0x04A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define KS884X_IACR_OFFSET KS884X_IACR_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* IADR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define KS884X_IADR1_P 0x04A2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define KS884X_IADR2_P 0x04A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define KS884X_IADR3_P 0x04A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define KS884X_IADR4_P 0x04A8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define KS884X_IADR5_P 0x04AA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define KS884X_ACC_CTRL_SEL_OFFSET KS884X_IACR_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define KS884X_ACC_CTRL_INDEX_OFFSET (KS884X_ACC_CTRL_SEL_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define KS884X_ACC_DATA_0_OFFSET KS884X_IADR4_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define KS884X_ACC_DATA_1_OFFSET (KS884X_ACC_DATA_0_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define KS884X_ACC_DATA_2_OFFSET KS884X_IADR5_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define KS884X_ACC_DATA_3_OFFSET (KS884X_ACC_DATA_2_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define KS884X_ACC_DATA_4_OFFSET KS884X_IADR2_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define KS884X_ACC_DATA_5_OFFSET (KS884X_ACC_DATA_4_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define KS884X_ACC_DATA_6_OFFSET KS884X_IADR3_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define KS884X_ACC_DATA_7_OFFSET (KS884X_ACC_DATA_6_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define KS884X_ACC_DATA_8_OFFSET KS884X_IADR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* P1MBCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define KS884X_P1MBCR_P 0x04D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define KS884X_P1MBSR_P 0x04D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define KS884X_PHY1ILR_P 0x04D4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #define KS884X_PHY1IHR_P 0x04D6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define KS884X_P1ANAR_P 0x04D8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define KS884X_P1ANLPR_P 0x04DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* P2MBCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define KS884X_P2MBCR_P 0x04E0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define KS884X_P2MBSR_P 0x04E2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define KS884X_PHY2ILR_P 0x04E4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define KS884X_PHY2IHR_P 0x04E6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #define KS884X_P2ANAR_P 0x04E8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define KS884X_P2ANLPR_P 0x04EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define KS884X_PHY_1_CTRL_OFFSET KS884X_P1MBCR_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define PHY_CTRL_INTERVAL (KS884X_P2MBCR_P - KS884X_P1MBCR_P)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define KS884X_PHY_CTRL_OFFSET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Mode Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define PHY_REG_CTRL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define PHY_RESET 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define PHY_LOOPBACK 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define PHY_SPEED_100MBIT 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define PHY_AUTO_NEG_ENABLE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define PHY_POWER_DOWN 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define PHY_MII_DISABLE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define PHY_AUTO_NEG_RESTART 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define PHY_FULL_DUPLEX 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define PHY_COLLISION_TEST 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define PHY_HP_MDIX 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #define PHY_FORCE_MDIX 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #define PHY_AUTO_MDIX_DISABLE 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define PHY_REMOTE_FAULT_DISABLE 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define PHY_TRANSMIT_DISABLE 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define PHY_LED_DISABLE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define KS884X_PHY_STATUS_OFFSET 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* Mode Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define PHY_REG_STATUS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define PHY_100BT4_CAPABLE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #define PHY_100BTX_FD_CAPABLE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define PHY_100BTX_CAPABLE 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define PHY_10BT_FD_CAPABLE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define PHY_10BT_CAPABLE 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define PHY_MII_SUPPRESS_CAPABLE 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define PHY_AUTO_NEG_ACKNOWLEDGE 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #define PHY_REMOTE_FAULT 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #define PHY_AUTO_NEG_CAPABLE 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) #define PHY_LINK_STATUS 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #define PHY_JABBER_DETECT 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #define PHY_EXTENDED_CAPABILITY 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #define KS884X_PHY_ID_1_OFFSET 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #define KS884X_PHY_ID_2_OFFSET 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* PHY Identifier Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #define PHY_REG_ID_1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #define PHY_REG_ID_2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define KS884X_PHY_AUTO_NEG_OFFSET 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Auto-Negotiation Advertisement Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define PHY_REG_AUTO_NEGOTIATION 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define PHY_AUTO_NEG_NEXT_PAGE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #define PHY_AUTO_NEG_REMOTE_FAULT 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* Not supported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #define PHY_AUTO_NEG_ASYM_PAUSE 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) #define PHY_AUTO_NEG_SYM_PAUSE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #define PHY_AUTO_NEG_100BT4 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #define PHY_AUTO_NEG_100BTX_FD 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define PHY_AUTO_NEG_100BTX 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define PHY_AUTO_NEG_10BT_FD 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #define PHY_AUTO_NEG_10BT 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #define PHY_AUTO_NEG_SELECTOR 0x001F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define PHY_AUTO_NEG_802_3 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define PHY_AUTO_NEG_PAUSE (PHY_AUTO_NEG_SYM_PAUSE | PHY_AUTO_NEG_ASYM_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define KS884X_PHY_REMOTE_CAP_OFFSET 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* Auto-Negotiation Link Partner Ability Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define PHY_REG_REMOTE_CAPABILITY 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define PHY_REMOTE_NEXT_PAGE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define PHY_REMOTE_ACKNOWLEDGE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #define PHY_REMOTE_REMOTE_FAULT 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define PHY_REMOTE_SYM_PAUSE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #define PHY_REMOTE_100BTX_FD 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define PHY_REMOTE_100BTX 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define PHY_REMOTE_10BT_FD 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #define PHY_REMOTE_10BT 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* P1VCT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #define KS884X_P1VCT_P 0x04F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define KS884X_P1PHYCTRL_P 0x04F2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* P2VCT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #define KS884X_P2VCT_P 0x04F4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #define KS884X_P2PHYCTRL_P 0x04F6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #define KS884X_PHY_SPECIAL_OFFSET KS884X_P1VCT_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #define PHY_SPECIAL_INTERVAL (KS884X_P2VCT_P - KS884X_P1VCT_P)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #define KS884X_PHY_LINK_MD_OFFSET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define PHY_START_CABLE_DIAG 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #define PHY_CABLE_DIAG_RESULT 0x6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #define PHY_CABLE_STAT_NORMAL 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #define PHY_CABLE_STAT_OPEN 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) #define PHY_CABLE_STAT_SHORT 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) #define PHY_CABLE_STAT_FAILED 0x6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) #define PHY_CABLE_10M_SHORT 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #define PHY_CABLE_FAULT_COUNTER 0x01FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #define KS884X_PHY_PHY_CTRL_OFFSET 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) #define PHY_STAT_REVERSED_POLARITY 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #define PHY_STAT_MDIX 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #define PHY_FORCE_LINK 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #define PHY_POWER_SAVING_DISABLE 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #define PHY_REMOTE_LOOPBACK 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* SIDER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #define KS884X_SIDER_P 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #define KS884X_CHIP_ID_OFFSET KS884X_SIDER_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #define KS884X_FAMILY_ID_OFFSET (KS884X_CHIP_ID_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) #define REG_FAMILY_ID 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #define REG_CHIP_ID_41 0x8810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define REG_CHIP_ID_42 0x8800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #define KS884X_CHIP_ID_MASK_41 0xFF10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define KS884X_CHIP_ID_MASK 0xFFF0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #define KS884X_CHIP_ID_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #define KS884X_REVISION_MASK 0x000E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) #define KS884X_REVISION_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #define KS8842_START 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define CHIP_IP_41_M 0x8810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) #define CHIP_IP_42_M 0x8800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) #define CHIP_IP_61_M 0x8890
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define CHIP_IP_62_M 0x8880
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #define CHIP_IP_41_P 0x8850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #define CHIP_IP_42_P 0x8840
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) #define CHIP_IP_61_P 0x88D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) #define CHIP_IP_62_P 0x88C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* SGCR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #define KS8842_SGCR1_P 0x0402
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #define KS8842_SWITCH_CTRL_1_OFFSET KS8842_SGCR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #define SWITCH_PASS_ALL 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #define SWITCH_TX_FLOW_CTRL 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #define SWITCH_RX_FLOW_CTRL 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #define SWITCH_CHECK_LENGTH 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #define SWITCH_AGING_ENABLE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #define SWITCH_FAST_AGING 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #define SWITCH_AGGR_BACKOFF 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #define SWITCH_PASS_PAUSE 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #define SWITCH_LINK_AUTO_AGING 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* SGCR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #define KS8842_SGCR2_P 0x0404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #define KS8842_SWITCH_CTRL_2_OFFSET KS8842_SGCR2_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) #define SWITCH_VLAN_ENABLE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) #define SWITCH_IGMP_SNOOP 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #define IPV6_MLD_SNOOP_ENABLE 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #define IPV6_MLD_SNOOP_OPTION 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #define PRIORITY_SCHEME_SELECT 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #define SWITCH_MIRROR_RX_TX 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #define UNICAST_VLAN_BOUNDARY 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #define MULTICAST_STORM_DISABLE 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) #define SWITCH_BACK_PRESSURE 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define FAIR_FLOW_CTRL 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #define NO_EXC_COLLISION_DROP 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #define SWITCH_HUGE_PACKET 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #define SWITCH_LEGAL_PACKET 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #define SWITCH_BUF_RESERVE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* SGCR3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) #define KS8842_SGCR3_P 0x0406
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #define KS8842_SWITCH_CTRL_3_OFFSET KS8842_SGCR3_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) #define BROADCAST_STORM_RATE_LO 0xFF00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #define SWITCH_REPEATER 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) #define SWITCH_HALF_DUPLEX 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #define SWITCH_FLOW_CTRL 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #define SWITCH_10_MBIT 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #define SWITCH_REPLACE_NULL_VID 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #define BROADCAST_STORM_RATE_HI 0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #define BROADCAST_STORM_RATE 0x07FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* SGCR4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #define KS8842_SGCR4_P 0x0408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* SGCR5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #define KS8842_SGCR5_P 0x040A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #define KS8842_SWITCH_CTRL_5_OFFSET KS8842_SGCR5_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #define LED_MODE 0x8200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #define LED_SPEED_DUPLEX_ACT 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define LED_SPEED_DUPLEX_LINK_ACT 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #define LED_DUPLEX_10_100 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* SGCR6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) #define KS8842_SGCR6_P 0x0410
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #define KS8842_SWITCH_CTRL_6_OFFSET KS8842_SGCR6_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) #define KS8842_PRIORITY_MASK 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #define KS8842_PRIORITY_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* SGCR7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #define KS8842_SGCR7_P 0x0412
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #define KS8842_SWITCH_CTRL_7_OFFSET KS8842_SGCR7_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #define SWITCH_UNK_DEF_PORT_ENABLE 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #define SWITCH_UNK_DEF_PORT_3 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) #define SWITCH_UNK_DEF_PORT_2 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #define SWITCH_UNK_DEF_PORT_1 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* MACAR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #define KS8842_MACAR1_P 0x0470
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) #define KS8842_MACAR2_P 0x0472
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #define KS8842_MACAR3_P 0x0474
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define KS8842_MAC_ADDR_1_OFFSET KS8842_MACAR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #define KS8842_MAC_ADDR_0_OFFSET (KS8842_MAC_ADDR_1_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #define KS8842_MAC_ADDR_3_OFFSET KS8842_MACAR2_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #define KS8842_MAC_ADDR_2_OFFSET (KS8842_MAC_ADDR_3_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #define KS8842_MAC_ADDR_5_OFFSET KS8842_MACAR3_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) #define KS8842_MAC_ADDR_4_OFFSET (KS8842_MAC_ADDR_5_OFFSET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* TOSR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #define KS8842_TOSR1_P 0x0480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #define KS8842_TOSR2_P 0x0482
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #define KS8842_TOSR3_P 0x0484
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #define KS8842_TOSR4_P 0x0486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #define KS8842_TOSR5_P 0x0488
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define KS8842_TOSR6_P 0x048A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #define KS8842_TOSR7_P 0x0490
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #define KS8842_TOSR8_P 0x0492
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define KS8842_TOS_1_OFFSET KS8842_TOSR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #define KS8842_TOS_2_OFFSET KS8842_TOSR2_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #define KS8842_TOS_3_OFFSET KS8842_TOSR3_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #define KS8842_TOS_4_OFFSET KS8842_TOSR4_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #define KS8842_TOS_5_OFFSET KS8842_TOSR5_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #define KS8842_TOS_6_OFFSET KS8842_TOSR6_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define KS8842_TOS_7_OFFSET KS8842_TOSR7_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #define KS8842_TOS_8_OFFSET KS8842_TOSR8_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* P1CR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #define KS8842_P1CR1_P 0x0500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #define KS8842_P1CR2_P 0x0502
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #define KS8842_P1VIDR_P 0x0504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #define KS8842_P1CR3_P 0x0506
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #define KS8842_P1IRCR_P 0x0508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #define KS8842_P1ERCR_P 0x050A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define KS884X_P1SCSLMD_P 0x0510
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #define KS884X_P1CR4_P 0x0512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define KS884X_P1SR_P 0x0514
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* P2CR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #define KS8842_P2CR1_P 0x0520
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #define KS8842_P2CR2_P 0x0522
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #define KS8842_P2VIDR_P 0x0524
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #define KS8842_P2CR3_P 0x0526
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #define KS8842_P2IRCR_P 0x0528
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #define KS8842_P2ERCR_P 0x052A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) #define KS884X_P2SCSLMD_P 0x0530
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) #define KS884X_P2CR4_P 0x0532
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #define KS884X_P2SR_P 0x0534
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* P3CR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #define KS8842_P3CR1_P 0x0540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #define KS8842_P3CR2_P 0x0542
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #define KS8842_P3VIDR_P 0x0544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #define KS8842_P3CR3_P 0x0546
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #define KS8842_P3IRCR_P 0x0548
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) #define KS8842_P3ERCR_P 0x054A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #define KS8842_PORT_1_CTRL_1 KS8842_P1CR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #define KS8842_PORT_2_CTRL_1 KS8842_P2CR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) #define KS8842_PORT_3_CTRL_1 KS8842_P3CR1_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #define PORT_CTRL_ADDR(port, addr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) (addr = KS8842_PORT_1_CTRL_1 + (port) * \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) (KS8842_PORT_2_CTRL_1 - KS8842_PORT_1_CTRL_1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) #define KS8842_PORT_CTRL_1_OFFSET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #define PORT_BROADCAST_STORM 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) #define PORT_DIFFSERV_ENABLE 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #define PORT_802_1P_ENABLE 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #define PORT_BASED_PRIORITY_MASK 0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #define PORT_BASED_PRIORITY_BASE 0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #define PORT_BASED_PRIORITY_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #define PORT_BASED_PRIORITY_0 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #define PORT_BASED_PRIORITY_1 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #define PORT_BASED_PRIORITY_2 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) #define PORT_BASED_PRIORITY_3 0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #define PORT_INSERT_TAG 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) #define PORT_REMOVE_TAG 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #define PORT_PRIO_QUEUE_ENABLE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) #define KS8842_PORT_CTRL_2_OFFSET 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) #define PORT_INGRESS_VLAN_FILTER 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #define PORT_DISCARD_NON_VID 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) #define PORT_FORCE_FLOW_CTRL 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #define PORT_BACK_PRESSURE 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) #define PORT_TX_ENABLE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #define PORT_RX_ENABLE 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) #define PORT_LEARN_DISABLE 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #define PORT_MIRROR_SNIFFER 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) #define PORT_MIRROR_RX 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) #define PORT_MIRROR_TX 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) #define PORT_USER_PRIORITY_CEILING 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) #define PORT_VLAN_MEMBERSHIP 0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #define KS8842_PORT_CTRL_VID_OFFSET 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #define PORT_DEFAULT_VID 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #define KS8842_PORT_CTRL_3_OFFSET 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #define PORT_INGRESS_LIMIT_MODE 0x000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #define PORT_INGRESS_ALL 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #define PORT_INGRESS_UNICAST 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #define PORT_INGRESS_MULTICAST 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #define PORT_INGRESS_BROADCAST 0x000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) #define PORT_COUNT_IFG 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #define PORT_COUNT_PREAMBLE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #define KS8842_PORT_IN_RATE_OFFSET 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #define KS8842_PORT_OUT_RATE_OFFSET 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) #define PORT_PRIORITY_RATE 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) #define PORT_PRIORITY_RATE_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #define KS884X_PORT_LINK_MD 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #define PORT_CABLE_10M_SHORT 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #define PORT_CABLE_DIAG_RESULT 0x6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #define PORT_CABLE_STAT_NORMAL 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #define PORT_CABLE_STAT_OPEN 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) #define PORT_CABLE_STAT_SHORT 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #define PORT_CABLE_STAT_FAILED 0x6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #define PORT_START_CABLE_DIAG 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #define PORT_FORCE_LINK 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) #define PORT_POWER_SAVING_DISABLE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #define PORT_PHY_REMOTE_LOOPBACK 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #define PORT_CABLE_FAULT_COUNTER 0x01FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #define KS884X_PORT_CTRL_4_OFFSET 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) #define PORT_LED_OFF 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #define PORT_TX_DISABLE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) #define PORT_AUTO_NEG_RESTART 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #define PORT_REMOTE_FAULT_DISABLE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) #define PORT_POWER_DOWN 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) #define PORT_AUTO_MDIX_DISABLE 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #define PORT_FORCE_MDIX 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #define PORT_LOOPBACK 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #define PORT_AUTO_NEG_ENABLE 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #define PORT_FORCE_100_MBIT 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) #define PORT_FORCE_FULL_DUPLEX 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) #define PORT_AUTO_NEG_SYM_PAUSE 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) #define PORT_AUTO_NEG_100BTX_FD 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #define PORT_AUTO_NEG_100BTX 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) #define PORT_AUTO_NEG_10BT_FD 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #define PORT_AUTO_NEG_10BT 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #define KS884X_PORT_STATUS_OFFSET 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) #define PORT_HP_MDIX 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #define PORT_REVERSED_POLARITY 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #define PORT_RX_FLOW_CTRL 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) #define PORT_TX_FLOW_CTRL 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) #define PORT_STATUS_SPEED_100MBIT 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) #define PORT_STATUS_FULL_DUPLEX 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #define PORT_REMOTE_FAULT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) #define PORT_MDIX_STATUS 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #define PORT_AUTO_NEG_COMPLETE 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) #define PORT_STATUS_LINK_GOOD 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) #define PORT_REMOTE_SYM_PAUSE 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #define PORT_REMOTE_100BTX_FD 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) #define PORT_REMOTE_100BTX 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #define PORT_REMOTE_10BT_FD 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #define PORT_REMOTE_10BT 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) #define STATIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #define STATIC_MAC_TABLE_FWD_PORTS 00-00070000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) #define STATIC_MAC_TABLE_VALID 00-00080000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) #define STATIC_MAC_TABLE_OVERRIDE 00-00100000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) #define STATIC_MAC_TABLE_USE_FID 00-00200000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) #define STATIC_MAC_TABLE_FID 00-03C00000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) #define STATIC_MAC_TABLE_ADDR 0x0000FFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) #define STATIC_MAC_TABLE_FWD_PORTS 0x00070000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) #define STATIC_MAC_TABLE_VALID 0x00080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) #define STATIC_MAC_TABLE_OVERRIDE 0x00100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #define STATIC_MAC_TABLE_USE_FID 0x00200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #define STATIC_MAC_TABLE_FID 0x03C00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #define STATIC_MAC_FWD_PORTS_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) #define STATIC_MAC_FID_SHIFT 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) #define VLAN_TABLE_VID 00-00000000-00000FFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) #define VLAN_TABLE_FID 00-00000000-0000F000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #define VLAN_TABLE_MEMBERSHIP 00-00000000-00070000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) #define VLAN_TABLE_VALID 00-00000000-00080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #define VLAN_TABLE_VID 0x00000FFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #define VLAN_TABLE_FID 0x0000F000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #define VLAN_TABLE_MEMBERSHIP 0x00070000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #define VLAN_TABLE_VALID 0x00080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) #define VLAN_TABLE_FID_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #define VLAN_TABLE_MEMBERSHIP_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #define DYNAMIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #define DYNAMIC_MAC_TABLE_FID 00-000F0000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #define DYNAMIC_MAC_TABLE_SRC_PORT 00-00300000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #define DYNAMIC_MAC_TABLE_TIMESTAMP 00-00C00000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #define DYNAMIC_MAC_TABLE_ENTRIES 03-FF000000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) #define DYNAMIC_MAC_TABLE_MAC_EMPTY 04-00000000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) #define DYNAMIC_MAC_TABLE_RESERVED 78-00000000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) #define DYNAMIC_MAC_TABLE_NOT_READY 80-00000000-00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) #define DYNAMIC_MAC_TABLE_ADDR 0x0000FFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) #define DYNAMIC_MAC_TABLE_FID 0x000F0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #define DYNAMIC_MAC_TABLE_SRC_PORT 0x00300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) #define DYNAMIC_MAC_TABLE_TIMESTAMP 0x00C00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) #define DYNAMIC_MAC_TABLE_ENTRIES 0xFF000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) #define DYNAMIC_MAC_TABLE_ENTRIES_H 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) #define DYNAMIC_MAC_TABLE_MAC_EMPTY 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) #define DYNAMIC_MAC_TABLE_RESERVED 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) #define DYNAMIC_MAC_TABLE_NOT_READY 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) #define DYNAMIC_MAC_FID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #define DYNAMIC_MAC_SRC_PORT_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) #define DYNAMIC_MAC_TIMESTAMP_SHIFT 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) #define DYNAMIC_MAC_ENTRIES_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) #define DYNAMIC_MAC_ENTRIES_H_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) #define MIB_COUNTER_VALUE 00-00000000-3FFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) #define MIB_COUNTER_VALID 00-00000000-40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) #define MIB_COUNTER_OVERFLOW 00-00000000-80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) #define MIB_COUNTER_VALUE 0x3FFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) #define MIB_COUNTER_VALID 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) #define MIB_COUNTER_OVERFLOW 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #define MIB_PACKET_DROPPED 0x0000FFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #define KS_MIB_PACKET_DROPPED_TX_0 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #define KS_MIB_PACKET_DROPPED_TX_1 0x101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) #define KS_MIB_PACKET_DROPPED_TX 0x102
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) #define KS_MIB_PACKET_DROPPED_RX_0 0x103
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #define KS_MIB_PACKET_DROPPED_RX_1 0x104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) #define KS_MIB_PACKET_DROPPED_RX 0x105
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Change default LED mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) #define SET_DEFAULT_LED LED_SPEED_DUPLEX_ACT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #define MAC_ADDR_ORDER(i) (ETH_ALEN - 1 - (i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) #define MAX_ETHERNET_BODY_SIZE 1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) #define ETHERNET_HEADER_SIZE (14 + VLAN_HLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) #define MAX_ETHERNET_PACKET_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) (MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) #define REGULAR_RX_BUF_SIZE (MAX_ETHERNET_PACKET_SIZE + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) #define MAX_RX_BUF_SIZE (1912 + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) #define ADDITIONAL_ENTRIES 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #define MAX_MULTICAST_LIST 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) #define HW_MULTICAST_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) #define HW_TO_DEV_PORT(port) (port - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) media_connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) media_disconnected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) OID_COUNTER_UNKOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) OID_COUNTER_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* total transmit errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) OID_COUNTER_XMIT_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* total receive errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) OID_COUNTER_RCV_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) OID_COUNTER_LAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * Hardware descriptor definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #define DESC_ALIGNMENT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #define BUFFER_ALIGNMENT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) #define NUM_OF_RX_DESC 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) #define NUM_OF_TX_DESC 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #define KS_DESC_RX_FRAME_LEN 0x000007FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) #define KS_DESC_RX_FRAME_TYPE 0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) #define KS_DESC_RX_ERROR_CRC 0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) #define KS_DESC_RX_ERROR_RUNT 0x00020000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) #define KS_DESC_RX_ERROR_TOO_LONG 0x00040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) #define KS_DESC_RX_ERROR_PHY 0x00080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) #define KS884X_DESC_RX_PORT_MASK 0x00300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) #define KS_DESC_RX_MULTICAST 0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) #define KS_DESC_RX_ERROR 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) #define KS_DESC_RX_ERROR_CSUM_UDP 0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) #define KS_DESC_RX_ERROR_CSUM_TCP 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) #define KS_DESC_RX_ERROR_CSUM_IP 0x10000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #define KS_DESC_RX_LAST 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #define KS_DESC_RX_FIRST 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) #define KS_DESC_RX_ERROR_COND \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) (KS_DESC_RX_ERROR_CRC | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) KS_DESC_RX_ERROR_RUNT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) KS_DESC_RX_ERROR_PHY | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) KS_DESC_RX_ERROR_TOO_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) #define KS_DESC_HW_OWNED 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) #define KS_DESC_BUF_SIZE 0x000007FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #define KS884X_DESC_TX_PORT_MASK 0x00300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) #define KS_DESC_END_OF_RING 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #define KS_DESC_TX_CSUM_GEN_UDP 0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) #define KS_DESC_TX_CSUM_GEN_TCP 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) #define KS_DESC_TX_CSUM_GEN_IP 0x10000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #define KS_DESC_TX_LAST 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #define KS_DESC_TX_FIRST 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #define KS_DESC_TX_INTERRUPT 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) #define KS_DESC_PORT_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) #define KS_DESC_RX_MASK (KS_DESC_BUF_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #define KS_DESC_TX_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) (KS_DESC_TX_INTERRUPT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) KS_DESC_TX_FIRST | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) KS_DESC_TX_LAST | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) KS_DESC_TX_CSUM_GEN_IP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) KS_DESC_TX_CSUM_GEN_TCP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) KS_DESC_TX_CSUM_GEN_UDP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) KS_DESC_BUF_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct ksz_desc_rx_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) u32 hw_owned:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) u32 first_desc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) u32 last_desc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u32 csum_err_ip:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) u32 csum_err_tcp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) u32 csum_err_udp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) u32 error:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) u32 multicast:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u32 src_port:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) u32 err_phy:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) u32 err_too_long:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) u32 err_runt:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) u32 err_crc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) u32 frame_type:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) u32 reserved1:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) u32 frame_len:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) u32 frame_len:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) u32 reserved1:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u32 frame_type:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u32 err_crc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) u32 err_runt:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) u32 err_too_long:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) u32 err_phy:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u32 src_port:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) u32 multicast:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) u32 error:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) u32 csum_err_udp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u32 csum_err_tcp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) u32 csum_err_ip:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) u32 last_desc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) u32 first_desc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u32 hw_owned:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct ksz_desc_tx_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) u32 hw_owned:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) u32 reserved1:31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) u32 reserved1:31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) u32 hw_owned:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct ksz_desc_rx_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) u32 reserved4:6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) u32 end_of_ring:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) u32 reserved3:14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) u32 buf_size:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) u32 buf_size:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u32 reserved3:14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) u32 end_of_ring:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) u32 reserved4:6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct ksz_desc_tx_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) u32 intr:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) u32 first_seg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u32 last_seg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) u32 csum_gen_ip:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) u32 csum_gen_tcp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) u32 csum_gen_udp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u32 end_of_ring:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u32 reserved4:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) u32 dest_port:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) u32 reserved3:9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) u32 buf_size:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) u32 buf_size:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) u32 reserved3:9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) u32 dest_port:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) u32 reserved4:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) u32 end_of_ring:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) u32 csum_gen_udp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) u32 csum_gen_tcp:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) u32 csum_gen_ip:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) u32 last_seg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) u32 first_seg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) u32 intr:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) union desc_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct ksz_desc_rx_stat rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct ksz_desc_tx_stat tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) union desc_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct ksz_desc_rx_buf rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct ksz_desc_tx_buf tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * struct ksz_hw_desc - Hardware descriptor data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * @ctrl: Descriptor control value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * @buf: Descriptor buffer value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * @addr: Physical address of memory buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * @next: Pointer to next hardware descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct ksz_hw_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) union desc_stat ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) union desc_buf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) u32 next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * struct ksz_sw_desc - Software descriptor data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * @ctrl: Descriptor control value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * @buf: Descriptor buffer value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * @buf_size: Current buffers size value in hardware descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct ksz_sw_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) union desc_stat ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) union desc_buf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) u32 buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * struct ksz_dma_buf - OS dependent DMA buffer data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * @skb: Associated socket buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * @dma: Associated physical DMA address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * @len: Actual len used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct ksz_dma_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) dma_addr_t dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * struct ksz_desc - Descriptor structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * @phw: Hardware descriptor pointer to uncached physical memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * @sw: Cached memory to hold hardware descriptor values for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * manipulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * @dma_buf: Operating system dependent data structure to hold physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * memory buffer allocation information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct ksz_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct ksz_hw_desc *phw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct ksz_sw_desc sw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct ksz_dma_buf dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #define DMA_BUFFER(desc) ((struct ksz_dma_buf *)(&(desc)->dma_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * struct ksz_desc_info - Descriptor information data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * @ring: First descriptor in the ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @cur: Current descriptor being manipulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * @ring_virt: First hardware descriptor in the ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * @ring_phys: The physical address of the first descriptor of the ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * @size: Size of hardware descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * @alloc: Number of descriptors allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * @avail: Number of descriptors available for use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * @last: Index for last descriptor released to hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * @next: Index for next descriptor available for use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * @mask: Mask for index wrapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct ksz_desc_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct ksz_desc *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct ksz_desc *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct ksz_hw_desc *ring_virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) u32 ring_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) int avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) int next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * KSZ8842 switch definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) TABLE_STATIC_MAC = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) TABLE_VLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) TABLE_DYNAMIC_MAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) TABLE_MIB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #define LEARNED_MAC_TABLE_ENTRIES 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #define STATIC_MAC_TABLE_ENTRIES 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * struct ksz_mac_table - Static MAC table data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * @mac_addr: MAC address to filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * @vid: VID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * @fid: FID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * @ports: Port membership.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * @override: Override setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * @use_fid: FID use setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * @valid: Valid setting indicating the entry is being used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct ksz_mac_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) u8 mac_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) u16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) u8 fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) u8 ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) u8 override:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) u8 use_fid:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) u8 valid:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) #define VLAN_TABLE_ENTRIES 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * struct ksz_vlan_table - VLAN table data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) * @vid: VID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * @fid: FID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * @member: Port membership.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct ksz_vlan_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) u16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) u8 fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) u8 member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) #define DIFFSERV_ENTRIES 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) #define PRIO_802_1P_ENTRIES 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) #define PRIO_QUEUES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) #define SWITCH_PORT_NUM 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) #define TOTAL_PORT_NUM (SWITCH_PORT_NUM + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #define HOST_MASK (1 << SWITCH_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #define PORT_MASK 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) #define MAIN_PORT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #define OTHER_PORT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) #define HOST_PORT SWITCH_PORT_NUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) #define PORT_COUNTER_NUM 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #define TOTAL_PORT_COUNTER_NUM (PORT_COUNTER_NUM + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) #define MIB_COUNTER_RX_LO_PRIORITY 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) #define MIB_COUNTER_RX_HI_PRIORITY 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) #define MIB_COUNTER_RX_UNDERSIZE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) #define MIB_COUNTER_RX_FRAGMENT 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) #define MIB_COUNTER_RX_OVERSIZE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) #define MIB_COUNTER_RX_JABBER 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) #define MIB_COUNTER_RX_SYMBOL_ERR 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) #define MIB_COUNTER_RX_CRC_ERR 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) #define MIB_COUNTER_RX_ALIGNMENT_ERR 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) #define MIB_COUNTER_RX_CTRL_8808 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) #define MIB_COUNTER_RX_PAUSE 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) #define MIB_COUNTER_RX_BROADCAST 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) #define MIB_COUNTER_RX_MULTICAST 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) #define MIB_COUNTER_RX_UNICAST 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) #define MIB_COUNTER_RX_OCTET_64 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) #define MIB_COUNTER_RX_OCTET_65_127 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) #define MIB_COUNTER_RX_OCTET_128_255 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) #define MIB_COUNTER_RX_OCTET_256_511 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) #define MIB_COUNTER_RX_OCTET_512_1023 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) #define MIB_COUNTER_RX_OCTET_1024_1522 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) #define MIB_COUNTER_TX_LO_PRIORITY 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) #define MIB_COUNTER_TX_HI_PRIORITY 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) #define MIB_COUNTER_TX_LATE_COLLISION 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) #define MIB_COUNTER_TX_PAUSE 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) #define MIB_COUNTER_TX_BROADCAST 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) #define MIB_COUNTER_TX_MULTICAST 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) #define MIB_COUNTER_TX_UNICAST 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) #define MIB_COUNTER_TX_DEFERRED 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) #define MIB_COUNTER_TX_TOTAL_COLLISION 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) #define MIB_COUNTER_TX_EXCESS_COLLISION 0x1D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) #define MIB_COUNTER_TX_SINGLE_COLLISION 0x1E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) #define MIB_COUNTER_TX_MULTI_COLLISION 0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) #define MIB_COUNTER_RX_DROPPED_PACKET 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) #define MIB_COUNTER_TX_DROPPED_PACKET 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * struct ksz_port_mib - Port MIB data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * @cnt_ptr: Current pointer to MIB counter index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * @link_down: Indication the link has just gone down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * @state: Connection status of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * @mib_start: The starting counter index. Some ports do not start at 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * @counter: 64-bit MIB counter value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * @dropped: Temporary buffer to remember last read packet dropped values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * MIB counters needs to be read periodically so that counters do not get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * overflowed and give incorrect values. A right balance is needed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * satisfy this condition and not waste too much CPU time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * It is pointless to read MIB counters when the port is disconnected. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * @state provides the connection status so that MIB counters are read only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * when the port is connected. The @link_down indicates the port is just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * disconnected so that all MIB counters are read one last time to update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct ksz_port_mib {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) u8 cnt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) u8 link_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) u8 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) u8 mib_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) u64 counter[TOTAL_PORT_COUNTER_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) u32 dropped[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * struct ksz_port_cfg - Port configuration data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * @vid: VID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * @member: Port membership.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * @port_prio: Port priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * @rx_rate: Receive priority rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) * @tx_rate: Transmit priority rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * @stp_state: Current Spanning Tree Protocol state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct ksz_port_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) u16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) u8 member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) u8 port_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) u32 rx_rate[PRIO_QUEUES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) u32 tx_rate[PRIO_QUEUES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int stp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * struct ksz_switch - KSZ8842 switch data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * @mac_table: MAC table entries information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * @vlan_table: VLAN table entries information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * @port_cfg: Port configuration information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * @diffserv: DiffServ priority settings. Possible values from 6-bit of ToS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * (bit7 ~ bit2) field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * @p_802_1p: 802.1P priority settings. Possible values from 3-bit of 802.1p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * Tag priority field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * @br_addr: Bridge address. Used for STP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * @other_addr: Other MAC address. Used for multiple network device mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * @broad_per: Broadcast storm percentage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * @member: Current port membership. Used for STP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct ksz_switch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct ksz_mac_table mac_table[STATIC_MAC_TABLE_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct ksz_vlan_table vlan_table[VLAN_TABLE_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct ksz_port_cfg port_cfg[TOTAL_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) u8 diffserv[DIFFSERV_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) u8 p_802_1p[PRIO_802_1P_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) u8 br_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) u8 other_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) u8 broad_per;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) u8 member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) #define TX_RATE_UNIT 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * struct ksz_port_info - Port information data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * @state: Connection status of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * @tx_rate: Transmit rate divided by 10000 to get Mbit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * @duplex: Duplex mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * @advertised: Advertised auto-negotiation setting. Used to determine link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * @partner: Auto-negotiation partner setting. Used to determine link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * @port_id: Port index to access actual hardware register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * @pdev: Pointer to OS dependent network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct ksz_port_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) uint state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) uint tx_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) u8 duplex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) u8 advertised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) u8 partner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) u8 port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) void *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) #define MAX_TX_HELD_SIZE 52000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* Hardware features and bug fixes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) #define LINK_INT_WORKING (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) #define SMALL_PACKET_TX_BUG (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) #define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) #define RX_HUGE_FRAME (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) #define STP_SUPPORT (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* Software overrides. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) #define PAUSE_FLOW_CTRL (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #define FAST_AGING (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * struct ksz_hw - KSZ884X hardware data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * @io: Virtual address assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * @ksz_switch: Pointer to KSZ8842 switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * @port_info: Port information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * @port_mib: Port MIB information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * @dev_count: Number of network devices this hardware supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * @dst_ports: Destination ports in switch for transmission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * @id: Hardware ID. Used for display only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * @mib_cnt: Number of MIB counters this hardware has.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * @mib_port_cnt: Number of ports with MIB counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * @tx_cfg: Cached transmit control settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * @rx_cfg: Cached receive control settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * @intr_mask: Current interrupt mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * @intr_set: Current interrup set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * @intr_blocked: Interrupt blocked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * @rx_desc_info: Receive descriptor information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * @tx_desc_info: Transmit descriptor information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * @tx_int_cnt: Transmit interrupt count. Used for TX optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * @tx_int_mask: Transmit interrupt mask. Used for TX optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * @tx_size: Transmit data size. Used for TX optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * The maximum is defined by MAX_TX_HELD_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * @perm_addr: Permanent MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * @override_addr: Overridden MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * @address: Additional MAC address entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * @addr_list_size: Additional MAC address list size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) * @mac_override: Indication of MAC address overridden.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * @promiscuous: Counter to keep track of promiscuous mode set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) * @all_multi: Counter to keep track of all multicast mode set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * @multi_list: Multicast address entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * @multi_bits: Cached multicast hash table settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * @multi_list_size: Multicast address list size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * @enabled: Indication of hardware enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * @rx_stop: Indication of receive process stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * @reserved2: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * @features: Hardware features to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * @overrides: Hardware features to override.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) * @parent: Pointer to parent, network device private structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) struct ksz_hw {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) void __iomem *io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct ksz_switch *ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct ksz_port_info port_info[SWITCH_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) struct ksz_port_mib port_mib[TOTAL_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) int dev_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int dst_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) int mib_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) int mib_port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) u32 tx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u32 rx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) u32 intr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) u32 intr_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) uint intr_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct ksz_desc_info rx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct ksz_desc_info tx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) int tx_int_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) int tx_int_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) int tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) u8 perm_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) u8 override_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) u8 address[ADDITIONAL_ENTRIES][ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) u8 addr_list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) u8 mac_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) u8 promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) u8 all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) u8 multi_list[MAX_MULTICAST_LIST][ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) u8 multi_bits[HW_MULTICAST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) u8 multi_list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) u8 enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) u8 rx_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) u8 reserved2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) uint features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) uint overrides;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) void *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) PHY_NO_FLOW_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) PHY_FLOW_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) PHY_TX_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) PHY_RX_ONLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) * struct ksz_port - Virtual port data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * @duplex: Duplex mode setting. 1 for half duplex, 2 for full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * duplex, and 0 for auto, which normally results in full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * duplex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * @speed: Speed setting. 10 for 10 Mbit, 100 for 100 Mbit, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * 0 for auto, which normally results in 100 Mbit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * @force_link: Force link setting. 0 for auto-negotiation, and 1 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) * force.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * @flow_ctrl: Flow control setting. PHY_NO_FLOW_CTRL for no flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * control, and PHY_FLOW_CTRL for flow control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * PHY_TX_ONLY and PHY_RX_ONLY are not supported for 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * Mbit PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * @first_port: Index of first port this port supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * @mib_port_cnt: Number of ports with MIB counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * @port_cnt: Number of ports this port supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) * @counter: Port statistics counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * @hw: Pointer to hardware structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * @linked: Pointer to port information linked to this port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct ksz_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) u8 duplex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) u8 speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) u8 force_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) u8 flow_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) int first_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int mib_port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) int port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) u64 counter[OID_COUNTER_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct ksz_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) struct ksz_port_info *linked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * struct ksz_timer_info - Timer information data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * @timer: Kernel timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * @cnt: Running timer counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * @max: Number of times to run timer; -1 for infinity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * @period: Timer period in jiffies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) struct ksz_timer_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) int max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) int period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * struct ksz_shared_mem - OS dependent shared memory data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * @dma_addr: Physical DMA address allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * @alloc_size: Allocation size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * @phys: Actual physical address used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * @alloc_virt: Virtual address allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * @virt: Actual virtual address used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct ksz_shared_mem {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) uint alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) uint phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) u8 *alloc_virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) u8 *virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * struct ksz_counter_info - OS dependent counter information data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) * @counter: Wait queue to wakeup after counters are read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * @time: Next time in jiffies to read counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * @read: Indication of counters read in full or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct ksz_counter_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) wait_queue_head_t counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) unsigned long time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) int read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) * struct dev_info - Network device information data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) * @dev: Pointer to network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) * @pdev: Pointer to PCI device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) * @hw: Hardware structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * @desc_pool: Physical memory used for descriptor pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * @hwlock: Spinlock to prevent hardware from accessing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * @lock: Mutex lock to prevent device from accessing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * @dev_rcv: Receive process function used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * @last_skb: Socket buffer allocated for descriptor rx fragments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * @skb_index: Buffer index for receiving fragments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * @skb_len: Buffer length for receiving fragments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * @mib_read: Workqueue to read MIB counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * @mib_timer_info: Timer to read MIB counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * @counter: Used for MIB reading.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * @mtu: Current MTU used. The default is REGULAR_RX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) * the maximum is MAX_RX_BUF_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * @opened: Counter to keep track of device open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * @rx_tasklet: Receive processing tasklet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) * @tx_tasklet: Transmit processing tasklet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) * @wol_enable: Wake-on-LAN enable set by ethtool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * @wol_support: Wake-on-LAN support used by ethtool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) * @pme_wait: Used for KSZ8841 power management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) struct dev_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct ksz_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) struct ksz_shared_mem desc_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) spinlock_t hwlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int (*dev_rcv)(struct dev_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct sk_buff *last_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) int skb_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) int skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct work_struct mib_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct ksz_timer_info mib_timer_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct ksz_counter_info counter[TOTAL_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) int mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) int opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) struct tasklet_struct rx_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct tasklet_struct tx_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) int wol_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) int wol_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) unsigned long pme_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * struct dev_priv - Network device private data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * @adapter: Adapter device information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * @port: Port information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * @monitor_timer_info: Timer to monitor ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * @proc_sem: Semaphore for proc accessing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * @id: Device ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * @mii_if: MII interface information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * @advertising: Temporary variable to store advertised settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * @msg_enable: The message flags controlling driver output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * @media_state: The connection status of the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * @multicast: The all multicast state of the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * @promiscuous: The promiscuous state of the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) struct dev_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct dev_info *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct ksz_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) struct ksz_timer_info monitor_timer_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct semaphore proc_sem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct mii_if_info mii_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) u32 advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) u32 msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) int media_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) int multicast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) int promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) #define DRV_NAME "KSZ884X PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) #define DEVICE_NAME "KSZ884x PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) #define DRV_VERSION "1.0.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) #define DRV_RELDATE "Feb 8, 2010"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) static char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) "Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * Interrupt processing primary routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static inline void hw_ack_intr(struct ksz_hw *hw, uint interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) writel(interrupt, hw->io + KS884X_INTERRUPTS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) static inline void hw_dis_intr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) hw->intr_blocked = hw->intr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) writel(0, hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) hw->intr_set = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static inline void hw_set_intr(struct ksz_hw *hw, uint interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) hw->intr_set = interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) writel(interrupt, hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) static inline void hw_ena_intr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) hw->intr_blocked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) hw_set_intr(hw, hw->intr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) static inline void hw_dis_intr_bit(struct ksz_hw *hw, uint bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) hw->intr_mask &= ~(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) static inline void hw_turn_off_intr(struct ksz_hw *hw, uint interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) u32 read_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) hw->intr_set = read_intr & ~interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) hw_dis_intr_bit(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * hw_turn_on_intr - turn on specified interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * @bit: The interrupt bits to be on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * This routine turns on the specified interrupts in the interrupt mask so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * those interrupts will be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) static void hw_turn_on_intr(struct ksz_hw *hw, u32 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) hw->intr_mask |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (!hw->intr_blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) hw_set_intr(hw, hw->intr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static inline void hw_ena_intr_bit(struct ksz_hw *hw, uint interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) u32 read_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) hw->intr_set = read_intr | interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) static inline void hw_read_intr(struct ksz_hw *hw, uint *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) *status = readl(hw->io + KS884X_INTERRUPTS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) *status = *status & hw->intr_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) static inline void hw_restore_intr(struct ksz_hw *hw, uint interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) hw_ena_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * hw_block_intr - block hardware interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * This function blocks all interrupts of the hardware and returns the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * interrupt enable mask so that interrupts can be restored later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * Return the current interrupt enable mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static uint hw_block_intr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) uint interrupt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (!hw->intr_blocked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) hw_dis_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) interrupt = hw->intr_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) return interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * Hardware descriptor routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static inline void reset_desc(struct ksz_desc *desc, union desc_stat status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) status.rx.hw_owned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) desc->phw->ctrl.data = cpu_to_le32(status.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static inline void release_desc(struct ksz_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) desc->sw.ctrl.tx.hw_owned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (desc->sw.buf_size != desc->sw.buf.data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) desc->sw.buf_size = desc->sw.buf.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) desc->phw->buf.data = cpu_to_le32(desc->sw.buf.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) desc->phw->ctrl.data = cpu_to_le32(desc->sw.ctrl.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) static void get_rx_pkt(struct ksz_desc_info *info, struct ksz_desc **desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) *desc = &info->ring[info->last];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) info->last++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) info->last &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) info->avail--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) (*desc)->sw.buf.data &= ~KS_DESC_RX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) static inline void set_rx_buf(struct ksz_desc *desc, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) desc->phw->addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) static inline void set_rx_len(struct ksz_desc *desc, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) desc->sw.buf.rx.buf_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) static inline void get_tx_pkt(struct ksz_desc_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) struct ksz_desc **desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) *desc = &info->ring[info->next];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) info->next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) info->next &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) info->avail--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) (*desc)->sw.buf.data &= ~KS_DESC_TX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) static inline void set_tx_buf(struct ksz_desc *desc, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) desc->phw->addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) static inline void set_tx_len(struct ksz_desc *desc, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) desc->sw.buf.tx.buf_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* Switch functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) #define TABLE_READ 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) #define TABLE_SEL_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) #define HW_DELAY(hw, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) readw(hw->io + reg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) * sw_r_table - read 4 bytes of data from switch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) * @table: The table selector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * @addr: The address of the table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * @data: Buffer to store the read data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) * This routine reads 4 bytes of data from the table of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * Hardware interrupts are disabled to minimize corruption of read data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) static void sw_r_table(struct ksz_hw *hw, int table, u16 addr, u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) ctrl_addr = (((table << TABLE_SEL_SHIFT) | TABLE_READ) << 8) | addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) HW_DELAY(hw, KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) *data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * sw_w_table_64 - write 8 bytes of data to the switch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) * @table: The table selector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * @addr: The address of the table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * @data_hi: The high part of data to be written (bit63 ~ bit32).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * @data_lo: The low part of data to be written (bit31 ~ bit0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * This routine writes 8 bytes of data to the table of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * Hardware interrupts are disabled to minimize corruption of written data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) static void sw_w_table_64(struct ksz_hw *hw, int table, u16 addr, u32 data_hi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) u32 data_lo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) ctrl_addr = ((table << TABLE_SEL_SHIFT) << 8) | addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) writel(data_hi, hw->io + KS884X_ACC_DATA_4_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) writel(data_lo, hw->io + KS884X_ACC_DATA_0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) HW_DELAY(hw, KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * sw_w_sta_mac_table - write to the static MAC table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * @addr: The address of the table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * @mac_addr: The MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) * @ports: The port members.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * @override: The flag to override the port receive/transmit settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) * @valid: The flag to indicate entry is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * @use_fid: The flag to indicate the FID is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * @fid: The FID value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * This routine writes an entry of the static MAC table of the switch. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * calls sw_w_table_64() to write the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) static void sw_w_sta_mac_table(struct ksz_hw *hw, u16 addr, u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) u8 ports, int override, int valid, int use_fid, u8 fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) u32 data_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) u32 data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) data_lo = ((u32) mac_addr[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ((u32) mac_addr[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) ((u32) mac_addr[4] << 8) | mac_addr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) data_hi = ((u32) mac_addr[0] << 8) | mac_addr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) data_hi |= (u32) ports << STATIC_MAC_FWD_PORTS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) data_hi |= STATIC_MAC_TABLE_OVERRIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (use_fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) data_hi |= STATIC_MAC_TABLE_USE_FID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) data_hi |= (u32) fid << STATIC_MAC_FID_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) data_hi |= STATIC_MAC_TABLE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) sw_w_table_64(hw, TABLE_STATIC_MAC, addr, data_hi, data_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) * sw_r_vlan_table - read from the VLAN table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) * @addr: The address of the table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) * @vid: Buffer to store the VID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) * @fid: Buffer to store the VID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) * @member: Buffer to store the port membership.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) * This function reads an entry of the VLAN table of the switch. It calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) * sw_r_table() to get the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) * Return 0 if the entry is valid; otherwise -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) static int sw_r_vlan_table(struct ksz_hw *hw, u16 addr, u16 *vid, u8 *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) u8 *member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) sw_r_table(hw, TABLE_VLAN, addr, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (data & VLAN_TABLE_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) *vid = (u16)(data & VLAN_TABLE_VID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) *fid = (u8)((data & VLAN_TABLE_FID) >> VLAN_TABLE_FID_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) *member = (u8)((data & VLAN_TABLE_MEMBERSHIP) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) VLAN_TABLE_MEMBERSHIP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) * port_r_mib_cnt - read MIB counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * @addr: The address of the counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) * @cnt: Buffer to store the counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * This routine reads a MIB counter of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) * Hardware interrupts are disabled to minimize corruption of read data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static void port_r_mib_cnt(struct ksz_hw *hw, int port, u16 addr, u64 *cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) ctrl_addr = addr + PORT_COUNTER_NUM * port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) HW_DELAY(hw, KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) for (timeout = 100; timeout > 0; timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (data & MIB_COUNTER_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (data & MIB_COUNTER_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) *cnt += MIB_COUNTER_VALUE + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) *cnt += data & MIB_COUNTER_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) * port_r_mib_pkt - read dropped packet counts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) * @last: last one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) * @cnt: Buffer to store the receive and transmit dropped packet counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) * This routine reads the dropped packet counts of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * Hardware interrupts are disabled to minimize corruption of read data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static void port_r_mib_pkt(struct ksz_hw *hw, int port, u32 *last, u64 *cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) u32 cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) index = KS_MIB_PACKET_DROPPED_RX_0 + port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) ctrl_addr = (u16) index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) HW_DELAY(hw, KS884X_IACR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) data &= MIB_PACKET_DROPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) cur = *last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (data != cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) *last = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) if (data < cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) data += MIB_PACKET_DROPPED + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) data -= cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) *cnt += data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) ++last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) ++cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) index -= KS_MIB_PACKET_DROPPED_TX -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) KS_MIB_PACKET_DROPPED_TX_0 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) } while (index >= KS_MIB_PACKET_DROPPED_TX_0 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * port_r_cnt - read MIB counters periodically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) * This routine is used to read the counters of the port periodically to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) * counter overflow. The hardware should be acquired first before calling this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) * routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) * Return non-zero when not all counters not read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) static int port_r_cnt(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) struct ksz_port_mib *mib = &hw->port_mib[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (mib->mib_start < PORT_COUNTER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) while (mib->cnt_ptr < PORT_COUNTER_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) port_r_mib_cnt(hw, port, mib->cnt_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) &mib->counter[mib->cnt_ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) ++mib->cnt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (hw->mib_cnt > PORT_COUNTER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) port_r_mib_pkt(hw, port, mib->dropped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) &mib->counter[PORT_COUNTER_NUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) mib->cnt_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) * port_init_cnt - initialize MIB counter values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) * This routine is used to initialize all counters to zero if the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) * cannot do it after reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) static void port_init_cnt(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct ksz_port_mib *mib = &hw->port_mib[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) mib->cnt_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (mib->mib_start < PORT_COUNTER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) port_r_mib_cnt(hw, port, mib->cnt_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) &mib->counter[mib->cnt_ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) ++mib->cnt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) } while (mib->cnt_ptr < PORT_COUNTER_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (hw->mib_cnt > PORT_COUNTER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) port_r_mib_pkt(hw, port, mib->dropped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) &mib->counter[PORT_COUNTER_NUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) memset((void *) mib->counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) mib->cnt_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * Port functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * port_chk - check port register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) * @offset: The offset of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * @bits: The data bits to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) * This function checks whether the specified bits of the port register are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) * or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * Return 0 if the bits are not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) static int port_chk(struct ksz_hw *hw, int port, int offset, u16 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) addr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return (data & bits) == bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * port_cfg - set port register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * @offset: The offset of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * @bits: The data bits to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * @set: The flag indicating whether the bits are to be set or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) * This routine sets or resets the specified bits of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static void port_cfg(struct ksz_hw *hw, int port, int offset, u16 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) addr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) data |= bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) data &= ~bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) writew(data, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) * port_chk_shift - check port bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) * @addr: The offset of the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) * @shift: Number of bits to shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * This function checks whether the specified port is set in the register or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) * not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) * Return 0 if the port is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) static int port_chk_shift(struct ksz_hw *hw, int port, u32 addr, int shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) u16 bit = 1 << port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) data >>= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) return (data & bit) == bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) * port_cfg_shift - set port bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) * @addr: The offset of the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * @shift: Number of bits to shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * @set: The flag indicating whether the port is to be set or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) * This routine sets or resets the specified port in the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) static void port_cfg_shift(struct ksz_hw *hw, int port, u32 addr, int shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) u16 bits = 1 << port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) bits <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) data |= bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) data &= ~bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) writew(data, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) * port_r8 - read byte from port register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) * @offset: The offset of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) * @data: Buffer to store the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * This routine reads a byte from the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) static void port_r8(struct ksz_hw *hw, int port, int offset, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) addr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) *data = readb(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * port_r16 - read word from port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) * @offset: The offset of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * @data: Buffer to store the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) * This routine reads a word from the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static void port_r16(struct ksz_hw *hw, int port, int offset, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) addr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) *data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * port_w16 - write word to port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * @offset: The offset of the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * @data: Data to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * This routine writes a word to the port register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) static void port_w16(struct ksz_hw *hw, int port, int offset, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) addr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) writew(data, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) * sw_chk - check switch register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * @addr: The address of the switch register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) * @bits: The data bits to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * This function checks whether the specified bits of the switch register are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) * set or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * Return 0 if the bits are not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) static int sw_chk(struct ksz_hw *hw, u32 addr, u16 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return (data & bits) == bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * sw_cfg - set switch register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) * @addr: The address of the switch register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * @bits: The data bits to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) * @set: The flag indicating whether the bits are to be set or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * This function sets or resets the specified bits of the switch register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) static void sw_cfg(struct ksz_hw *hw, u32 addr, u16 bits, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) data = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) data |= bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) data &= ~bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) writew(data, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) /* Bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) static inline void port_cfg_broad_storm(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) static inline int port_chk_broad_storm(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) /* Driver set switch broadcast storm protection at 10% rate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) #define BROADCAST_STORM_PROTECTION_RATE 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /* 148,800 frames * 67 ms / 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) #define BROADCAST_STORM_VALUE 9969
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) * sw_cfg_broad_storm - configure broadcast storm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) * @percent: Broadcast storm threshold in percent of transmit rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) * This routine configures the broadcast storm threshold of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) static void sw_cfg_broad_storm(struct ksz_hw *hw, u8 percent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) u32 value = ((u32) BROADCAST_STORM_VALUE * (u32) percent / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) if (value > BROADCAST_STORM_RATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) value = BROADCAST_STORM_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) data &= ~(BROADCAST_STORM_RATE_LO | BROADCAST_STORM_RATE_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) data |= ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) * sw_get_board_storm - get broadcast storm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) * @percent: Buffer to store the broadcast storm threshold percentage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) * This routine retrieves the broadcast storm threshold of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) static void sw_get_broad_storm(struct ksz_hw *hw, u8 *percent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) num = (data & BROADCAST_STORM_RATE_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) num <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) num |= (data & BROADCAST_STORM_RATE_LO) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) num = DIV_ROUND_CLOSEST(num * 100, BROADCAST_STORM_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) *percent = (u8) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * sw_dis_broad_storm - disable broadstorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * This routine disables the broadcast storm limit function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static void sw_dis_broad_storm(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) port_cfg_broad_storm(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * sw_ena_broad_storm - enable broadcast storm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) * This routine enables the broadcast storm limit function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) static void sw_ena_broad_storm(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) port_cfg_broad_storm(hw, port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) * sw_init_broad_storm - initialize broadcast storm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) * This routine initializes the broadcast storm limit function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) static void sw_init_broad_storm(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) hw->ksz_switch->broad_per = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) for (port = 0; port < TOTAL_PORT_NUM; port++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) sw_dis_broad_storm(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, MULTICAST_STORM_DISABLE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * hw_cfg_broad_storm - configure broadcast storm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) * @percent: Broadcast storm threshold in percent of transmit rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * This routine configures the broadcast storm threshold of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * It is called by user functions. The hardware should be acquired first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static void hw_cfg_broad_storm(struct ksz_hw *hw, u8 percent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (percent > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) percent = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) sw_cfg_broad_storm(hw, percent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) sw_get_broad_storm(hw, &percent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) hw->ksz_switch->broad_per = percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) * sw_dis_prio_rate - disable switch priority rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) * This routine disables the priority rate function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) static void sw_dis_prio_rate(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) addr += KS8842_PORT_IN_RATE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) writel(0, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) * sw_init_prio_rate - initialize switch prioirty rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * This routine initializes the priority rate function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) static void sw_init_prio_rate(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) int prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) for (port = 0; port < TOTAL_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) for (prio = 0; prio < PRIO_QUEUES; prio++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) sw->port_cfg[port].rx_rate[prio] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) sw->port_cfg[port].tx_rate[prio] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) sw_dis_prio_rate(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) /* Communication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static inline void port_cfg_back_pressure(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static inline void port_cfg_force_flow_ctrl(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) static inline int port_chk_back_pressure(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) /* Spanning Tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) KS8842_PORT_CTRL_2_OFFSET, PORT_RX_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) static inline void port_cfg_tx(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) KS8842_PORT_CTRL_2_OFFSET, PORT_TX_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) static inline void sw_cfg_fast_aging(struct ksz_hw *hw, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, SWITCH_FAST_AGING, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) static inline void sw_flush_dyn_mac_table(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (!(hw->overrides & FAST_AGING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) sw_cfg_fast_aging(hw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) sw_cfg_fast_aging(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) /* VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) static inline void port_cfg_ins_tag(struct ksz_hw *hw, int p, int insert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG, insert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) static inline void port_cfg_rmv_tag(struct ksz_hw *hw, int p, int remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG, remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static inline int port_chk_ins_tag(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) static inline int port_chk_rmv_tag(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) static inline void port_cfg_dis_non_vid(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) static inline void port_cfg_in_filter(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) static inline int port_chk_dis_non_vid(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) static inline int port_chk_in_filter(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) /* Mirroring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) static inline void port_cfg_mirror_sniffer(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_SNIFFER, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) static inline void port_cfg_mirror_rx(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_RX, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) static inline void port_cfg_mirror_tx(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_TX, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) static inline void sw_cfg_mirror_rx_tx(struct ksz_hw *hw, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, SWITCH_MIRROR_RX_TX, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) static void sw_init_mirror(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) for (port = 0; port < TOTAL_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) port_cfg_mirror_sniffer(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) port_cfg_mirror_rx(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) port_cfg_mirror_tx(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) sw_cfg_mirror_rx_tx(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static inline void sw_cfg_unk_def_deliver(struct ksz_hw *hw, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) sw_cfg(hw, KS8842_SWITCH_CTRL_7_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) SWITCH_UNK_DEF_PORT_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) static inline int sw_cfg_chk_unk_def_deliver(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) return sw_chk(hw, KS8842_SWITCH_CTRL_7_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) SWITCH_UNK_DEF_PORT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) static inline void sw_cfg_unk_def_port(struct ksz_hw *hw, int port, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) port_cfg_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) static inline int sw_chk_unk_def_port(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) return port_chk_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) /* Priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) static inline void port_cfg_diffserv(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) static inline void port_cfg_802_1p(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) static inline void port_cfg_replace_vid(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) static inline void port_cfg_prio(struct ksz_hw *hw, int p, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) static inline int port_chk_diffserv(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) static inline int port_chk_802_1p(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) static inline int port_chk_replace_vid(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) static inline int port_chk_prio(struct ksz_hw *hw, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) return port_chk(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) * sw_dis_diffserv - disable switch DiffServ priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) * This routine disables the DiffServ priority function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static void sw_dis_diffserv(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) port_cfg_diffserv(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) * sw_dis_802_1p - disable switch 802.1p priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) * This routine disables the 802.1p priority function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) static void sw_dis_802_1p(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) port_cfg_802_1p(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) * sw_cfg_replace_null_vid -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) * @set: The flag to disable or enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) static void sw_cfg_replace_null_vid(struct ksz_hw *hw, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) sw_cfg(hw, KS8842_SWITCH_CTRL_3_OFFSET, SWITCH_REPLACE_NULL_VID, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) * sw_cfg_replace_vid - enable switch 802.10 priority re-mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) * @set: The flag to disable or enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) * This routine enables the 802.1p priority re-mapping function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) * That allows 802.1p priority field to be replaced with the port's default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) * tag's priority value if the ingress packet's 802.1p priority has a higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) * priority than port's default tag's priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) static void sw_cfg_replace_vid(struct ksz_hw *hw, int port, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) port_cfg_replace_vid(hw, port, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) * sw_cfg_port_based - configure switch port based priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) * @prio: The priority to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) * This routine configures the port based priority of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) static void sw_cfg_port_based(struct ksz_hw *hw, int port, u8 prio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) if (prio > PORT_BASED_PRIORITY_BASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) prio = PORT_BASED_PRIORITY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) hw->ksz_switch->port_cfg[port].port_prio = prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) port_r16(hw, port, KS8842_PORT_CTRL_1_OFFSET, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) data &= ~PORT_BASED_PRIORITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) data |= prio << PORT_BASED_PRIORITY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) port_w16(hw, port, KS8842_PORT_CTRL_1_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) * sw_dis_multi_queue - disable transmit multiple queues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) * This routine disables the transmit multiple queues selection of the switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) * port. Only single transmit queue on the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) static void sw_dis_multi_queue(struct ksz_hw *hw, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) port_cfg_prio(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) * sw_init_prio - initialize switch priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) * This routine initializes the switch QoS priority functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) static void sw_init_prio(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) int tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) * Init all the 802.1p tag priority value to be assigned to different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) * priority queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) sw->p_802_1p[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) sw->p_802_1p[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) sw->p_802_1p[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) sw->p_802_1p[3] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) sw->p_802_1p[4] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) sw->p_802_1p[5] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) sw->p_802_1p[6] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) sw->p_802_1p[7] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) * Init all the DiffServ priority value to be assigned to priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * queue 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) for (tos = 0; tos < DIFFSERV_ENTRIES; tos++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) sw->diffserv[tos] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) /* All QoS functions disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) for (port = 0; port < TOTAL_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) sw_dis_multi_queue(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) sw_dis_diffserv(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) sw_dis_802_1p(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) sw_cfg_replace_vid(hw, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) sw->port_cfg[port].port_prio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) sw_cfg_port_based(hw, port, sw->port_cfg[port].port_prio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) sw_cfg_replace_null_vid(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) * port_get_def_vid - get port default VID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) * @vid: Buffer to store the VID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) * This routine retrieves the default VID of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) static void port_get_def_vid(struct ksz_hw *hw, int port, u16 *vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) addr += KS8842_PORT_CTRL_VID_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) *vid = readw(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) * sw_init_vlan - initialize switch VLAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) * This routine initializes the VLAN function of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) static void sw_init_vlan(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) int entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) /* Read 16 VLAN entries from device's VLAN table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) for (entry = 0; entry < VLAN_TABLE_ENTRIES; entry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) sw_r_vlan_table(hw, entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) &sw->vlan_table[entry].vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) &sw->vlan_table[entry].fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) &sw->vlan_table[entry].member);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) for (port = 0; port < TOTAL_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) port_get_def_vid(hw, port, &sw->port_cfg[port].vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) sw->port_cfg[port].member = PORT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) * sw_cfg_port_base_vlan - configure port-based VLAN membership
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) * @member: The port-based VLAN membership.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) * This routine configures the port-based VLAN membership of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) static void sw_cfg_port_base_vlan(struct ksz_hw *hw, int port, u8 member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) PORT_CTRL_ADDR(port, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) addr += KS8842_PORT_CTRL_2_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) data = readb(hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) data &= ~PORT_VLAN_MEMBERSHIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) data |= (member & PORT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) writeb(data, hw->io + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) hw->ksz_switch->port_cfg[port].member = member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) * sw_get_addr - get the switch MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) * @mac_addr: Buffer to store the MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) * This function retrieves the MAC address of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) static inline void sw_get_addr(struct ksz_hw *hw, u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) for (i = 0; i < 6; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) mac_addr[i] = readb(hw->io + KS8842_MAC_ADDR_0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) mac_addr[1 + i] = readb(hw->io + KS8842_MAC_ADDR_1_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) * sw_set_addr - configure switch MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) * @mac_addr: The MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) * This function configures the MAC address of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) static void sw_set_addr(struct ksz_hw *hw, u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) for (i = 0; i < 6; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) writeb(mac_addr[i], hw->io + KS8842_MAC_ADDR_0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) writeb(mac_addr[1 + i], hw->io + KS8842_MAC_ADDR_1_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) * sw_set_global_ctrl - set switch global control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) * This routine sets the global control of the switch function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) static void sw_set_global_ctrl(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) /* Enable switch MII flow control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) data |= SWITCH_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) data = readw(hw->io + KS8842_SWITCH_CTRL_1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) /* Enable aggressive back off algorithm in half duplex mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) data |= SWITCH_AGGR_BACKOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) /* Enable automatic fast aging when link changed detected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) data |= SWITCH_AGING_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) data |= SWITCH_LINK_AUTO_AGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) if (hw->overrides & FAST_AGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) data |= SWITCH_FAST_AGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) data &= ~SWITCH_FAST_AGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) writew(data, hw->io + KS8842_SWITCH_CTRL_1_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) /* Enable no excessive collision drop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) data |= NO_EXC_COLLISION_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) STP_STATE_DISABLED = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) STP_STATE_LISTENING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) STP_STATE_LEARNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) STP_STATE_FORWARDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) STP_STATE_BLOCKED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) STP_STATE_SIMPLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) * port_set_stp_state - configure port spanning tree state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) * @port: The port index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) * @state: The spanning tree state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) * This routine configures the spanning tree state of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) static void port_set_stp_state(struct ksz_hw *hw, int port, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) port_r16(hw, port, KS8842_PORT_CTRL_2_OFFSET, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) case STP_STATE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) case STP_STATE_LISTENING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) * No need to turn on transmit because of port direct mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) * Turning on receive is required if static MAC table is not setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) data &= ~PORT_TX_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) data |= PORT_RX_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) case STP_STATE_LEARNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) data &= ~PORT_TX_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) data |= PORT_RX_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) data &= ~PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) case STP_STATE_FORWARDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) data &= ~PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) case STP_STATE_BLOCKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) * Need to setup static MAC table with override to keep receiving BPDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) * messages. See sw_init_stp routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) case STP_STATE_SIMPLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) port_w16(hw, port, KS8842_PORT_CTRL_2_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) hw->ksz_switch->port_cfg[port].stp_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) #define STP_ENTRY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) #define BROADCAST_ENTRY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) #define BRIDGE_ADDR_ENTRY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) #define IPV6_ADDR_ENTRY 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) * sw_clr_sta_mac_table - clear static MAC table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) * This routine clears the static MAC table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) static void sw_clr_sta_mac_table(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) struct ksz_mac_table *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) for (i = 0; i < STATIC_MAC_TABLE_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) entry = &hw->ksz_switch->mac_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) sw_w_sta_mac_table(hw, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) entry->mac_addr, entry->ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) entry->override, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) entry->use_fid, entry->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) * sw_init_stp - initialize switch spanning tree support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) * This routine initializes the spanning tree support of the switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) static void sw_init_stp(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) struct ksz_mac_table *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) entry = &hw->ksz_switch->mac_table[STP_ENTRY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) entry->mac_addr[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) entry->mac_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) entry->mac_addr[2] = 0xC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) entry->mac_addr[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) entry->mac_addr[4] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) entry->mac_addr[5] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) entry->ports = HOST_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) entry->override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) entry->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) sw_w_sta_mac_table(hw, STP_ENTRY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) entry->mac_addr, entry->ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) entry->override, entry->valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) entry->use_fid, entry->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) * sw_block_addr - block certain packets from the host port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) * This routine blocks certain packets from reaching to the host port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) static void sw_block_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) struct ksz_mac_table *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) for (i = BROADCAST_ENTRY; i <= IPV6_ADDR_ENTRY; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) entry = &hw->ksz_switch->mac_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) entry->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) sw_w_sta_mac_table(hw, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) entry->mac_addr, entry->ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) entry->override, entry->valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) entry->use_fid, entry->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) #define PHY_LINK_SUPPORT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) (PHY_AUTO_NEG_ASYM_PAUSE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) PHY_AUTO_NEG_SYM_PAUSE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) PHY_AUTO_NEG_100BT4 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) PHY_AUTO_NEG_100BTX_FD | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) PHY_AUTO_NEG_100BTX | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) PHY_AUTO_NEG_10BT_FD | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) PHY_AUTO_NEG_10BT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) static inline void hw_r_phy_ctrl(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) *data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) static inline void hw_w_phy_ctrl(struct ksz_hw *hw, int phy, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) static inline void hw_r_phy_link_stat(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) *data = readw(hw->io + phy + KS884X_PHY_STATUS_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) static inline void hw_r_phy_auto_neg(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) *data = readw(hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) static inline void hw_w_phy_auto_neg(struct ksz_hw *hw, int phy, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) writew(data, hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) static inline void hw_r_phy_rem_cap(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) *data = readw(hw->io + phy + KS884X_PHY_REMOTE_CAP_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) static inline void hw_r_phy_crossover(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) *data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) static inline void hw_w_phy_crossover(struct ksz_hw *hw, int phy, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) static inline void hw_r_phy_polarity(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) *data = readw(hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) static inline void hw_w_phy_polarity(struct ksz_hw *hw, int phy, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) writew(data, hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) static inline void hw_r_phy_link_md(struct ksz_hw *hw, int phy, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) *data = readw(hw->io + phy + KS884X_PHY_LINK_MD_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) static inline void hw_w_phy_link_md(struct ksz_hw *hw, int phy, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) writew(data, hw->io + phy + KS884X_PHY_LINK_MD_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) * hw_r_phy - read data from PHY register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) * @port: Port to read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) * @reg: PHY register to read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) * @val: Buffer to store the read data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) * This routine reads data from the PHY register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) static void hw_r_phy(struct ksz_hw *hw, int port, u16 reg, u16 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) int phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) *val = readw(hw->io + phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) * port_w_phy - write data to PHY register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) * @port: Port to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) * @reg: PHY register to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) * @val: Word data to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) * This routine writes data to the PHY register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) static void hw_w_phy(struct ksz_hw *hw, int port, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) int phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) writew(val, hw->io + phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) * EEPROM access functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) #define AT93C_CODE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) #define AT93C_WR_OFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) #define AT93C_WR_ALL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) #define AT93C_ER_ALL 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) #define AT93C_WR_ON 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) #define AT93C_WRITE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) #define AT93C_READ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) #define AT93C_ERASE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) #define EEPROM_DELAY 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) static inline void drop_gpio(struct ksz_hw *hw, u8 gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) data &= ~gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) static inline void raise_gpio(struct ksz_hw *hw, u8 gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) data |= gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) static inline u8 state_gpio(struct ksz_hw *hw, u8 gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) return (u8)(data & gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) static void eeprom_clk(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) raise_gpio(hw, EEPROM_SERIAL_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) udelay(EEPROM_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) drop_gpio(hw, EEPROM_SERIAL_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) udelay(EEPROM_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) static u16 spi_r(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) u16 temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) for (i = 15; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) raise_gpio(hw, EEPROM_SERIAL_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) udelay(EEPROM_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) temp |= (state_gpio(hw, EEPROM_DATA_IN)) ? 1 << i : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) drop_gpio(hw, EEPROM_SERIAL_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) udelay(EEPROM_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) return temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) static void spi_w(struct ksz_hw *hw, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) for (i = 15; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) (data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) drop_gpio(hw, EEPROM_DATA_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) eeprom_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) static void spi_reg(struct ksz_hw *hw, u8 data, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) /* Initial start bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) raise_gpio(hw, EEPROM_DATA_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) eeprom_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) /* AT93C operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) for (i = 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) (data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) drop_gpio(hw, EEPROM_DATA_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) eeprom_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) /* Address location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) for (i = 5; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) (reg & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) drop_gpio(hw, EEPROM_DATA_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) eeprom_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) #define EEPROM_DATA_RESERVED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) #define EEPROM_DATA_MAC_ADDR_0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) #define EEPROM_DATA_MAC_ADDR_1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) #define EEPROM_DATA_MAC_ADDR_2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) #define EEPROM_DATA_SUBSYS_ID 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) #define EEPROM_DATA_SUBSYS_VEN_ID 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) #define EEPROM_DATA_PM_CAP 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) /* User defined EEPROM data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) #define EEPROM_DATA_OTHER_MAC_ADDR 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) * eeprom_read - read from AT93C46 EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) * @reg: The register offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) * This function reads a word from the AT93C46 EEPROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) * Return the data value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) static u16 eeprom_read(struct ksz_hw *hw, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) spi_reg(hw, AT93C_READ, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) data = spi_r(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) * eeprom_write - write to AT93C46 EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) * @reg: The register offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) * @data: The data value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) * This procedure writes a word to the AT93C46 EEPROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) static void eeprom_write(struct ksz_hw *hw, u8 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) /* Enable write. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) spi_reg(hw, AT93C_CODE, AT93C_WR_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) drop_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) /* Erase the register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) raise_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) spi_reg(hw, AT93C_ERASE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) drop_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) /* Check operation complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) raise_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) timeout = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) mdelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) } while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) drop_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) /* Write the register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) raise_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) spi_reg(hw, AT93C_WRITE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) spi_w(hw, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) drop_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) /* Check operation complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) raise_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) timeout = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) mdelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) } while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) drop_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) /* Disable write. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) raise_gpio(hw, EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) spi_reg(hw, AT93C_CODE, AT93C_WR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) * Link detection routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) static u16 advertised_flow_ctrl(struct ksz_port *port, u16 ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) ctrl &= ~PORT_AUTO_NEG_SYM_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) switch (port->flow_ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) case PHY_FLOW_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) ctrl |= PORT_AUTO_NEG_SYM_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) /* Not supported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) case PHY_TX_ONLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) case PHY_RX_ONLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) return ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) static void set_flow_ctrl(struct ksz_hw *hw, int rx, int tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) u32 rx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) u32 tx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) rx_cfg = hw->rx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) tx_cfg = hw->tx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) if (rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) hw->rx_cfg |= DMA_RX_FLOW_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) hw->rx_cfg &= ~DMA_RX_FLOW_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) if (tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) hw->tx_cfg |= DMA_TX_FLOW_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) if (hw->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) if (rx_cfg != hw->rx_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) if (tx_cfg != hw->tx_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) static void determine_flow_ctrl(struct ksz_hw *hw, struct ksz_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) u16 local, u16 remote)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) int rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) int tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) if (hw->overrides & PAUSE_FLOW_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) rx = tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) if (port->force_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) rx = tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) if (remote & PHY_AUTO_NEG_SYM_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) if (local & PHY_AUTO_NEG_SYM_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) rx = tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) } else if ((remote & PHY_AUTO_NEG_ASYM_PAUSE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) (local & PHY_AUTO_NEG_PAUSE) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) PHY_AUTO_NEG_ASYM_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) } else if (remote & PHY_AUTO_NEG_ASYM_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) if ((local & PHY_AUTO_NEG_PAUSE) == PHY_AUTO_NEG_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) rx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) if (!hw->ksz_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) set_flow_ctrl(hw, rx, tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) static inline void port_cfg_change(struct ksz_hw *hw, struct ksz_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) struct ksz_port_info *info, u16 link_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) if ((hw->features & HALF_DUPLEX_SIGNAL_BUG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) !(hw->overrides & PAUSE_FLOW_CTRL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) u32 cfg = hw->tx_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) /* Disable flow control in the half duplex mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) if (1 == info->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) if (hw->enabled && cfg != hw->tx_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) * port_get_link_speed - get current link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) * @port: The port instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) * This routine reads PHY registers to determine the current link status of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) * switch ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) static void port_get_link_speed(struct ksz_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) struct ksz_port_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) struct ksz_port_info *linked = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) u8 local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) u8 remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) info = &hw->port_info[p];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) port_r16(hw, p, KS884X_PORT_STATUS_OFFSET, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) * Link status is changing all the time even when there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) * cable connection!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) remote = status & (PORT_AUTO_NEG_COMPLETE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) PORT_STATUS_LINK_GOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) local = (u8) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) /* No change to status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) if (local == info->advertised && remote == info->partner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) info->advertised = local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) info->partner = remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) if (status & PORT_STATUS_LINK_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) /* Remember the first linked port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (!linked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) linked = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) info->tx_rate = 10 * TX_RATE_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) if (status & PORT_STATUS_SPEED_100MBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) info->tx_rate = 100 * TX_RATE_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) info->duplex = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) if (status & PORT_STATUS_FULL_DUPLEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) info->duplex = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) if (media_connected != info->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) hw_r_phy(hw, p, KS884X_PHY_AUTO_NEG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) hw_r_phy(hw, p, KS884X_PHY_REMOTE_CAP_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) determine_flow_ctrl(hw, port, data, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (hw->ksz_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) port_cfg_back_pressure(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) (1 == info->duplex));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) change |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) port_cfg_change(hw, port, info, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) info->state = media_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) if (media_disconnected != info->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) change |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) /* Indicate the link just goes down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) hw->port_mib[p].link_down = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) info->state = media_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) hw->port_mib[p].state = (u8) info->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) if (linked && media_disconnected == port->linked->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) port->linked = linked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) #define PHY_RESET_TIMEOUT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) * port_set_link_speed - set port speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) * @port: The port instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) * This routine sets the link speed of the switch ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) static void port_set_link_speed(struct ksz_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) u16 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) port_r8(hw, p, KS884X_PORT_STATUS_OFFSET, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) cfg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) if (status & PORT_STATUS_LINK_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) cfg = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) data |= PORT_AUTO_NEG_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) data = advertised_flow_ctrl(port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) data |= PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_100BTX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) PORT_AUTO_NEG_10BT_FD | PORT_AUTO_NEG_10BT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) /* Check if manual configuration is specified by the user. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) if (port->speed || port->duplex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) if (10 == port->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) data &= ~(PORT_AUTO_NEG_100BTX_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) PORT_AUTO_NEG_100BTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) else if (100 == port->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) data &= ~(PORT_AUTO_NEG_10BT_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) PORT_AUTO_NEG_10BT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) if (1 == port->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) data &= ~(PORT_AUTO_NEG_100BTX_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) PORT_AUTO_NEG_10BT_FD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) else if (2 == port->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) data &= ~(PORT_AUTO_NEG_100BTX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) PORT_AUTO_NEG_10BT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) if (data != cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) data |= PORT_AUTO_NEG_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) port_w16(hw, p, KS884X_PORT_CTRL_4_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) * port_force_link_speed - force port speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) * @port: The port instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) * This routine forces the link speed of the switch ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) static void port_force_link_speed(struct ksz_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) int phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) phy = KS884X_PHY_1_CTRL_OFFSET + p * PHY_CTRL_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) hw_r_phy_ctrl(hw, phy, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) data &= ~PHY_AUTO_NEG_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) if (10 == port->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) data &= ~PHY_SPEED_100MBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) else if (100 == port->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) data |= PHY_SPEED_100MBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) if (1 == port->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) data &= ~PHY_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) else if (2 == port->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) data |= PHY_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) hw_w_phy_ctrl(hw, phy, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) static void port_set_power_saving(struct ksz_port *port, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) port_cfg(hw, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) KS884X_PORT_CTRL_4_OFFSET, PORT_POWER_DOWN, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) * KSZ8841 power management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) * hw_chk_wol_pme_status - check PMEN pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) * This function is used to check PMEN pin is asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) * Return 1 if PMEN pin is asserted; otherwise, 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) static int hw_chk_wol_pme_status(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) struct pci_dev *pdev = hw_priv->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) if (!pdev->pm_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) return (data & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) * hw_clr_wol_pme_status - clear PMEN pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) * This routine is used to clear PME_Status to deassert PMEN pin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) static void hw_clr_wol_pme_status(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) struct pci_dev *pdev = hw_priv->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (!pdev->pm_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) /* Clear PME_Status to deassert PMEN pin. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) data |= PCI_PM_CTRL_PME_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) * hw_cfg_wol_pme - enable or disable Wake-on-LAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) * @set: The flag indicating whether to enable or disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) * This routine is used to enable or disable Wake-on-LAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) static void hw_cfg_wol_pme(struct ksz_hw *hw, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) struct pci_dev *pdev = hw_priv->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) if (!pdev->pm_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) data &= ~PCI_PM_CTRL_STATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) data |= PCI_PM_CTRL_PME_ENABLE | PCI_D3hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) data &= ~PCI_PM_CTRL_PME_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) * hw_cfg_wol - configure Wake-on-LAN features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) * @frame: The pattern frame bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) * @set: The flag indicating whether to enable or disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) * This routine is used to enable or disable certain Wake-on-LAN features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) data = readw(hw->io + KS8841_WOL_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) data |= frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) data &= ~frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) writew(data, hw->io + KS8841_WOL_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) * hw_set_wol_frame - program Wake-on-LAN pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) * @i: The frame index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) * @mask_size: The size of the mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) * @mask: Mask to ignore certain bytes in the pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) * @frame_size: The size of the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) * @pattern: The frame data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) * This routine is used to program Wake-on-LAN pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) const u8 *mask, uint frame_size, const u8 *pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) int bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) int from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) int to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) u8 data[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) u8 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) if (frame_size > mask_size * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) frame_size = mask_size * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) if (frame_size > 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) frame_size = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) i *= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) writel(0, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) writel(0, hw->io + KS8841_WOL_FRAME_BYTE2_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) bits = len = from = to = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) if (bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) if ((val & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) data[to++] = pattern[from];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) val >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) ++from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) --bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) val = mask[len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) writeb(val, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) ++len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) from += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) } while (from < (int) frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) bits = mask[len - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) val <<= (from % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) bits &= ~val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) writeb(bits, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i + len -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) crc = ether_crc(to, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) writel(crc, hw->io + KS8841_WOL_FRAME_CRC_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) * hw_add_wol_arp - add ARP pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) * @ip_addr: The IPv4 address assigned to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) * This routine is used to add ARP pattern for waking up the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) static const u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) u8 pattern[42] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 0x08, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 0x00, 0x00, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) memcpy(&pattern[38], ip_addr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) hw_set_wol_frame(hw, 3, 6, mask, 42, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) * hw_add_wol_bcast - add broadcast pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) * This routine is used to add broadcast pattern for waking up the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) static void hw_add_wol_bcast(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) static const u8 mask[] = { 0x3F };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) hw_set_wol_frame(hw, 2, 1, mask, ETH_ALEN, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) * hw_add_wol_mcast - add multicast pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) * This routine is used to add multicast pattern for waking up the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) * It is assumed the multicast packet is the ICMPv6 neighbor solicitation used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) * by IPv6 ping command. Note that multicast packets are filtred through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) * multicast hash table, so not all multicast packets can wake up the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) static void hw_add_wol_mcast(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) static const u8 mask[] = { 0x3F };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) memcpy(&pattern[3], &hw->override_addr[3], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) hw_set_wol_frame(hw, 1, 1, mask, 6, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) * hw_add_wol_ucast - add unicast pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) * This routine is used to add unicast pattern to wakeup the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) * It is assumed the unicast packet is directed to the device, as the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) * can only receive them in normal case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) static void hw_add_wol_ucast(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) static const u8 mask[] = { 0x3F };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) hw_set_wol_frame(hw, 0, 1, mask, ETH_ALEN, hw->override_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) * hw_enable_wol - enable Wake-on-LAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * @wol_enable: The Wake-on-LAN settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * @net_addr: The IPv4 address assigned to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) * This routine is used to enable Wake-on-LAN depending on driver settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) hw_add_wol_ucast(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) hw_cfg_wol(hw, KS8841_WOL_FRAME1_ENABLE, (wol_enable & WAKE_MCAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) hw_add_wol_mcast(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) hw_cfg_wol(hw, KS8841_WOL_FRAME2_ENABLE, (wol_enable & WAKE_BCAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) hw_cfg_wol(hw, KS8841_WOL_FRAME3_ENABLE, (wol_enable & WAKE_ARP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) hw_add_wol_arp(hw, net_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) * hw_init - check driver is correct for the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) * This function checks the hardware is correct for this driver and sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) * hardware up for proper initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) * Return number of ports or 0 if not right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) static int hw_init(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) u16 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) /* Set bus speed to 125MHz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) writew(BUS_SPEED_125_MHZ, hw->io + KS884X_BUS_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) /* Check KSZ884x chip ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) data = readw(hw->io + KS884X_CHIP_ID_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) revision = (data & KS884X_REVISION_MASK) >> KS884X_REVISION_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) data &= KS884X_CHIP_ID_MASK_41;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) if (REG_CHIP_ID_41 == data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) else if (REG_CHIP_ID_42 == data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) rc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) /* Setup hardware features or bug workarounds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) if (revision <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) hw->features |= SMALL_PACKET_TX_BUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) if (1 == rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) hw->features |= HALF_DUPLEX_SIGNAL_BUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) * hw_reset - reset the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) * This routine resets the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) static void hw_reset(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) writew(GLOBAL_SOFTWARE_RESET, hw->io + KS884X_GLOBAL_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) /* Wait for device to reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) /* Write 0 to clear device reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) writew(0, hw->io + KS884X_GLOBAL_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) * hw_setup - setup the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) * This routine setup the hardware for proper operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) static void hw_setup(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) #if SET_DEFAULT_LED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) /* Change default LED mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) data = readw(hw->io + KS8842_SWITCH_CTRL_5_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) data &= ~LED_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) data |= SET_DEFAULT_LED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) writew(data, hw->io + KS8842_SWITCH_CTRL_5_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) /* Setup transmit control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) hw->tx_cfg = (DMA_TX_PAD_ENABLE | DMA_TX_CRC_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) (DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_TX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) /* Setup receive control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) hw->rx_cfg = (DMA_RX_BROADCAST | DMA_RX_UNICAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) (DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) hw->rx_cfg |= KS884X_DMA_RX_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) /* Hardware cannot handle UDP packet in IP fragments. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) hw->rx_cfg |= (DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) if (hw->all_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) hw->rx_cfg |= DMA_RX_ALL_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) if (hw->promiscuous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) hw->rx_cfg |= DMA_RX_PROMISCUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) * hw_setup_intr - setup interrupt mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) * This routine setup the interrupt mask for proper operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) static void hw_setup_intr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) hw->intr_mask = KS884X_INT_MASK | KS884X_INT_RX_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) static void ksz_check_desc_num(struct ksz_desc_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) #define MIN_DESC_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) int alloc = info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) while (!(alloc & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) alloc >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) if (alloc != 1 || shift < MIN_DESC_SHIFT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) pr_alert("Hardware descriptor numbers not right!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) while (alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) alloc >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) if (shift < MIN_DESC_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) shift = MIN_DESC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) alloc = 1 << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) info->alloc = alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) info->mask = info->alloc - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) static void hw_init_desc(struct ksz_desc_info *desc_info, int transmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) u32 phys = desc_info->ring_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) struct ksz_hw_desc *desc = desc_info->ring_virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) struct ksz_desc *cur = desc_info->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) struct ksz_desc *previous = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) for (i = 0; i < desc_info->alloc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) cur->phw = desc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) phys += desc_info->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) previous = cur++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) previous->phw->next = cpu_to_le32(phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) previous->phw->next = cpu_to_le32(desc_info->ring_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) previous->sw.buf.rx.end_of_ring = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) previous->phw->buf.data = cpu_to_le32(previous->sw.buf.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) desc_info->avail = desc_info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) desc_info->last = desc_info->next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) desc_info->cur = desc_info->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) * hw_set_desc_base - set descriptor base addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) * @tx_addr: The transmit descriptor base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) * @rx_addr: The receive descriptor base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) * This routine programs the descriptor base addresses after reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) static void hw_set_desc_base(struct ksz_hw *hw, u32 tx_addr, u32 rx_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) /* Set base address of Tx/Rx descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) writel(tx_addr, hw->io + KS_DMA_TX_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) writel(rx_addr, hw->io + KS_DMA_RX_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) static void hw_reset_pkts(struct ksz_desc_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) info->cur = info->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) info->avail = info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) info->last = info->next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) static inline void hw_resume_rx(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) writel(DMA_START, hw->io + KS_DMA_RX_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) * hw_start_rx - start receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) * This routine starts the receive function of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) static void hw_start_rx(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) /* Notify when the receive stops. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) hw->intr_mask |= KS884X_INT_RX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) writel(DMA_START, hw->io + KS_DMA_RX_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) hw_ack_intr(hw, KS884X_INT_RX_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) hw->rx_stop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) /* Variable overflows. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) if (0 == hw->rx_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) hw->rx_stop = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) * hw_stop_rx - stop receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) * This routine stops the receive function of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) static void hw_stop_rx(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) hw->rx_stop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) hw_turn_off_intr(hw, KS884X_INT_RX_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) writel((hw->rx_cfg & ~DMA_RX_ENABLE), hw->io + KS_DMA_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) * hw_start_tx - start transmitting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) * This routine starts the transmit function of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) static void hw_start_tx(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) * hw_stop_tx - stop transmitting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) * This routine stops the transmit function of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) static void hw_stop_tx(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) writel((hw->tx_cfg & ~DMA_TX_ENABLE), hw->io + KS_DMA_TX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) * hw_disable - disable hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) * This routine disables the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) static void hw_disable(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) hw_stop_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) hw_stop_tx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) hw->enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) * hw_enable - enable hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) * This routine enables the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) static void hw_enable(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) hw_start_tx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) hw_start_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) hw->enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) * hw_alloc_pkt - allocate enough descriptors for transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) * @length: The length of the packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) * @physical: Number of descriptors required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) * This function allocates descriptors for transmission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) * Return 0 if not successful; 1 for buffer copy; or number of descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) static int hw_alloc_pkt(struct ksz_hw *hw, int length, int physical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) /* Always leave one descriptor free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) if (hw->tx_desc_info.avail <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) /* Allocate a descriptor for transmission and mark it current. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) get_tx_pkt(&hw->tx_desc_info, &hw->tx_desc_info.cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) hw->tx_desc_info.cur->sw.buf.tx.first_seg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) /* Keep track of number of transmit descriptors used so far. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) ++hw->tx_int_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) hw->tx_size += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) /* Cannot hold on too much data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) if (hw->tx_size >= MAX_TX_HELD_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) hw->tx_int_cnt = hw->tx_int_mask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) if (physical > hw->tx_desc_info.avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) return hw->tx_desc_info.avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) * hw_send_pkt - mark packet for transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) * This routine marks the packet for transmission in PCI version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) static void hw_send_pkt(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) struct ksz_desc *cur = hw->tx_desc_info.cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) cur->sw.buf.tx.last_seg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) /* Interrupt only after specified number of descriptors used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) if (hw->tx_int_cnt > hw->tx_int_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) cur->sw.buf.tx.intr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) hw->tx_int_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) hw->tx_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) /* KSZ8842 supports port directed transmission. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) cur->sw.buf.tx.dest_port = hw->dst_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) release_desc(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) writel(0, hw->io + KS_DMA_TX_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) static int empty_addr(u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) u32 *addr1 = (u32 *) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) u16 *addr2 = (u16 *) &addr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) return 0 == *addr1 && 0 == *addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) * hw_set_addr - set MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) * This routine programs the MAC address of the hardware when the address is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) * overridden.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) static void hw_set_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) writeb(hw->override_addr[MAC_ADDR_ORDER(i)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) hw->io + KS884X_ADDR_0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) sw_set_addr(hw, hw->override_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) * hw_read_addr - read MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) * This routine retrieves the MAC address of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) static void hw_read_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) KS884X_ADDR_0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) if (!hw->mac_override) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) memcpy(hw->override_addr, hw->perm_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) if (empty_addr(hw->override_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) hw->override_addr[5] += hw->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) hw_set_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) static void hw_ena_add_addr(struct ksz_hw *hw, int index, u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) u32 mac_addr_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) u32 mac_addr_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) mac_addr_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) mac_addr_hi <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) mac_addr_hi |= mac_addr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) mac_addr_hi |= ADD_ADDR_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) mac_addr_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) for (i = 2; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) mac_addr_lo <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) mac_addr_lo |= mac_addr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) index *= ADD_ADDR_INCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) writel(mac_addr_lo, hw->io + index + KS_ADD_ADDR_0_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) writel(mac_addr_hi, hw->io + index + KS_ADD_ADDR_0_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) static void hw_set_add_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) for (i = 0; i < ADDITIONAL_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) if (empty_addr(hw->address[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) writel(0, hw->io + ADD_ADDR_INCR * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) KS_ADD_ADDR_0_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) hw_ena_add_addr(hw, i, hw->address[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) int j = ADDITIONAL_ENTRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) if (ether_addr_equal(hw->override_addr, mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) for (i = 0; i < hw->addr_list_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) if (ether_addr_equal(hw->address[i], mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) j = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) if (j < ADDITIONAL_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) memcpy(hw->address[j], mac_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) hw_ena_add_addr(hw, j, hw->address[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) for (i = 0; i < hw->addr_list_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) if (ether_addr_equal(hw->address[i], mac_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) eth_zero_addr(hw->address[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) writel(0, hw->io + ADD_ADDR_INCR * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) KS_ADD_ADDR_0_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) * hw_clr_multicast - clear multicast addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) * This routine removes all multicast addresses set in the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) static void hw_clr_multicast(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) for (i = 0; i < HW_MULTICAST_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) hw->multi_bits[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) writeb(0, hw->io + KS884X_MULTICAST_0_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) * hw_set_grp_addr - set multicast addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) * This routine programs multicast addresses for the hardware to accept those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) * addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) static void hw_set_grp_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) int position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) memset(hw->multi_bits, 0, sizeof(u8) * HW_MULTICAST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) for (i = 0; i < hw->multi_list_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) position = (ether_crc(6, hw->multi_list[i]) >> 26) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) index = position >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) value = 1 << (position & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) hw->multi_bits[index] |= (u8) value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) for (i = 0; i < HW_MULTICAST_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) writeb(hw->multi_bits[i], hw->io + KS884X_MULTICAST_0_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) * hw_set_multicast - enable or disable all multicast receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) * @multicast: To turn on or off the all multicast feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) * This routine enables/disables the hardware to accept all multicast packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) static void hw_set_multicast(struct ksz_hw *hw, u8 multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) /* Stop receiving for reconfiguration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) hw_stop_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) if (multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) hw->rx_cfg |= DMA_RX_ALL_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) hw->rx_cfg &= ~DMA_RX_ALL_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) if (hw->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) hw_start_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) * hw_set_promiscuous - enable or disable promiscuous receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) * @prom: To turn on or off the promiscuous feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) * This routine enables/disables the hardware to accept all packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) static void hw_set_promiscuous(struct ksz_hw *hw, u8 prom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) /* Stop receiving for reconfiguration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) hw_stop_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) if (prom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) hw->rx_cfg |= DMA_RX_PROMISCUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) hw->rx_cfg &= ~DMA_RX_PROMISCUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) if (hw->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) hw_start_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) * sw_enable - enable the switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) * @enable: The flag to enable or disable the switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) * This routine is used to enable/disable the switch in KSZ8842.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) static void sw_enable(struct ksz_hw *hw, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) for (port = 0; port < SWITCH_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) /* Set port-base vlan membership with host port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) sw_cfg_port_base_vlan(hw, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) HOST_MASK | (1 << port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) port_set_stp_state(hw, port, STP_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) sw_cfg_port_base_vlan(hw, port, PORT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) port_set_stp_state(hw, port, STP_STATE_FORWARDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) if (hw->dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_FORWARDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) enable = KS8842_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) writew(enable, hw->io + KS884X_CHIP_ID_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) * sw_setup - setup the switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) * @hw: The hardware instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) * This routine setup the hardware switch engine for default operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) static void sw_setup(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) sw_set_global_ctrl(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) /* Enable switch broadcast storm protection at 10% percent rate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) sw_init_broad_storm(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) hw_cfg_broad_storm(hw, BROADCAST_STORM_PROTECTION_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) for (port = 0; port < SWITCH_PORT_NUM; port++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) sw_ena_broad_storm(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) sw_init_prio(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) sw_init_mirror(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) sw_init_prio_rate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) sw_init_vlan(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) if (hw->features & STP_SUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) sw_init_stp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) if (!sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) SWITCH_TX_FLOW_CTRL | SWITCH_RX_FLOW_CTRL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) hw->overrides |= PAUSE_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) sw_enable(hw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) * ksz_start_timer - start kernel timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) * @info: Kernel timer information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) * @time: The time tick.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) * This routine starts the kernel timer after the specified time tick.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) static void ksz_start_timer(struct ksz_timer_info *info, int time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) info->cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) info->timer.expires = jiffies + time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) add_timer(&info->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) /* infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) info->max = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) * ksz_stop_timer - stop kernel timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) * @info: Kernel timer information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) * This routine stops the kernel timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) static void ksz_stop_timer(struct ksz_timer_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) if (info->max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) info->max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) del_timer_sync(&info->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) static void ksz_init_timer(struct ksz_timer_info *info, int period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) void (*function)(struct timer_list *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) info->max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) info->period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) timer_setup(&info->timer, function, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) static void ksz_update_timer(struct ksz_timer_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) ++info->cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) if (info->max > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) if (info->cnt < info->max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) info->timer.expires = jiffies + info->period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) add_timer(&info->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) info->max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) } else if (info->max < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) info->timer.expires = jiffies + info->period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) add_timer(&info->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) * ksz_alloc_soft_desc - allocate software descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) * @desc_info: Descriptor information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) * @transmit: Indication that descriptors are for transmit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) * This local function allocates software descriptors for manipulation in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) * memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) * Return 0 if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) desc_info->ring = kcalloc(desc_info->alloc, sizeof(struct ksz_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) if (!desc_info->ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) hw_init_desc(desc_info, transmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) * ksz_alloc_desc - allocate hardware descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) * This local function allocates hardware descriptors for receiving and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) * transmitting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) * Return 0 if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) static int ksz_alloc_desc(struct dev_info *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) struct ksz_hw *hw = &adapter->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) /* Allocate memory for RX & TX descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) adapter->desc_pool.alloc_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) hw->rx_desc_info.size * hw->rx_desc_info.alloc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) hw->tx_desc_info.size * hw->tx_desc_info.alloc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) DESC_ALIGNMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) adapter->desc_pool.alloc_virt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) dma_alloc_coherent(&adapter->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) adapter->desc_pool.alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) &adapter->desc_pool.dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) if (adapter->desc_pool.alloc_virt == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) adapter->desc_pool.alloc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) /* Align to the next cache line boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) offset = (((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) (DESC_ALIGNMENT -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) ((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT)) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) adapter->desc_pool.virt = adapter->desc_pool.alloc_virt + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) adapter->desc_pool.phys = adapter->desc_pool.dma_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) /* Allocate receive/transmit descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) hw->rx_desc_info.ring_virt = (struct ksz_hw_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) adapter->desc_pool.virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) hw->rx_desc_info.ring_phys = adapter->desc_pool.phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) offset = hw->rx_desc_info.alloc * hw->rx_desc_info.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) hw->tx_desc_info.ring_virt = (struct ksz_hw_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) (adapter->desc_pool.virt + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) hw->tx_desc_info.ring_phys = adapter->desc_pool.phys + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) if (ksz_alloc_soft_desc(&hw->rx_desc_info, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) if (ksz_alloc_soft_desc(&hw->tx_desc_info, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) * free_dma_buf - release DMA buffer resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) * @dma_buf: pointer to buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) * @direction: to or from device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) * This routine is just a helper function to release the DMA buffer resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) static void free_dma_buf(struct dev_info *adapter, struct ksz_dma_buf *dma_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) dma_unmap_single(&adapter->pdev->dev, dma_buf->dma, dma_buf->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) dev_kfree_skb(dma_buf->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) dma_buf->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) dma_buf->dma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) * ksz_init_rx_buffers - initialize receive descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) * This routine initializes DMA buffers for receiving.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) static void ksz_init_rx_buffers(struct dev_info *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) struct ksz_dma_buf *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) struct ksz_hw *hw = &adapter->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) struct ksz_desc_info *info = &hw->rx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) for (i = 0; i < hw->rx_desc_info.alloc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) get_rx_pkt(info, &desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) if (dma_buf->skb && dma_buf->len != adapter->mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) free_dma_buf(adapter, dma_buf, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) dma_buf->len = adapter->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) if (!dma_buf->skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) if (dma_buf->skb && !dma_buf->dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) dma_buf->dma = dma_map_single(&adapter->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) skb_tail_pointer(dma_buf->skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) dma_buf->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) /* Set descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) set_rx_buf(desc, dma_buf->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) set_rx_len(desc, dma_buf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) release_desc(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) * ksz_alloc_mem - allocate memory for hardware descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) * This function allocates memory for use by hardware descriptors for receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) * and transmitting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) * Return 0 if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) static int ksz_alloc_mem(struct dev_info *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) struct ksz_hw *hw = &adapter->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) /* Determine the number of receive and transmit descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) hw->rx_desc_info.alloc = NUM_OF_RX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) hw->tx_desc_info.alloc = NUM_OF_TX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) /* Determine how many descriptors to skip transmit interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) hw->tx_int_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) hw->tx_int_mask = NUM_OF_TX_DESC / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) if (hw->tx_int_mask > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) hw->tx_int_mask = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) while (hw->tx_int_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) hw->tx_int_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) hw->tx_int_mask >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) if (hw->tx_int_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) hw->tx_int_mask = (1 << (hw->tx_int_cnt - 1)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) hw->tx_int_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) /* Determine the descriptor size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) hw->rx_desc_info.size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) (((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) DESC_ALIGNMENT) * DESC_ALIGNMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) hw->tx_desc_info.size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) (((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) DESC_ALIGNMENT) * DESC_ALIGNMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) if (hw->rx_desc_info.size != sizeof(struct ksz_hw_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) pr_alert("Hardware descriptor size not right!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) ksz_check_desc_num(&hw->rx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) ksz_check_desc_num(&hw->tx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) /* Allocate descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) if (ksz_alloc_desc(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) * ksz_free_desc - free software and hardware descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) * This local routine frees the software and hardware descriptors allocated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) * ksz_alloc_desc().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) static void ksz_free_desc(struct dev_info *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) struct ksz_hw *hw = &adapter->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) /* Reset descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) hw->rx_desc_info.ring_virt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) hw->tx_desc_info.ring_virt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) hw->rx_desc_info.ring_phys = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) hw->tx_desc_info.ring_phys = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) /* Free memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) if (adapter->desc_pool.alloc_virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) dma_free_coherent(&adapter->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) adapter->desc_pool.alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) adapter->desc_pool.alloc_virt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) adapter->desc_pool.dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) /* Reset resource pool. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) adapter->desc_pool.alloc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) adapter->desc_pool.alloc_virt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) kfree(hw->rx_desc_info.ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) hw->rx_desc_info.ring = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) kfree(hw->tx_desc_info.ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) hw->tx_desc_info.ring = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) * ksz_free_buffers - free buffers used in the descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) * @desc_info: Descriptor information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) * @direction: to or from device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) * This local routine frees buffers used in the DMA buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) static void ksz_free_buffers(struct dev_info *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) struct ksz_desc_info *desc_info, int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) struct ksz_dma_buf *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) struct ksz_desc *desc = desc_info->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) for (i = 0; i < desc_info->alloc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) if (dma_buf->skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) free_dma_buf(adapter, dma_buf, direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) desc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) * ksz_free_mem - free all resources used by descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) * @adapter: Adapter information structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) * This local routine frees all the resources allocated by ksz_alloc_mem().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) static void ksz_free_mem(struct dev_info *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) /* Free transmit buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) ksz_free_buffers(adapter, &adapter->hw.tx_desc_info, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) /* Free receive buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) ksz_free_buffers(adapter, &adapter->hw.rx_desc_info, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) /* Free descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) ksz_free_desc(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) static void get_mib_counters(struct ksz_hw *hw, int first, int cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) u64 *counter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) int mib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) struct ksz_port_mib *port_mib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) memset(counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) for (i = 0, port = first; i < cnt; i++, port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) port_mib = &hw->port_mib[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) for (mib = port_mib->mib_start; mib < hw->mib_cnt; mib++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) counter[mib] += port_mib->counter[mib];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) * send_packet - send packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) * @skb: Socket buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) * This routine is used to send a packet out to the network.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) static void send_packet(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) struct ksz_desc *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) struct ksz_desc_info *info = &hw->tx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) struct ksz_dma_buf *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) int last_frag = skb_shinfo(skb)->nr_frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) * KSZ8842 with multiple device interfaces needs to be told which port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) * to send.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) if (hw->dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) hw->dst_ports = 1 << priv->port.first_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) /* Hardware will pad the length to 60. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) /* Remember the very first descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) first = info->cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) desc = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (last_frag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) int frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) skb_frag_t *this_frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) dma_buf->len = skb_headlen(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) dma_buf->dma = dma_map_single(&hw_priv->pdev->dev, skb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) dma_buf->len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) set_tx_buf(desc, dma_buf->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) set_tx_len(desc, dma_buf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) frag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) this_frag = &skb_shinfo(skb)->frags[frag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) /* Get a new descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) get_tx_pkt(info, &desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) /* Keep track of descriptors used so far. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) ++hw->tx_int_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) dma_buf->len = skb_frag_size(this_frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) dma_buf->dma = dma_map_single(&hw_priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) skb_frag_address(this_frag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) dma_buf->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) set_tx_buf(desc, dma_buf->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) set_tx_len(desc, dma_buf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) frag++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) if (frag == last_frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) /* Do not release the last descriptor here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) release_desc(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) /* current points to the last descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) info->cur = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) /* Release the first descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) release_desc(first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) dma_buf->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) dma_buf->dma = dma_map_single(&hw_priv->pdev->dev, skb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) dma_buf->len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) set_tx_buf(desc, dma_buf->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) set_tx_len(desc, dma_buf->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) if (skb->ip_summed == CHECKSUM_PARTIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) (desc)->sw.buf.tx.csum_gen_tcp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) (desc)->sw.buf.tx.csum_gen_udp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) * The last descriptor holds the packet so that it can be returned to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) * network subsystem after all descriptors are transmitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) dma_buf->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) hw_send_pkt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) /* Update transmit statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) dev->stats.tx_bytes += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) * transmit_cleanup - clean up transmit descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) * @hw_priv: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) * @normal: break if owned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) * This routine is called to clean up the transmitted buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) static void transmit_cleanup(struct dev_info *hw_priv, int normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) int last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) union desc_stat status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) struct ksz_desc_info *info = &hw->tx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) struct ksz_dma_buf *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) spin_lock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) last = info->last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) while (info->avail < info->alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) /* Get next descriptor which is not hardware owned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) desc = &info->ring[last];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) status.data = le32_to_cpu(desc->phw->ctrl.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) if (status.tx.hw_owned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) if (normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) reset_desc(desc, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) dma_unmap_single(&hw_priv->pdev->dev, dma_buf->dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) dma_buf->len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) /* This descriptor contains the last buffer in the packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) if (dma_buf->skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) dev = dma_buf->skb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) /* Release the packet back to network subsystem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) dev_kfree_skb_irq(dma_buf->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) dma_buf->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) /* Free the transmitted descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) last++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) last &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) info->avail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) info->last = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) spin_unlock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) /* Notify the network subsystem that the packet has been sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) * transmit_done - transmit done processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) * @hw_priv: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) * This routine is called when the transmit interrupt is triggered, indicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) * either a packet is sent successfully or there are transmit errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) static void tx_done(struct dev_info *hw_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) transmit_cleanup(hw_priv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) for (port = 0; port < hw->dev_count; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) struct net_device *dev = hw->port_info[port].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) if (netif_running(dev) && netif_queue_stopped(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) skb->dev = old->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) skb->protocol = old->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) skb->ip_summed = old->ip_summed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) skb->csum = old->csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) skb_set_network_header(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) dev_consume_skb_any(old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) * netdev_tx - send out packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) * @skb: Socket buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) * This function is used by the upper network layer to send out a packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) * Return 0 if successful; otherwise an error code indicating failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) int left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) int num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) if (hw->features & SMALL_PACKET_TX_BUG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) struct sk_buff *org_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) if (skb->len <= 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) if (skb_end_pointer(skb) - skb->data >= 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) memset(&skb->data[skb->len], 0, 50 - skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) skb->len = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) skb = netdev_alloc_skb(dev, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) memcpy(skb->data, org_skb->data, org_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) memset(&skb->data[org_skb->len], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 50 - org_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) skb->len = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) copy_old_skb(org_skb, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) spin_lock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) num = skb_shinfo(skb)->nr_frags + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) left = hw_alloc_pkt(hw, skb->len, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) if (left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) if (left < num ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) (CHECKSUM_PARTIAL == skb->ip_summed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) skb->protocol == htons(ETH_P_IPV6))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) struct sk_buff *org_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) skb = netdev_alloc_skb(dev, org_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) rc = NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) skb_copy_and_csum_dev(org_skb, skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) org_skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) skb->len = org_skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) copy_old_skb(org_skb, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) send_packet(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) if (left <= num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) /* Stop the transmit queue until packet is allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) rc = NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) spin_unlock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) * netdev_tx_timeout - transmit timeout processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) * @txqueue: index of hanging queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) * This routine is called when the transmit timer expires. That indicates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) * hardware is not running correctly because transmit interrupts are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) * triggered to free up resources so that the transmit routine can continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) * sending out packets. The hardware is reset to correct the problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) static void netdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) static unsigned long last_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) * Only reset the hardware if time between calls is long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) * enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) if (time_before_eq(jiffies, last_reset + dev->watchdog_timeo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) hw_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) last_reset = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) if (hw_priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) hw_dis_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) hw_disable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) transmit_cleanup(hw_priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) hw_reset_pkts(&hw->rx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) hw_reset_pkts(&hw->tx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) ksz_init_rx_buffers(hw_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) hw_reset(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) hw_set_desc_base(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) hw->tx_desc_info.ring_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) hw->rx_desc_info.ring_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) hw_set_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) if (hw->all_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) hw_set_multicast(hw, hw->all_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) else if (hw->multi_list_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) hw_set_grp_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) hw_set_add_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) for (port = 0; port < SWITCH_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) struct net_device *port_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) port_set_stp_state(hw, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) STP_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) port_dev = hw->port_info[port].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) if (netif_running(port_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) port_set_stp_state(hw, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) STP_STATE_SIMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) hw_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) hw_ena_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) static inline void csum_verified(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) unsigned short protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) struct iphdr *iph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) protocol = skb->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) iph = (struct iphdr *) skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) if (protocol == htons(ETH_P_8021Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) protocol = iph->tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) skb_set_network_header(skb, VLAN_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) iph = (struct iphdr *) skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) if (protocol == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) if (iph->protocol == IPPROTO_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) skb->ip_summed = CHECKSUM_UNNECESSARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) struct ksz_desc *desc, union desc_stat status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) int packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) struct ksz_dma_buf *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) /* Received length includes 4-byte CRC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) packet_len = status.rx.frame_len - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) dma_buf = DMA_BUFFER(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) dma_sync_single_for_cpu(&hw_priv->pdev->dev, dma_buf->dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) packet_len + 4, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) /* skb->data != skb->head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) skb = netdev_alloc_skb(dev, packet_len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) * Align socket buffer in 4-byte boundary for better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) * performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) skb_reserve(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) skb_put_data(skb, dma_buf->skb->data, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) if (hw->rx_cfg & (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) csum_verified(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) /* Update receive statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) dev->stats.rx_bytes += packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) /* Notify upper layer for received packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) static int dev_rcv_packets(struct dev_info *hw_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) int next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) union desc_stat status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) struct net_device *dev = hw->port_info[0].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) struct ksz_desc_info *info = &hw->rx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) int left = info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) int received = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) next = info->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) while (left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) /* Get next descriptor which is not hardware owned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) desc = &info->ring[next];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) status.data = le32_to_cpu(desc->phw->ctrl.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) if (status.rx.hw_owned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) /* Status valid only when last descriptor bit is set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) if (status.rx.last_desc && status.rx.first_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) if (rx_proc(dev, hw, desc, status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) goto release_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) received++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) release_packet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) release_desc(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) next &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) info->next = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) return received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) static int port_rcv_packets(struct dev_info *hw_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) int next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) union desc_stat status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) struct net_device *dev = hw->port_info[0].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) struct ksz_desc_info *info = &hw->rx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) int left = info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) int received = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) next = info->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) while (left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) /* Get next descriptor which is not hardware owned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) desc = &info->ring[next];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) status.data = le32_to_cpu(desc->phw->ctrl.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) if (status.rx.hw_owned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) /* Get received port number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) int p = HW_TO_DEV_PORT(status.rx.src_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) dev = hw->port_info[p].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) goto release_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) /* Status valid only when last descriptor bit is set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) if (status.rx.last_desc && status.rx.first_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) if (rx_proc(dev, hw, desc, status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) goto release_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) received++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) release_packet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) release_desc(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) next &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) info->next = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) return received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) static int dev_rcv_special(struct dev_info *hw_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) int next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) union desc_stat status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) struct net_device *dev = hw->port_info[0].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) struct ksz_desc_info *info = &hw->rx_desc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) int left = info->alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) struct ksz_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) int received = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) next = info->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) while (left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) /* Get next descriptor which is not hardware owned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) desc = &info->ring[next];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) status.data = le32_to_cpu(desc->phw->ctrl.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) if (status.rx.hw_owned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) /* Get received port number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) int p = HW_TO_DEV_PORT(status.rx.src_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) dev = hw->port_info[p].pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) goto release_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) /* Status valid only when last descriptor bit is set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) if (status.rx.last_desc && status.rx.first_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) * Receive without error. With receive errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) * disabled, packets with receive errors will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) * dropped, so no need to check the error bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) if (!status.rx.error || (status.data &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) KS_DESC_RX_ERROR_COND) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) KS_DESC_RX_ERROR_TOO_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) if (rx_proc(dev, hw, desc, status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) goto release_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) received++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) /* Update receive error statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) priv->port.counter[OID_COUNTER_RCV_ERROR]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) release_packet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) release_desc(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) next &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) info->next = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) return received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) static void rx_proc_task(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) struct dev_info *hw_priv = from_tasklet(hw_priv, t, rx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) if (!hw->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) if (unlikely(!hw_priv->dev_rcv(hw_priv))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) /* In case receive process is suspended because of overrun. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) hw_resume_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) /* tasklets are interruptible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) spin_lock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) hw_turn_on_intr(hw, KS884X_INT_RX_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) spin_unlock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) hw_ack_intr(hw, KS884X_INT_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) tasklet_schedule(&hw_priv->rx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) static void tx_proc_task(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) struct dev_info *hw_priv = from_tasklet(hw_priv, t, tx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) hw_ack_intr(hw, KS884X_INT_TX_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) tx_done(hw_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) /* tasklets are interruptible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) spin_lock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) hw_turn_on_intr(hw, KS884X_INT_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) spin_unlock_irq(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) static inline void handle_rx_stop(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) /* Receive just has been stopped. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) if (0 == hw->rx_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) hw->intr_mask &= ~KS884X_INT_RX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) else if (hw->rx_stop > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) if (hw->enabled && (hw->rx_cfg & DMA_RX_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) hw_start_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) hw->intr_mask &= ~KS884X_INT_RX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) hw->rx_stop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) /* Receive just has been started. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) hw->rx_stop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) * netdev_intr - interrupt handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) * @irq: Interrupt number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) * @dev_id: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) * This function is called by upper network layer to signal interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) * Return IRQ_HANDLED if interrupt is handled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) static irqreturn_t netdev_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) uint int_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) struct net_device *dev = (struct net_device *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) spin_lock(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) hw_read_intr(hw, &int_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) /* Not our interrupt! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) if (!int_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) spin_unlock(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) hw_ack_intr(hw, int_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) int_enable &= hw->intr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) if (unlikely(int_enable & KS884X_INT_TX_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) hw_dis_intr_bit(hw, KS884X_INT_TX_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) tasklet_schedule(&hw_priv->tx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) if (likely(int_enable & KS884X_INT_RX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) hw_dis_intr_bit(hw, KS884X_INT_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) tasklet_schedule(&hw_priv->rx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) if (unlikely(int_enable & KS884X_INT_RX_OVERRUN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) hw_resume_rx(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) if (unlikely(int_enable & KS884X_INT_PHY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) hw->features |= LINK_INT_WORKING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) port_get_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) if (unlikely(int_enable & KS884X_INT_RX_STOPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) handle_rx_stop(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) if (unlikely(int_enable & KS884X_INT_TX_STOPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) hw->intr_mask &= ~KS884X_INT_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) pr_info("Tx stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) data = readl(hw->io + KS_DMA_TX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) if (!(data & DMA_TX_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) pr_info("Tx disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) hw_ena_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) spin_unlock(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) * Linux network device functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) static unsigned long next_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) static void netdev_netpoll(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) hw_dis_intr(&hw_priv->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) netdev_intr(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) static void bridge_change(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) u8 member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) /* No ports in forwarding state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) if (!sw->member) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) sw_block_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) for (port = 0; port < SWITCH_PORT_NUM; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) if (STP_STATE_FORWARDING == sw->port_cfg[port].stp_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) member = HOST_MASK | sw->member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) member = HOST_MASK | (1 << port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) if (member != sw->port_cfg[port].member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) sw_cfg_port_base_vlan(hw, port, member);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) * netdev_close - close network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) * This function process the close operation of network device. This is caused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) * by the user command "ifconfig ethX down."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) * Return 0 if successful; otherwise an error code indicating failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) static int netdev_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) int pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) ksz_stop_timer(&priv->monitor_timer_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) /* Need to shut the port manually in multiple device interfaces mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) port_set_stp_state(hw, port->first_port, STP_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) /* Port is closed. Need to change bridge setting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) if (hw->features & STP_SUPPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) pi = 1 << port->first_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) if (hw->ksz_switch->member & pi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) hw->ksz_switch->member &= ~pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) bridge_change(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) if (port->first_port > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) hw_del_addr(hw, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) if (!hw_priv->wol_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) port_set_power_saving(port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) if (priv->multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) --hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) if (priv->promiscuous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) --hw->promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) hw_priv->opened--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) if (!(hw_priv->opened)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) ksz_stop_timer(&hw_priv->mib_timer_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) flush_work(&hw_priv->mib_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) hw_dis_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) hw_disable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) hw_clr_multicast(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) /* Delay for receive task to stop scheduling itself. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) msleep(2000 / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) tasklet_kill(&hw_priv->rx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) tasklet_kill(&hw_priv->tx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) free_irq(dev->irq, hw_priv->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) transmit_cleanup(hw_priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) hw_reset_pkts(&hw->rx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) hw_reset_pkts(&hw->tx_desc_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) /* Clean out static MAC table when the switch is shutdown. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) if (hw->features & STP_SUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) sw_clr_sta_mac_table(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) static void hw_cfg_huge_frame(struct dev_info *hw_priv, struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) if (hw->ksz_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) if (hw->features & RX_HUGE_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) data |= SWITCH_HUGE_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) data &= ~SWITCH_HUGE_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) if (hw->features & RX_HUGE_FRAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) hw->rx_cfg |= DMA_RX_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) hw_priv->dev_rcv = dev_rcv_special;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) hw->rx_cfg &= ~DMA_RX_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) if (hw->dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) hw_priv->dev_rcv = port_rcv_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) hw_priv->dev_rcv = dev_rcv_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) static int prepare_hardware(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) /* Remember the network device that requests interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) hw_priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) tasklet_setup(&hw_priv->rx_tasklet, rx_proc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) tasklet_setup(&hw_priv->tx_tasklet, tx_proc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) hw->promiscuous = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) hw->all_multi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) hw->multi_list_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) hw_reset(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) hw_set_desc_base(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) hw->tx_desc_info.ring_phys, hw->rx_desc_info.ring_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) hw_set_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) hw_cfg_huge_frame(hw_priv, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) ksz_init_rx_buffers(hw_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) static void set_media_state(struct net_device *dev, int media_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) if (media_state == priv->media_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) netif_info(priv, link, dev, "link %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) media_state == priv->media_state ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) * netdev_open - open network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) * This function process the open operation of network device. This is caused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) * by the user command "ifconfig ethX up."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) * Return 0 if successful; otherwise an error code indicating failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) static int netdev_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) priv->multicast = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) priv->promiscuous = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) /* Reset device statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) memset(&dev->stats, 0, sizeof(struct net_device_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) memset((void *) port->counter, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) (sizeof(u64) * OID_COUNTER_LAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) if (!(hw_priv->opened)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) rc = prepare_hardware(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) for (i = 0; i < hw->mib_port_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) if (next_jiffies < jiffies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) next_jiffies = jiffies + HZ * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) next_jiffies += HZ * 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) hw_priv->counter[i].time = next_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) hw->port_mib[i].state = media_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) port_init_cnt(hw, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) if (hw->ksz_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) hw->port_mib[HOST_PORT].state = media_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) hw_add_wol_bcast(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) hw_cfg_wol_pme(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) hw_clr_wol_pme_status(&hw_priv->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) port_set_power_saving(port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) * Initialize to invalid value so that link detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) * is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) hw->port_info[p].partner = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) hw->port_info[p].state = media_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) /* Need to open the port in multiple device interfaces mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) port_set_stp_state(hw, port->first_port, STP_STATE_SIMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) if (port->first_port > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) hw_add_addr(hw, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) port_get_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) if (port->force_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) port_force_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) port_set_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) if (!(hw_priv->opened)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) hw_setup_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) hw_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) hw_ena_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) if (hw->mib_port_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) ksz_start_timer(&hw_priv->mib_timer_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) hw_priv->mib_timer_info.period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) hw_priv->opened++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) ksz_start_timer(&priv->monitor_timer_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) priv->monitor_timer_info.period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) priv->media_state = port->linked->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) set_media_state(dev, media_connected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) /* RX errors = rx_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) /* RX dropped = rx_dropped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) /* RX overruns = rx_fifo_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) /* RX frame = rx_crc_errors + rx_frame_errors + rx_length_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) /* TX errors = tx_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) /* TX dropped = tx_dropped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) /* TX overruns = tx_fifo_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) /* TX carrier = tx_aborted_errors + tx_carrier_errors + tx_window_errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) /* collisions = collisions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) * netdev_query_statistics - query network device statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) * This function returns the statistics of the network device. The device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) * needs not be opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) * Return network device statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) static struct net_device_stats *netdev_query_statistics(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) struct ksz_hw *hw = &priv->adapter->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) struct ksz_port_mib *mib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) dev->stats.rx_errors = port->counter[OID_COUNTER_RCV_ERROR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) dev->stats.tx_errors = port->counter[OID_COUNTER_XMIT_ERROR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) /* Reset to zero to add count later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) dev->stats.multicast = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) dev->stats.collisions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) dev->stats.rx_length_errors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) dev->stats.rx_crc_errors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) dev->stats.rx_frame_errors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) dev->stats.tx_window_errors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) mib = &hw->port_mib[p];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) dev->stats.multicast += (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) mib->counter[MIB_COUNTER_RX_MULTICAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) dev->stats.collisions += (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) mib->counter[MIB_COUNTER_TX_TOTAL_COLLISION];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) dev->stats.rx_length_errors += (unsigned long)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) mib->counter[MIB_COUNTER_RX_UNDERSIZE] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) mib->counter[MIB_COUNTER_RX_FRAGMENT] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) mib->counter[MIB_COUNTER_RX_OVERSIZE] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) mib->counter[MIB_COUNTER_RX_JABBER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) dev->stats.rx_crc_errors += (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) mib->counter[MIB_COUNTER_RX_CRC_ERR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) dev->stats.rx_frame_errors += (unsigned long)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) mib->counter[MIB_COUNTER_RX_ALIGNMENT_ERR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) mib->counter[MIB_COUNTER_RX_SYMBOL_ERR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) dev->stats.tx_window_errors += (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) mib->counter[MIB_COUNTER_TX_LATE_COLLISION];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) return &dev->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) * netdev_set_mac_address - set network device MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) * @addr: Buffer of MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) * This function is used to set the MAC address of the network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) * Return 0 to indicate success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) static int netdev_set_mac_address(struct net_device *dev, void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) struct sockaddr *mac = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) uint interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) if (priv->port.first_port > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) hw_del_addr(hw, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) hw->mac_override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) interrupt = hw_block_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) if (priv->port.first_port > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) hw_add_addr(hw, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) hw_set_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) hw_restore_intr(hw, interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) static void dev_set_promiscuous(struct net_device *dev, struct dev_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) struct ksz_hw *hw, int promiscuous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) if (promiscuous != priv->promiscuous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) u8 prev_state = hw->promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) if (promiscuous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) ++hw->promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) --hw->promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) priv->promiscuous = promiscuous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) /* Turn on/off promiscuous mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) if (hw->promiscuous <= 1 && prev_state <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) hw_set_promiscuous(hw, hw->promiscuous);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) * Port is not in promiscuous mode, meaning it is released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) * from the bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) if ((hw->features & STP_SUPPORT) && !promiscuous &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) netif_is_bridge_port(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) int port = priv->port.first_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) port_set_stp_state(hw, port, STP_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) port = 1 << port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) if (sw->member & port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) sw->member &= ~port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) bridge_change(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) static void dev_set_multicast(struct dev_priv *priv, struct ksz_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) int multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) if (multicast != priv->multicast) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) u8 all_multi = hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) if (multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) ++hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) --hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) priv->multicast = multicast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) /* Turn on/off all multicast mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) if (hw->all_multi <= 1 && all_multi <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) hw_set_multicast(hw, hw->all_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) * netdev_set_rx_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) * This routine is used to set multicast addresses or put the network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) * into promiscuous mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) static void netdev_set_rx_mode(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) int multicast = (dev->flags & IFF_ALLMULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) dev_set_promiscuous(dev, priv, hw, (dev->flags & IFF_PROMISC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) if (hw_priv->hw.dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) multicast |= (dev->flags & IFF_MULTICAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) dev_set_multicast(priv, hw, multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) /* Cannot use different hashes in multiple device interfaces mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) if (hw_priv->hw.dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) /* List too big to support so turn on all multicast mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) if (netdev_mc_count(dev) > MAX_MULTICAST_LIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) if (MAX_MULTICAST_LIST != hw->multi_list_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) hw->multi_list_size = MAX_MULTICAST_LIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) ++hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) hw_set_multicast(hw, hw->all_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) netdev_for_each_mc_addr(ha, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) if (i >= MAX_MULTICAST_LIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) memcpy(hw->multi_list[i++], ha->addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) hw->multi_list_size = (u8) i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) hw_set_grp_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) if (MAX_MULTICAST_LIST == hw->multi_list_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) --hw->all_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) hw_set_multicast(hw, hw->all_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) hw->multi_list_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) hw_clr_multicast(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) static int netdev_change_mtu(struct net_device *dev, int new_mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) int hw_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) /* Cannot use different MTU in multiple device interfaces mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) if (hw->dev_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) if (dev != hw_priv->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) hw_mtu = new_mtu + ETHERNET_HEADER_SIZE + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) if (hw_mtu > REGULAR_RX_BUF_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) hw->features |= RX_HUGE_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) hw_mtu = MAX_RX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) hw->features &= ~RX_HUGE_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) hw_mtu = REGULAR_RX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) hw_mtu = (hw_mtu + 3) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) hw_priv->mtu = hw_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) dev->mtu = new_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) * netdev_ioctl - I/O control processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) * @ifr: Interface request structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) * @cmd: I/O control code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) * This function is used to process I/O control calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) * Return 0 to indicate success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) struct mii_ioctl_data *data = if_mii(ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) if (down_interruptible(&priv->proc_sem))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) /* Get address of MII PHY in use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) case SIOCGMIIPHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) data->phy_id = priv->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) /* Read MII PHY register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) case SIOCGMIIREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) if (data->phy_id != priv->id || data->reg_num >= 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) hw_r_phy(hw, port->linked->port_id, data->reg_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) &data->val_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) /* Write MII PHY register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) case SIOCSMIIREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) result = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) else if (data->phy_id != priv->id || data->reg_num >= 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) hw_w_phy(hw, port->linked->port_id, data->reg_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) data->val_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) result = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) up(&priv->proc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) * MII support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) * mdio_read - read PHY register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) * @phy_id: The PHY id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) * @reg_num: The register number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) * This function returns the PHY register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) * Return the register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) u16 val_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) hw_r_phy(hw, port->linked->port_id, reg_num << 1, &val_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) return val_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) * mdio_write - set PHY register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) * @phy_id: The PHY id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) * @reg_num: The register number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) * @val: The register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) * This procedure sets the PHY register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) struct ksz_hw *hw = port->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) int pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) for (i = 0, pi = port->first_port; i < port->port_cnt; i++, pi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) hw_w_phy(hw, pi, reg_num << 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) * ethtool support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) #define EEPROM_SIZE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) static u16 eeprom_data[EEPROM_SIZE] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) #define ADVERTISED_ALL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) (ADVERTISED_10baseT_Half | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) ADVERTISED_10baseT_Full | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) ADVERTISED_100baseT_Half | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) ADVERTISED_100baseT_Full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) /* These functions use the MII functions in mii.c. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) * netdev_get_link_ksettings - get network device settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) * @cmd: Ethtool command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) * This function queries the PHY and returns its state in the ethtool command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) static int netdev_get_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) mii_ethtool_get_link_ksettings(&priv->mii_if, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) /* Save advertised settings for workaround in next function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) ethtool_convert_link_mode_to_legacy_u32(&priv->advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) cmd->link_modes.advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) * netdev_set_link_ksettings - set network device settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) * @cmd: Ethtool command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) * This function sets the PHY according to the ethtool command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) static int netdev_set_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) struct ethtool_link_ksettings copy_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) u32 speed = cmd->base.speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) u32 advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) ethtool_convert_link_mode_to_legacy_u32(&advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) cmd->link_modes.advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) * ethtool utility does not change advertised setting if auto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) * negotiation is not specified explicitly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) if (cmd->base.autoneg && priv->advertising == advertising) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) advertising |= ADVERTISED_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) if (10 == speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) advertising &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) ~(ADVERTISED_100baseT_Full |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) ADVERTISED_100baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) else if (100 == speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) advertising &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) ~(ADVERTISED_10baseT_Full |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) ADVERTISED_10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) if (0 == cmd->base.duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) advertising &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) ~(ADVERTISED_100baseT_Full |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) ADVERTISED_10baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) else if (1 == cmd->base.duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) advertising &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) ~(ADVERTISED_100baseT_Half |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) ADVERTISED_10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) if (cmd->base.autoneg &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) (advertising & ADVERTISED_ALL) == ADVERTISED_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) port->duplex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) port->speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) port->force_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) port->duplex = cmd->base.duplex + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) if (1000 != speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) port->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) if (cmd->base.autoneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) port->force_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) port->force_link = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) memcpy(©_cmd, cmd, sizeof(copy_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) ethtool_convert_legacy_u32_to_link_mode(copy_cmd.link_modes.advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) rc = mii_ethtool_set_link_ksettings(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) &priv->mii_if,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) (const struct ethtool_link_ksettings *)©_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) * netdev_nway_reset - restart auto-negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) * This function restarts the PHY for auto-negotiation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) static int netdev_nway_reset(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) rc = mii_nway_restart(&priv->mii_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) * netdev_get_link - get network device link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) * This function gets the link status from the PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) * Return true if PHY is linked and false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) static u32 netdev_get_link(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) rc = mii_link_ok(&priv->mii_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) * netdev_get_drvinfo - get network driver information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) * @info: Ethtool driver info data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) * This procedure returns the driver information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) static void netdev_get_drvinfo(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) strlcpy(info->version, DRV_VERSION, sizeof(info->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) strlcpy(info->bus_info, pci_name(hw_priv->pdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) sizeof(info->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) static struct hw_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) int end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) } hw_regs_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) { KS_DMA_TX_CTRL, KS884X_INTERRUPTS_STATUS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) { KS_ADD_ADDR_0_LO, KS_ADD_ADDR_F_HI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) { KS884X_ADDR_0_OFFSET, KS8841_WOL_FRAME_BYTE2_OFFSET },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) { KS884X_SIDER_P, KS8842_SGCR7_P },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) { KS8842_MACAR1_P, KS8842_TOSR8_P },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) { KS884X_P1MBCR_P, KS8842_P3ERCR_P },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) * netdev_get_regs_len - get length of register dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) * This function returns the length of the register dump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) * Return length of the register dump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) static int netdev_get_regs_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) struct hw_regs *range = hw_regs_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) int regs_len = 0x10 * sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) while (range->end > range->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) regs_len += (range->end - range->start + 3) / 4 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) return regs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) * netdev_get_regs - get register dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) * @regs: Ethtool registers data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) * @ptr: Buffer to store the register values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) * This procedure dumps the register values in the provided buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) static void netdev_get_regs(struct net_device *dev, struct ethtool_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) int *buf = (int *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) struct hw_regs *range = hw_regs_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) regs->version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) for (len = 0; len < 0x40; len += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) pci_read_config_dword(hw_priv->pdev, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) while (range->end > range->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) for (len = range->start; len < range->end; len += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) *buf = readl(hw->io + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) #define WOL_SUPPORT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) (WAKE_PHY | WAKE_MAGIC | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) WAKE_UCAST | WAKE_MCAST | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) WAKE_BCAST | WAKE_ARP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) * netdev_get_wol - get Wake-on-LAN support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) * @wol: Ethtool Wake-on-LAN data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) * This procedure returns Wake-on-LAN support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) static void netdev_get_wol(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) wol->supported = hw_priv->wol_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) wol->wolopts = hw_priv->wol_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) memset(&wol->sopass, 0, sizeof(wol->sopass));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) * netdev_set_wol - set Wake-on-LAN support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) * @wol: Ethtool Wake-on-LAN data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) * This function sets Wake-on-LAN support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) static int netdev_set_wol(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) /* Need to find a way to retrieve the device IP address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) static const u8 net_addr[] = { 192, 168, 1, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) if (wol->wolopts & ~hw_priv->wol_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) hw_priv->wol_enable = wol->wolopts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) /* Link wakeup cannot really be disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) if (wol->wolopts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) hw_priv->wol_enable |= WAKE_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) hw_enable_wol(&hw_priv->hw, hw_priv->wol_enable, net_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) * netdev_get_msglevel - get debug message level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) * This function returns current debug message level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) * Return current debug message flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) static u32 netdev_get_msglevel(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) return priv->msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) * netdev_set_msglevel - set debug message level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) * @value: Debug message flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) * This procedure sets debug message level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) static void netdev_set_msglevel(struct net_device *dev, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) priv->msg_enable = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) * netdev_get_eeprom_len - get EEPROM length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) * This function returns the length of the EEPROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) * Return length of the EEPROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) static int netdev_get_eeprom_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) return EEPROM_SIZE * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) #define EEPROM_MAGIC 0x10A18842
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) * netdev_get_eeprom - get EEPROM data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) * @eeprom: Ethtool EEPROM data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) * @data: Buffer to store the EEPROM data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) * This function dumps the EEPROM data in the provided buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) static int netdev_get_eeprom(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) u8 *eeprom_byte = (u8 *) eeprom_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) len = (eeprom->offset + eeprom->len + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) for (i = eeprom->offset / 2; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) eeprom_data[i] = eeprom_read(&hw_priv->hw, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) eeprom->magic = EEPROM_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) memcpy(data, &eeprom_byte[eeprom->offset], eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) * netdev_set_eeprom - write EEPROM data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) * @eeprom: Ethtool EEPROM data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) * @data: Data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) * This function modifies the EEPROM data one byte at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) static int netdev_set_eeprom(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) u16 eeprom_word[EEPROM_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) u8 *eeprom_byte = (u8 *) eeprom_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) if (eeprom->magic != EEPROM_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) len = (eeprom->offset + eeprom->len + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) for (i = eeprom->offset / 2; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) eeprom_data[i] = eeprom_read(&hw_priv->hw, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) memcpy(eeprom_word, eeprom_data, EEPROM_SIZE * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) memcpy(&eeprom_byte[eeprom->offset], data, eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) for (i = 0; i < EEPROM_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) if (eeprom_word[i] != eeprom_data[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) eeprom_data[i] = eeprom_word[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) eeprom_write(&hw_priv->hw, i, eeprom_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) * netdev_get_pauseparam - get flow control parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) * @pause: Ethtool PAUSE settings data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) * This procedure returns the PAUSE control flow settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) static void netdev_get_pauseparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) struct ethtool_pauseparam *pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) pause->autoneg = (hw->overrides & PAUSE_FLOW_CTRL) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) if (!hw->ksz_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) pause->rx_pause =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) (hw->rx_cfg & DMA_RX_FLOW_ENABLE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) pause->tx_pause =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) (hw->tx_cfg & DMA_TX_FLOW_ENABLE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) pause->rx_pause =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) (sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) SWITCH_RX_FLOW_CTRL)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) pause->tx_pause =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) (sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) SWITCH_TX_FLOW_CTRL)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) * netdev_set_pauseparam - set flow control parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) * @pause: Ethtool PAUSE settings data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) * This function sets the PAUSE control flow settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) * Not implemented yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) static int netdev_set_pauseparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) struct ethtool_pauseparam *pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) if (pause->autoneg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) if (!pause->rx_pause && !pause->tx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) port->flow_ctrl = PHY_NO_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) port->flow_ctrl = PHY_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) hw->overrides &= ~PAUSE_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) port->force_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) if (hw->ksz_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) SWITCH_RX_FLOW_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) SWITCH_TX_FLOW_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) port_set_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) hw->overrides |= PAUSE_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) if (hw->ksz_switch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) SWITCH_RX_FLOW_CTRL, pause->rx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) SWITCH_TX_FLOW_CTRL, pause->tx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) set_flow_ctrl(hw, pause->rx_pause, pause->tx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) * netdev_get_ringparam - get tx/rx ring parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) * @ring: Ethtool RING settings data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) * This procedure returns the TX/RX ring settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) static void netdev_get_ringparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) struct ethtool_ringparam *ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) ring->tx_max_pending = (1 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) ring->tx_pending = hw->tx_desc_info.alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) ring->rx_max_pending = (1 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) ring->rx_pending = hw->rx_desc_info.alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) #define STATS_LEN (TOTAL_PORT_COUNTER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) char string[ETH_GSTRING_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) } ethtool_stats_keys[STATS_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) { "rx_lo_priority_octets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) { "rx_hi_priority_octets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) { "rx_undersize_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) { "rx_fragments" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) { "rx_oversize_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) { "rx_jabbers" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) { "rx_symbol_errors" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) { "rx_crc_errors" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) { "rx_align_errors" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) { "rx_mac_ctrl_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) { "rx_pause_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) { "rx_bcast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) { "rx_mcast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) { "rx_ucast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) { "rx_64_or_less_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) { "rx_65_to_127_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) { "rx_128_to_255_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) { "rx_256_to_511_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) { "rx_512_to_1023_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) { "rx_1024_to_1522_octet_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) { "tx_lo_priority_octets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) { "tx_hi_priority_octets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) { "tx_late_collisions" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) { "tx_pause_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) { "tx_bcast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) { "tx_mcast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) { "tx_ucast_packets" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) { "tx_deferred" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) { "tx_total_collisions" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) { "tx_excessive_collisions" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) { "tx_single_collisions" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) { "tx_mult_collisions" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) { "rx_discards" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) { "tx_discards" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) * netdev_get_strings - get statistics identity strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) * @stringset: String set identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) * @buf: Buffer to store the strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) * This procedure returns the strings used to identify the statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) static void netdev_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) if (ETH_SS_STATS == stringset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) memcpy(buf, ðtool_stats_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) ETH_GSTRING_LEN * hw->mib_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) * netdev_get_sset_count - get statistics size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) * @sset: The statistics set number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) * This function returns the size of the statistics to be reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) * Return size of the statistics to be reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) static int netdev_get_sset_count(struct net_device *dev, int sset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) switch (sset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) case ETH_SS_STATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) return hw->mib_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) * netdev_get_ethtool_stats - get network device statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) * @stats: Ethtool statistics data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) * @data: Buffer to store the statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) * This procedure returns the statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) static void netdev_get_ethtool_stats(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) struct ethtool_stats *stats, u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) int n_stats = stats->n_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) u64 counter[TOTAL_PORT_COUNTER_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) n = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) if (media_connected == hw->port_mib[p].state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) hw_priv->counter[p].read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) /* Remember first port that requests read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) if (n == SWITCH_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) n = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) if (n < SWITCH_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) schedule_work(&hw_priv->mib_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) if (1 == port->mib_port_cnt && n < SWITCH_PORT_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) p = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) wait_event_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) hw_priv->counter[p].counter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) 2 == hw_priv->counter[p].read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) HZ * 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) for (i = 0, p = n; i < port->mib_port_cnt - n; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) if (0 == i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) wait_event_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) hw_priv->counter[p].counter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) 2 == hw_priv->counter[p].read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) HZ * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) } else if (hw->port_mib[p].cnt_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) wait_event_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) hw_priv->counter[p].counter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) 2 == hw_priv->counter[p].read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) HZ * 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) get_mib_counters(hw, port->first_port, port->mib_port_cnt, counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) n = hw->mib_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) if (n > n_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) n = n_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) n_stats -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) *data++ = counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) * netdev_set_features - set receive checksum support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) * @features: New device features (offloads).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) * This function sets receive checksum support setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) * Return 0 if successful; otherwise an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) static int netdev_set_features(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) mutex_lock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) /* see note in hw_setup() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) if (features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) if (hw->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) mutex_unlock(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) static const struct ethtool_ops netdev_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) .nway_reset = netdev_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) .get_link = netdev_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) .get_drvinfo = netdev_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) .get_regs_len = netdev_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) .get_regs = netdev_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) .get_wol = netdev_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) .set_wol = netdev_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) .get_msglevel = netdev_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) .set_msglevel = netdev_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) .get_eeprom_len = netdev_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) .get_eeprom = netdev_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) .set_eeprom = netdev_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) .get_pauseparam = netdev_get_pauseparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) .set_pauseparam = netdev_set_pauseparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) .get_ringparam = netdev_get_ringparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) .get_strings = netdev_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) .get_sset_count = netdev_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) .get_ethtool_stats = netdev_get_ethtool_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) .get_link_ksettings = netdev_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) .set_link_ksettings = netdev_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) * Hardware monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) static void update_link(struct net_device *dev, struct dev_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) struct ksz_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) if (priv->media_state != port->linked->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) priv->media_state = port->linked->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) set_media_state(dev, media_connected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) static void mib_read_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) struct dev_info *hw_priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) container_of(work, struct dev_info, mib_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) struct ksz_port_mib *mib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) next_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) for (i = 0; i < hw->mib_port_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) mib = &hw->port_mib[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) /* Reading MIB counters or requested to read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) if (mib->cnt_ptr || 1 == hw_priv->counter[i].read) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) /* Need to process receive interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) if (port_r_cnt(hw, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) hw_priv->counter[i].read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) /* Finish reading counters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) if (0 == mib->cnt_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) hw_priv->counter[i].read = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) wake_up_interruptible(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) &hw_priv->counter[i].counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) } else if (time_after_eq(jiffies, hw_priv->counter[i].time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) /* Only read MIB counters when the port is connected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) if (media_connected == mib->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) hw_priv->counter[i].read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) next_jiffies += HZ * 1 * hw->mib_port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) hw_priv->counter[i].time = next_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) /* Port is just disconnected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) } else if (mib->link_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) mib->link_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) /* Read counters one last time after link is lost. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) hw_priv->counter[i].read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) static void mib_monitor(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) struct dev_info *hw_priv = from_timer(hw_priv, t, mib_timer_info.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) mib_read_work(&hw_priv->mib_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) /* This is used to verify Wake-on-LAN is working. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) if (hw_priv->pme_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) if (time_is_before_eq_jiffies(hw_priv->pme_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) hw_clr_wol_pme_status(&hw_priv->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) hw_priv->pme_wait = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) } else if (hw_chk_wol_pme_status(&hw_priv->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) /* PME is asserted. Wait 2 seconds to clear it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) hw_priv->pme_wait = jiffies + HZ * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) ksz_update_timer(&hw_priv->mib_timer_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) * dev_monitor - periodic monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) * @t: timer list containing a network device pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) * This routine is run in a kernel timer to monitor the network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) static void dev_monitor(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) struct dev_priv *priv = from_timer(priv, t, monitor_timer_info.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) struct net_device *dev = priv->mii_if.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) struct dev_info *hw_priv = priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) struct ksz_port *port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) if (!(hw->features & LINK_INT_WORKING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) port_get_link_speed(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) update_link(dev, priv, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) ksz_update_timer(&priv->monitor_timer_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) * Linux network device interface functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) /* Driver exported variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) static int msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) static char *macaddr = ":";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) static char *mac1addr = ":";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) * This enables multiple network device mode for KSZ8842, which contains a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) * switch with two physical ports. Some users like to take control of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) * ports for running Spanning Tree Protocol. The driver will create an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) * additional eth? device for the other port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) * Some limitations are the network devices cannot have different MTU and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) * multicast hash tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) static int multi_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) * As most users select multiple network device mode to use Spanning Tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) * Protocol, this enables a feature in which most unicast and multicast packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) * are forwarded inside the switch and not passed to the host. Only packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) * that need the host's attention are passed to it. This prevents the host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) * wasting CPU time to examine each and every incoming packets and do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) * forwarding itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) * As the hack requires the private bridge header, the driver cannot compile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) * with just the kernel headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) * Enabling STP support also turns on multiple network device mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) static int stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) * This enables fast aging in the KSZ8842 switch. Not sure what situation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) * needs that. However, fast aging is used to flush the dynamic MAC table when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) * STP support is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) static int fast_aging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) * netdev_init - initialize network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) * @dev: Network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) * This function initializes the network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) * Return 0 if successful; otherwise an error code indicating failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) static int __init netdev_init(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) struct dev_priv *priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) /* 500 ms timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) ksz_init_timer(&priv->monitor_timer_info, 500 * HZ / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) dev_monitor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) /* 500 ms timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) dev->watchdog_timeo = HZ / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) * Hardware does not really support IPv6 checksum generation, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) * driver actually runs faster with this on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) dev->hw_features |= NETIF_F_IPV6_CSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) dev->features |= dev->hw_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) sema_init(&priv->proc_sem, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) priv->mii_if.phy_id_mask = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) priv->mii_if.reg_num_mask = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) priv->mii_if.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) priv->mii_if.mdio_read = mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) priv->mii_if.mdio_write = mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) priv->mii_if.phy_id = priv->port.first_port + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) priv->msg_enable = netif_msg_init(msg_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) static const struct net_device_ops netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) .ndo_init = netdev_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) .ndo_open = netdev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) .ndo_stop = netdev_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) .ndo_get_stats = netdev_query_statistics,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) .ndo_start_xmit = netdev_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) .ndo_tx_timeout = netdev_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) .ndo_change_mtu = netdev_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) .ndo_set_features = netdev_set_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) .ndo_set_mac_address = netdev_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) .ndo_do_ioctl = netdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) .ndo_set_rx_mode = netdev_set_rx_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) .ndo_poll_controller = netdev_netpoll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) static void netdev_free(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) if (dev->watchdog_timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) struct platform_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) struct dev_info dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) struct net_device *netdev[SWITCH_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) static int net_device_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) int got_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) i = j = num = got_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) while (j < ETH_ALEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) if (macaddr[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) int digit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) got_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) digit = hex_to_bin(macaddr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) if (digit >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) num = num * 16 + digit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) else if (':' == macaddr[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) got_num = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) } else if (got_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) got_num = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) if (2 == got_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) if (MAIN_PORT == port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) hw_priv->hw.override_addr[j++] = (u8) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) hw_priv->hw.override_addr[5] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) hw_priv->hw.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) hw_priv->hw.ksz_switch->other_addr[j++] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) (u8) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) hw_priv->hw.ksz_switch->other_addr[5] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) hw_priv->hw.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) num = got_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) if (ETH_ALEN == j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) if (MAIN_PORT == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) hw_priv->hw.mac_override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) #define KS884X_DMA_MASK (~0x0UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) static void read_other_addr(struct ksz_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) u16 data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) struct ksz_switch *sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) data[i] = eeprom_read(hw, i + EEPROM_DATA_OTHER_MAC_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) if ((data[0] || data[1] || data[2]) && data[0] != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) sw->other_addr[5] = (u8) data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) sw->other_addr[4] = (u8)(data[0] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) sw->other_addr[3] = (u8) data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) sw->other_addr[2] = (u8)(data[1] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) sw->other_addr[1] = (u8) data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) sw->other_addr[0] = (u8)(data[2] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) #ifndef PCI_VENDOR_ID_MICREL_KS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) #define PCI_VENDOR_ID_MICREL_KS 0x16c6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) struct dev_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) struct dev_info *hw_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) struct ksz_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) struct platform_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) struct ksz_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) unsigned long reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) unsigned long reg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) int mib_port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) int pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) int port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) char banner[sizeof(version)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) struct ksz_switch *sw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) result = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) reg_base = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) reg_len = pci_resource_len(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) if (!request_mem_region(reg_base, reg_len, DRV_NAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) info = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) goto pcidev_init_dev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) hw_priv = &info->dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) hw_priv->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) hw->io = ioremap(reg_base, reg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) if (!hw->io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) goto pcidev_init_io_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) cnt = hw_init(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) if (msg_enable & NETIF_MSG_PROBE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) pr_alert("chip not detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) goto pcidev_init_alloc_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) snprintf(banner, sizeof(banner), "%s", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) banner[13] = cnt + '0'; /* Replace x in "Micrel KSZ884x" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) dev_info(&hw_priv->pdev->dev, "%s\n", banner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) dev_dbg(&hw_priv->pdev->dev, "Mem = %p; IRQ = %d\n", hw->io, pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) /* Assume device is KSZ8841. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) hw->dev_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) port_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) mib_port_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) hw->addr_list_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) hw->mib_cnt = PORT_COUNTER_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) hw->mib_port_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) /* KSZ8842 has a switch with multiple ports. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) if (2 == cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) if (fast_aging)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) hw->overrides |= FAST_AGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) hw->mib_cnt = TOTAL_PORT_COUNTER_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) /* Multiple network device interfaces are required. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) if (multi_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) hw->dev_count = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) hw->addr_list_size = SWITCH_PORT_NUM - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) /* Single network device has multiple ports. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) if (1 == hw->dev_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) port_count = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) mib_port_count = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) hw->mib_port_cnt = TOTAL_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) hw->ksz_switch = kzalloc(sizeof(struct ksz_switch), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) if (!hw->ksz_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) goto pcidev_init_alloc_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) sw = hw->ksz_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) for (i = 0; i < hw->mib_port_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) hw->port_mib[i].mib_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) hw->parent = hw_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) /* Default MTU is 1500. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) hw_priv->mtu = (REGULAR_RX_BUF_SIZE + 3) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) if (ksz_alloc_mem(hw_priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) goto pcidev_init_mem_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) hw_priv->hw.id = net_device_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) spin_lock_init(&hw_priv->hwlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) mutex_init(&hw_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) for (i = 0; i < TOTAL_PORT_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) init_waitqueue_head(&hw_priv->counter[i].counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) if (macaddr[0] != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) get_mac_addr(hw_priv, macaddr, MAIN_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) /* Read MAC address and initialize override address if not overridden. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) hw_read_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) /* Multiple device interfaces mode requires a second MAC address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) if (hw->dev_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) memcpy(sw->other_addr, hw->override_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) read_other_addr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) if (mac1addr[0] != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) get_mac_addr(hw_priv, mac1addr, OTHER_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) hw_setup(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) if (hw->ksz_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) sw_setup(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) hw_priv->wol_support = WOL_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) hw_priv->wol_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) INIT_WORK(&hw_priv->mib_read, mib_read_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) /* 500 ms timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) ksz_init_timer(&hw_priv->mib_timer_info, 500 * HZ / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) mib_monitor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) for (i = 0; i < hw->dev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) dev = alloc_etherdev(sizeof(struct dev_priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) goto pcidev_init_reg_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) SET_NETDEV_DEV(dev, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) info->netdev[i] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) priv = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) priv->adapter = hw_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) priv->id = net_device_present++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) port = &priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) port->port_cnt = port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) port->mib_port_cnt = mib_port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) port->first_port = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) port->flow_ctrl = PHY_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) port->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) port->linked = &hw->port_info[port->first_port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) for (cnt = 0, pi = i; cnt < port_count; cnt++, pi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) hw->port_info[pi].port_id = pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) hw->port_info[pi].pdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) hw->port_info[pi].state = media_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) dev->mem_start = (unsigned long) hw->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) dev->mem_end = dev->mem_start + reg_len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) dev->irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) if (MAIN_PORT == i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) memcpy(dev->dev_addr, hw_priv->hw.override_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) memcpy(dev->dev_addr, sw->other_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) if (ether_addr_equal(sw->other_addr, hw->override_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) dev->dev_addr[5] += port->first_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) dev->netdev_ops = &netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) dev->ethtool_ops = &netdev_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) /* MTU range: 60 - 1894 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) dev->min_mtu = ETH_ZLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) dev->max_mtu = MAX_RX_BUF_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) if (register_netdev(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) goto pcidev_init_reg_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) port_set_power_saving(port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) pci_dev_get(hw_priv->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) pci_set_drvdata(pdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) pcidev_init_reg_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) for (i = 0; i < hw->dev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) if (info->netdev[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) netdev_free(info->netdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) info->netdev[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) pcidev_init_mem_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) ksz_free_mem(hw_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) kfree(hw->ksz_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) pcidev_init_alloc_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) iounmap(hw->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) pcidev_init_io_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) pcidev_init_dev_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) release_mem_region(reg_base, reg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) static void pcidev_exit(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) struct platform_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) struct dev_info *hw_priv = &info->dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) release_mem_region(pci_resource_start(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) pci_resource_len(pdev, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) for (i = 0; i < hw_priv->hw.dev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) if (info->netdev[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) netdev_free(info->netdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) if (hw_priv->hw.io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) iounmap(hw_priv->hw.io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) ksz_free_mem(hw_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) kfree(hw_priv->hw.ksz_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) pci_dev_put(hw_priv->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) static int __maybe_unused pcidev_resume(struct device *dev_d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) struct platform_info *info = dev_get_drvdata(dev_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) struct dev_info *hw_priv = &info->dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) device_wakeup_disable(dev_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) if (hw_priv->wol_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) hw_cfg_wol_pme(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) for (i = 0; i < hw->dev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) if (info->netdev[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) struct net_device *dev = info->netdev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) netdev_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) netif_device_attach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) static int __maybe_unused pcidev_suspend(struct device *dev_d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) struct platform_info *info = dev_get_drvdata(dev_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) struct dev_info *hw_priv = &info->dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) struct ksz_hw *hw = &hw_priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) /* Need to find a way to retrieve the device IP address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) static const u8 net_addr[] = { 192, 168, 1, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) for (i = 0; i < hw->dev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) if (info->netdev[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) struct net_device *dev = info->netdev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) netif_device_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) netdev_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) if (hw_priv->wol_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) hw_enable_wol(hw, hw_priv->wol_enable, net_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) hw_cfg_wol_pme(hw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) device_wakeup_enable(dev_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205) static char pcidev_name[] = "ksz884xp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) static const struct pci_device_id pcidev_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) { PCI_VENDOR_ID_MICREL_KS, 0x8841,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) { PCI_VENDOR_ID_MICREL_KS, 0x8842,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) MODULE_DEVICE_TABLE(pci, pcidev_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) static SIMPLE_DEV_PM_OPS(pcidev_pm_ops, pcidev_suspend, pcidev_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) static struct pci_driver pci_device_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) .driver.pm = &pcidev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) .name = pcidev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) .id_table = pcidev_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) .probe = pcidev_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) .remove = pcidev_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) module_pci_driver(pci_device_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) MODULE_DESCRIPTION("KSZ8841/2 PCI network driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) module_param_named(message, msg_enable, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) module_param(macaddr, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) module_param(mac1addr, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) module_param(fast_aging, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) module_param(multi_dev, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) module_param(stp, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) MODULE_PARM_DESC(macaddr, "MAC address");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) MODULE_PARM_DESC(mac1addr, "Second MAC address");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) MODULE_PARM_DESC(fast_aging, "Fast aging");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) MODULE_PARM_DESC(multi_dev, "Multiple device interfaces");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) MODULE_PARM_DESC(stp, "STP support");