Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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(&copy_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 *)&copy_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, &ethtool_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");