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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Microchip KSZ8795 switch driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2017 Microchip Technology Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *	Tristram Ha <Tristram.Ha@microchip.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) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/platform_data/microchip-ksz.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/if_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <net/dsa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <net/switchdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "ksz_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "ksz8795_reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 	char string[ETH_GSTRING_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) } mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	{ "rx_hi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 	{ "rx_undersize" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	{ "rx_fragments" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	{ "rx_oversize" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	{ "rx_jabbers" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	{ "rx_symbol_err" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	{ "rx_crc_err" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	{ "rx_align_err" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	{ "rx_mac_ctrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	{ "rx_pause" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	{ "rx_bcast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	{ "rx_mcast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	{ "rx_ucast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	{ "rx_64_or_less" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	{ "rx_65_127" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	{ "rx_128_255" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	{ "rx_256_511" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	{ "rx_512_1023" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	{ "rx_1024_1522" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	{ "rx_1523_2000" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	{ "rx_2001" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	{ "tx_hi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	{ "tx_late_col" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	{ "tx_pause" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	{ "tx_bcast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	{ "tx_mcast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	{ "tx_ucast" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	{ "tx_deferred" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	{ "tx_total_col" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	{ "tx_exc_col" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	{ "tx_single_col" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	{ "tx_mult_col" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	{ "rx_total" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	{ "tx_total" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	{ "rx_discards" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	{ "tx_discards" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 			 bool set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 			   bits, set ? bits : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) static int ksz8795_reset_switch(struct ksz_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	/* reset switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	ksz_write8(dev, REG_POWER_MANAGEMENT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		   SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	u8 hi, lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	/* Number of queues can only be 1, 2, or 4. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	switch (queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		queue = PORT_QUEUE_SPLIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		queue = PORT_QUEUE_SPLIT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		queue = PORT_QUEUE_SPLIT_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	ksz_pread8(dev, port, REG_PORT_CTRL_0, &lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	ksz_pread8(dev, port, P_DROP_TAG_CTRL, &hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	lo &= ~PORT_QUEUE_SPLIT_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	if (queue & PORT_QUEUE_SPLIT_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		lo |= PORT_QUEUE_SPLIT_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	hi &= ~PORT_QUEUE_SPLIT_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	if (queue & PORT_QUEUE_SPLIT_4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		hi |= PORT_QUEUE_SPLIT_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	ksz_pwrite8(dev, port, REG_PORT_CTRL_0, lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	ksz_pwrite8(dev, port, P_DROP_TAG_CTRL, hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	/* Default is port based for egress rate limit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	if (queue != PORT_QUEUE_SPLIT_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		ksz_cfg(dev, REG_SW_CTRL_19, SW_OUT_RATE_LIMIT_QUEUE_BASED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 			true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) static void ksz8795_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 			      u64 *cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	u8 check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	ctrl_addr = addr + SWITCH_COUNTER_NUM * port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	mutex_lock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	/* It is almost guaranteed to always read the valid bit because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	 * slow SPI speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	for (loop = 2; loop > 0; loop--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		ksz_read8(dev, REG_IND_MIB_CHECK, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		if (check & MIB_COUNTER_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			ksz_read32(dev, REG_IND_DATA_LO, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 			if (check & MIB_COUNTER_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 				*cnt += MIB_COUNTER_VALUE + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			*cnt += data & MIB_COUNTER_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	mutex_unlock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static void ksz8795_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 			      u64 *dropped, u64 *cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	u8 check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	addr -= SWITCH_COUNTER_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	ctrl_addr = (KS_MIB_TOTAL_RX_1 - KS_MIB_TOTAL_RX_0) * port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	ctrl_addr += addr + KS_MIB_TOTAL_RX_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	mutex_lock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	/* It is almost guaranteed to always read the valid bit because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	 * slow SPI speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	for (loop = 2; loop > 0; loop--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		ksz_read8(dev, REG_IND_MIB_CHECK, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		if (check & MIB_COUNTER_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			ksz_read32(dev, REG_IND_DATA_LO, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			if (addr < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 				u64 total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 				total = check & MIB_TOTAL_BYTES_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 				total <<= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 				*cnt += total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 				*cnt += data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 				if (check & MIB_COUNTER_OVERFLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 					total = MIB_TOTAL_BYTES_H + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 					total <<= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 					*cnt += total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 				if (check & MIB_COUNTER_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 					*cnt += MIB_PACKET_DROPPED + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 				*cnt += data & MIB_PACKET_DROPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	mutex_unlock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) static void ksz8795_freeze_mib(struct ksz_device *dev, int port, bool freeze)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	/* enable the port for flush/freeze function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	if (freeze)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	ksz_cfg(dev, REG_SW_CTRL_6, SW_MIB_COUNTER_FREEZE, freeze);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	/* disable the port after freeze is done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	if (!freeze)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static void ksz8795_port_init_cnt(struct ksz_device *dev, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	struct ksz_port_mib *mib = &dev->ports[port].mib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	/* flush all enabled port MIB counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	ksz_cfg(dev, REG_SW_CTRL_6, SW_MIB_COUNTER_FLUSH, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	mib->cnt_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	/* Some ports may not have MIB counters before SWITCH_COUNTER_NUM. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	while (mib->cnt_ptr < dev->reg_mib_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		dev->dev_ops->r_mib_cnt(dev, port, mib->cnt_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 					&mib->counters[mib->cnt_ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		++mib->cnt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	/* Some ports may not have MIB counters after SWITCH_COUNTER_NUM. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	while (mib->cnt_ptr < dev->mib_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		dev->dev_ops->r_mib_pkt(dev, port, mib->cnt_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 					NULL, &mib->counters[mib->cnt_ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		++mib->cnt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	mib->cnt_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) static void ksz8795_r_table(struct ksz_device *dev, int table, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			    u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	ctrl_addr = IND_ACC_TABLE(table | TABLE_READ) | addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	mutex_lock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	ksz_read64(dev, REG_IND_DATA_HI, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	mutex_unlock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) static void ksz8795_w_table(struct ksz_device *dev, int table, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 			    u64 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	ctrl_addr = IND_ACC_TABLE(table) | addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	mutex_lock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	ksz_write64(dev, REG_IND_DATA_HI, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	mutex_unlock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) static int ksz8795_valid_dyn_entry(struct ksz_device *dev, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	int timeout = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		ksz_read8(dev, REG_IND_DATA_CHECK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	} while ((*data & DYNAMIC_MAC_TABLE_NOT_READY) && timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	/* Entry is not ready for accessing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (*data & DYNAMIC_MAC_TABLE_NOT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	/* Entry is ready for accessing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		ksz_read8(dev, REG_IND_DATA_8, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		/* There is no valid entry in the table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		if (*data & DYNAMIC_MAC_TABLE_MAC_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) static int ksz8795_r_dyn_mac_table(struct ksz_device *dev, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 				   u8 *mac_addr, u8 *fid, u8 *src_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 				   u8 *timestamp, u16 *entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	u32 data_hi, data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	u16 ctrl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	ctrl_addr = IND_ACC_TABLE(TABLE_DYNAMIC_MAC | TABLE_READ) | addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	mutex_lock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	rc = ksz8795_valid_dyn_entry(dev, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	if (rc == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		if (addr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			*entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	} else if (rc == -ENXIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		*entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	/* At least one valid entry in the table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		u64 buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		ksz_read64(dev, REG_IND_DATA_HI, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		data_hi = (u32)(buf >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		data_lo = (u32)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		/* Check out how many valid entry in the table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		cnt = data & DYNAMIC_MAC_TABLE_ENTRIES_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		cnt <<= DYNAMIC_MAC_ENTRIES_H_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		cnt |= (data_hi & DYNAMIC_MAC_TABLE_ENTRIES) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			DYNAMIC_MAC_ENTRIES_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		*entries = cnt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		*fid = (data_hi & DYNAMIC_MAC_TABLE_FID) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			DYNAMIC_MAC_FID_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		*src_port = (data_hi & DYNAMIC_MAC_TABLE_SRC_PORT) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			DYNAMIC_MAC_SRC_PORT_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		*timestamp = (data_hi & DYNAMIC_MAC_TABLE_TIMESTAMP) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			DYNAMIC_MAC_TIMESTAMP_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		mac_addr[5] = (u8)data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		mac_addr[4] = (u8)(data_lo >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		mac_addr[3] = (u8)(data_lo >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		mac_addr[2] = (u8)(data_lo >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		mac_addr[1] = (u8)data_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		mac_addr[0] = (u8)(data_hi >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	mutex_unlock(&dev->alu_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) static int ksz8795_r_sta_mac_table(struct ksz_device *dev, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				   struct alu_struct *alu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	u32 data_hi, data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	u64 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	ksz8795_r_table(dev, TABLE_STATIC_MAC, addr, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	data_hi = data >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	data_lo = (u32)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	if (data_hi & (STATIC_MAC_TABLE_VALID | STATIC_MAC_TABLE_OVERRIDE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		alu->mac[5] = (u8)data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		alu->mac[4] = (u8)(data_lo >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		alu->mac[3] = (u8)(data_lo >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		alu->mac[2] = (u8)(data_lo >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		alu->mac[1] = (u8)data_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		alu->mac[0] = (u8)(data_hi >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		alu->port_forward = (data_hi & STATIC_MAC_TABLE_FWD_PORTS) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 			STATIC_MAC_FWD_PORTS_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		alu->is_override =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			(data_hi & STATIC_MAC_TABLE_OVERRIDE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		data_hi >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		alu->is_use_fid = (data_hi & STATIC_MAC_TABLE_USE_FID) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		alu->fid = (data_hi & STATIC_MAC_TABLE_FID) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			STATIC_MAC_FID_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static void ksz8795_w_sta_mac_table(struct ksz_device *dev, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 				    struct alu_struct *alu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	u32 data_hi, data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	u64 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	data_lo = ((u32)alu->mac[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		((u32)alu->mac[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		((u32)alu->mac[4] << 8) | alu->mac[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	data_hi = ((u32)alu->mac[0] << 8) | alu->mac[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	data_hi |= (u32)alu->port_forward << STATIC_MAC_FWD_PORTS_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	if (alu->is_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		data_hi |= STATIC_MAC_TABLE_OVERRIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	if (alu->is_use_fid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		data_hi |= STATIC_MAC_TABLE_USE_FID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		data_hi |= (u32)alu->fid << STATIC_MAC_FID_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	if (alu->is_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		data_hi |= STATIC_MAC_TABLE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		data_hi &= ~STATIC_MAC_TABLE_OVERRIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	data = (u64)data_hi << 32 | data_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	ksz8795_w_table(dev, TABLE_STATIC_MAC, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) static void ksz8795_from_vlan(u16 vlan, u8 *fid, u8 *member, u8 *valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	*fid = vlan & VLAN_TABLE_FID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	*member = (vlan & VLAN_TABLE_MEMBERSHIP) >> VLAN_TABLE_MEMBERSHIP_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	*valid = !!(vlan & VLAN_TABLE_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) static void ksz8795_to_vlan(u8 fid, u8 member, u8 valid, u16 *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	*vlan = fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	*vlan |= (u16)member << VLAN_TABLE_MEMBERSHIP_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	if (valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		*vlan |= VLAN_TABLE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) static void ksz8795_r_vlan_entries(struct ksz_device *dev, u16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	u64 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	ksz8795_r_table(dev, TABLE_VLAN, addr, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	addr *= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		dev->vlan_cache[addr + i].table[0] = (u16)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		data >>= VLAN_TABLE_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static void ksz8795_r_vlan_table(struct ksz_device *dev, u16 vid, u16 *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	u16 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	u64 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	data = (u16 *)&buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	addr = vid / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	index = vid & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	ksz8795_r_table(dev, TABLE_VLAN, addr, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	*vlan = data[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) static void ksz8795_w_vlan_table(struct ksz_device *dev, u16 vid, u16 vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	u16 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	u64 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	data = (u16 *)&buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	addr = vid / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	index = vid & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	ksz8795_r_table(dev, TABLE_VLAN, addr, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	data[index] = vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	dev->vlan_cache[vid].table[0] = vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	ksz8795_w_table(dev, TABLE_VLAN, addr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) static void ksz8795_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	u8 restart, speed, ctrl, link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	int processed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	u16 data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	u8 p = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	case PHY_REG_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		ksz_pread8(dev, p, P_NEG_RESTART_CTRL, &restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		ksz_pread8(dev, p, P_SPEED_STATUS, &speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		ksz_pread8(dev, p, P_FORCE_CTRL, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		if (restart & PORT_PHY_LOOPBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			data |= PHY_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		if (ctrl & PORT_FORCE_100_MBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			data |= PHY_SPEED_100MBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		if (!(ctrl & PORT_AUTO_NEG_DISABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			data |= PHY_AUTO_NEG_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		if (restart & PORT_POWER_DOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			data |= PHY_POWER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		if (restart & PORT_AUTO_NEG_RESTART)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			data |= PHY_AUTO_NEG_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		if (ctrl & PORT_FORCE_FULL_DUPLEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			data |= PHY_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		if (speed & PORT_HP_MDIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			data |= PHY_HP_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		if (restart & PORT_FORCE_MDIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			data |= PHY_FORCE_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (restart & PORT_AUTO_MDIX_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			data |= PHY_AUTO_MDIX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		if (restart & PORT_TX_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			data |= PHY_TRANSMIT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		if (restart & PORT_LED_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			data |= PHY_LED_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	case PHY_REG_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		ksz_pread8(dev, p, P_LINK_STATUS, &link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		data = PHY_100BTX_FD_CAPABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		       PHY_100BTX_CAPABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		       PHY_10BT_FD_CAPABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		       PHY_10BT_CAPABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		       PHY_AUTO_NEG_CAPABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		if (link & PORT_AUTO_NEG_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			data |= PHY_AUTO_NEG_ACKNOWLEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		if (link & PORT_STAT_LINK_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			data |= PHY_LINK_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	case PHY_REG_ID_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		data = KSZ8795_ID_HI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	case PHY_REG_ID_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		data = KSZ8795_ID_LO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	case PHY_REG_AUTO_NEGOTIATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		ksz_pread8(dev, p, P_LOCAL_CTRL, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		data = PHY_AUTO_NEG_802_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		if (ctrl & PORT_AUTO_NEG_SYM_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			data |= PHY_AUTO_NEG_SYM_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		if (ctrl & PORT_AUTO_NEG_100BTX_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 			data |= PHY_AUTO_NEG_100BTX_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		if (ctrl & PORT_AUTO_NEG_100BTX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			data |= PHY_AUTO_NEG_100BTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		if (ctrl & PORT_AUTO_NEG_10BT_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			data |= PHY_AUTO_NEG_10BT_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		if (ctrl & PORT_AUTO_NEG_10BT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			data |= PHY_AUTO_NEG_10BT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	case PHY_REG_REMOTE_CAPABILITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		ksz_pread8(dev, p, P_REMOTE_STATUS, &link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		data = PHY_AUTO_NEG_802_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		if (link & PORT_REMOTE_SYM_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 			data |= PHY_AUTO_NEG_SYM_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		if (link & PORT_REMOTE_100BTX_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 			data |= PHY_AUTO_NEG_100BTX_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		if (link & PORT_REMOTE_100BTX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 			data |= PHY_AUTO_NEG_100BTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		if (link & PORT_REMOTE_10BT_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 			data |= PHY_AUTO_NEG_10BT_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		if (link & PORT_REMOTE_10BT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			data |= PHY_AUTO_NEG_10BT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		if (data & ~PHY_AUTO_NEG_802_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			data |= PHY_REMOTE_ACKNOWLEDGE_NOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		processed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	if (processed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		*val = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) static void ksz8795_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	u8 p = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	u8 restart, speed, ctrl, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	case PHY_REG_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		/* Do not support PHY reset function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (val & PHY_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		ksz_pread8(dev, p, P_SPEED_STATUS, &speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		data = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		if (val & PHY_HP_MDIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			data |= PORT_HP_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			data &= ~PORT_HP_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		if (data != speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			ksz_pwrite8(dev, p, P_SPEED_STATUS, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		ksz_pread8(dev, p, P_FORCE_CTRL, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		data = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		if (!(val & PHY_AUTO_NEG_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 			data |= PORT_AUTO_NEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			data &= ~PORT_AUTO_NEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		/* Fiber port does not support auto-negotiation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		if (dev->ports[p].fiber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			data |= PORT_AUTO_NEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		if (val & PHY_SPEED_100MBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 			data |= PORT_FORCE_100_MBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 			data &= ~PORT_FORCE_100_MBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		if (val & PHY_FULL_DUPLEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			data |= PORT_FORCE_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 			data &= ~PORT_FORCE_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		if (data != ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 			ksz_pwrite8(dev, p, P_FORCE_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		ksz_pread8(dev, p, P_NEG_RESTART_CTRL, &restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		data = restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		if (val & PHY_LED_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			data |= PORT_LED_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			data &= ~PORT_LED_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		if (val & PHY_TRANSMIT_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			data |= PORT_TX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 			data &= ~PORT_TX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		if (val & PHY_AUTO_NEG_RESTART)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 			data |= PORT_AUTO_NEG_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 			data &= ~(PORT_AUTO_NEG_RESTART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		if (val & PHY_POWER_DOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			data |= PORT_POWER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			data &= ~PORT_POWER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		if (val & PHY_AUTO_MDIX_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			data |= PORT_AUTO_MDIX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			data &= ~PORT_AUTO_MDIX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		if (val & PHY_FORCE_MDIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			data |= PORT_FORCE_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			data &= ~PORT_FORCE_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		if (val & PHY_LOOPBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			data |= PORT_PHY_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			data &= ~PORT_PHY_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		if (data != restart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			ksz_pwrite8(dev, p, P_NEG_RESTART_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	case PHY_REG_AUTO_NEGOTIATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		ksz_pread8(dev, p, P_LOCAL_CTRL, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		data = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		data &= ~(PORT_AUTO_NEG_SYM_PAUSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			  PORT_AUTO_NEG_100BTX_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 			  PORT_AUTO_NEG_100BTX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			  PORT_AUTO_NEG_10BT_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			  PORT_AUTO_NEG_10BT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		if (val & PHY_AUTO_NEG_SYM_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			data |= PORT_AUTO_NEG_SYM_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		if (val & PHY_AUTO_NEG_100BTX_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			data |= PORT_AUTO_NEG_100BTX_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		if (val & PHY_AUTO_NEG_100BTX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			data |= PORT_AUTO_NEG_100BTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		if (val & PHY_AUTO_NEG_10BT_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			data |= PORT_AUTO_NEG_10BT_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		if (val & PHY_AUTO_NEG_10BT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			data |= PORT_AUTO_NEG_10BT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		if (data != ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			ksz_pwrite8(dev, p, P_LOCAL_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) static enum dsa_tag_protocol ksz8795_get_tag_protocol(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 						      int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 						      enum dsa_tag_protocol mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	return DSA_TAG_PROTO_KSZ8795;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) static void ksz8795_get_strings(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 				u32 stringset, uint8_t *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		memcpy(buf + i * ETH_GSTRING_LEN, mib_names[i].string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		       ETH_GSTRING_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) static void ksz8795_cfg_port_member(struct ksz_device *dev, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 				    u8 member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	ksz_pread8(dev, port, P_MIRROR_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	data &= ~PORT_VLAN_MEMBERSHIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	data |= (member & dev->port_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	ksz_pwrite8(dev, port, P_MIRROR_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	dev->ports[port].member = member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static void ksz8795_port_stp_state_set(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 				       u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	int forward = dev->member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	struct ksz_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	int member = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	p = &dev->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	ksz_pread8(dev, port, P_STP_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	case BR_STATE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		if (port < SWITCH_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			member = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	case BR_STATE_LISTENING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		if (port < SWITCH_PORT_NUM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		    p->stp_state == BR_STATE_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 			member = dev->host_mask | p->vid_member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	case BR_STATE_LEARNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		data |= PORT_RX_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	case BR_STATE_FORWARDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		/* This function is also used internally. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		if (port == dev->cpu_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		/* Port is a member of a bridge. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		if (dev->br_member & BIT(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			dev->member |= BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			member = dev->member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			member = dev->host_mask | p->vid_member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	case BR_STATE_BLOCKING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		data |= PORT_LEARN_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		if (port < SWITCH_PORT_NUM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		    p->stp_state == BR_STATE_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			member = dev->host_mask | p->vid_member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		dev_err(ds->dev, "invalid STP state: %d\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	ksz_pwrite8(dev, port, P_STP_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	p->stp_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	/* Port membership may share register with STP state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	if (member >= 0 && member != p->member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		ksz8795_cfg_port_member(dev, port, (u8)member);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	/* Check if forwarding needs to be updated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	if (state != BR_STATE_FORWARDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		if (dev->br_member & BIT(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			dev->member &= ~BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	/* When topology has changed the function ksz_update_port_member
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	 * should be called to modify port forwarding behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	if (forward != dev->member)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		ksz_update_port_member(dev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) static void ksz8795_flush_dyn_mac_table(struct ksz_device *dev, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	u8 learn[TOTAL_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	int first, index, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	struct ksz_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if ((uint)port < TOTAL_PORT_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		first = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		cnt = port + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		/* Flush all ports. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		cnt = dev->mib_port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	for (index = first; index < cnt; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		p = &dev->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		if (!p->on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		ksz_pread8(dev, index, P_STP_CTRL, &learn[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		if (!(learn[index] & PORT_LEARN_DISABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 			ksz_pwrite8(dev, index, P_STP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				    learn[index] | PORT_LEARN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	for (index = first; index < cnt; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		p = &dev->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		if (!p->on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		if (!(learn[index] & PORT_LEARN_DISABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			ksz_pwrite8(dev, index, P_STP_CTRL, learn[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) static int ksz8795_port_vlan_filtering(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				       bool flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				       struct switchdev_trans *trans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (switchdev_trans_ph_prepare(trans))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	/* Discard packets with VID not enabled on the switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	ksz_cfg(dev, S_MIRROR_CTRL, SW_VLAN_ENABLE, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	/* Discard packets with VID not enabled on the ingress port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	for (port = 0; port < dev->phy_port_cnt; ++port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		ksz_port_cfg(dev, port, REG_PORT_CTRL_2, PORT_INGRESS_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			     flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) static bool ksz8795_port_vlan_changes_remove_tag(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	struct ksz_port *p = &dev->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	/* If a VLAN is added with untagged flag different from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	 * port's Remove Tag flag, we need to change the latter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	 * Ignore VID 0, which is always untagged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	 * Ignore CPU port, which will always be tagged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	return untagged != p->remove_tag &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		!(vlan->vid_begin == 0 && vlan->vid_end == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		port != dev->cpu_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) int ksz8795_port_vlan_prepare(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			      const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	/* Reject attempts to add a VLAN that requires the Remove Tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	 * flag to be changed, unless there are no other VLANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	 * currently configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	if (ksz8795_port_vlan_changes_remove_tag(ds, port, vlan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		unsigned int vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		for (vid = 1; vid < dev->num_vlans; ++vid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			u8 fid, member, valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			/* Skip the VIDs we are going to add or reconfigure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			if (vid == vlan->vid_begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				vid = vlan->vid_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			ksz8795_from_vlan(dev->vlan_cache[vid].table[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 					  &fid, &member, &valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			if (valid && (member & BIT(port)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	return ksz_port_vlan_prepare(ds, port, vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) static void ksz8795_port_vlan_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 				  const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	struct ksz_port *p = &dev->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	u16 data, vid, new_pvid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	u8 fid, member, valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	if (ksz8795_port_vlan_changes_remove_tag(ds, port, vlan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		p->remove_tag = untagged;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		ksz8795_r_vlan_table(dev, vid, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		ksz8795_from_vlan(data, &fid, &member, &valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		/* First time to setup the VLAN entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		if (!valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			/* Need to find a way to map VID to FID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			fid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		member |= BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		ksz8795_to_vlan(fid, member, valid, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		ksz8795_w_vlan_table(dev, vid, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		/* change PVID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		if (vlan->flags & BRIDGE_VLAN_INFO_PVID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			new_pvid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	if (new_pvid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		ksz_pread16(dev, port, REG_PORT_CTRL_VID, &vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		vid &= ~VLAN_VID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		vid |= new_pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 				 const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	u16 data, vid, pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	u8 fid, member, valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	bool del_pvid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	pvid = pvid & 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		ksz8795_r_vlan_table(dev, vid, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		ksz8795_from_vlan(data, &fid, &member, &valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		member &= ~BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		/* Invalidate the entry if no more member. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		if (!member) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			fid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			valid = 0;
^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) 		if (pvid == vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			del_pvid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		ksz8795_to_vlan(fid, member, valid, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		ksz8795_w_vlan_table(dev, vid, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (del_pvid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	return 0;
^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) static int ksz8795_port_mirror_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 				   struct dsa_mall_mirror_tc_entry *mirror,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 				   bool ingress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	if (ingress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		dev->mirror_rx |= BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		dev->mirror_tx |= BIT(port);
^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) 	ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_SNIFFER, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* configure mirror port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (dev->mirror_rx || dev->mirror_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 			     PORT_MIRROR_SNIFFER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) static void ksz8795_port_mirror_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 				    struct dsa_mall_mirror_tc_entry *mirror)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (mirror->ingress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		dev->mirror_rx &= ~BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		dev->mirror_tx &= ~BIT(port);
^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) 	ksz_pread8(dev, port, P_MIRROR_CTRL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	if (!dev->mirror_rx && !dev->mirror_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			     PORT_MIRROR_SNIFFER, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) static void ksz8795_port_setup(struct ksz_device *dev, int port, bool cpu_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	struct ksz_port *p = &dev->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	u8 data8, member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	/* enable broadcast storm limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	ksz8795_set_prio_queue(dev, port, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	/* disable DiffServ priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	/* replace priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	ksz_port_cfg(dev, port, P_802_1P_CTRL, PORT_802_1P_REMAPPING, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	/* enable 802.1p priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (cpu_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		if (!p->interface && dev->compat_interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			dev_warn(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 				 "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 				 "Please update your device tree.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 				 port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			p->interface = dev->compat_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		/* Configure MII interface for proper network communication. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		ksz_read8(dev, REG_PORT_5_CTRL_6, &data8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		data8 &= ~PORT_INTERFACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		data8 &= ~PORT_GMII_1GPS_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		switch (p->interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		case PHY_INTERFACE_MODE_MII:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			p->phydev.speed = SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		case PHY_INTERFACE_MODE_RMII:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			data8 |= PORT_INTERFACE_RMII;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			p->phydev.speed = SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		case PHY_INTERFACE_MODE_GMII:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			data8 |= PORT_GMII_1GPS_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			data8 |= PORT_INTERFACE_GMII;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			p->phydev.speed = SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			data8 &= ~PORT_RGMII_ID_IN_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			data8 &= ~PORT_RGMII_ID_OUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			if (p->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 			    p->interface == PHY_INTERFACE_MODE_RGMII_RXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 				data8 |= PORT_RGMII_ID_IN_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			if (p->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 			    p->interface == PHY_INTERFACE_MODE_RGMII_TXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 				data8 |= PORT_RGMII_ID_OUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			data8 |= PORT_GMII_1GPS_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			data8 |= PORT_INTERFACE_RGMII;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			p->phydev.speed = SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		ksz_write8(dev, REG_PORT_5_CTRL_6, data8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		p->phydev.duplex = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		member = dev->port_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		member = dev->host_mask | p->vid_member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	ksz8795_cfg_port_member(dev, port, member);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static void ksz8795_config_cpu_port(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	struct ksz_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	u8 remote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	ds->num_ports = dev->port_cnt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	/* Switch marks the maximum frame with extra byte as oversize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	ksz_cfg(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	ksz_cfg(dev, S_TAIL_TAG_CTRL, SW_TAIL_TAG_ENABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	p = &dev->ports[dev->cpu_port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	p->vid_member = dev->port_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	p->on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	ksz8795_port_setup(dev, dev->cpu_port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	dev->member = dev->host_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	for (i = 0; i < SWITCH_PORT_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		p = &dev->ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		/* Initialize to non-zero so that ksz_cfg_port_member() will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		 * be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		p->vid_member = BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		p->member = dev->port_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		ksz8795_port_stp_state_set(ds, i, BR_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		/* Last port may be disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		if (i == dev->port_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		p->on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		p->phy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	for (i = 0; i < dev->phy_port_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		p = &dev->ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		if (!p->on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		ksz_pread8(dev, i, P_REMOTE_STATUS, &remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if (remote & PORT_FIBER_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			p->fiber = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		if (p->fiber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			ksz_port_cfg(dev, i, P_STP_CTRL, PORT_FORCE_FLOW_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 				     true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			ksz_port_cfg(dev, i, P_STP_CTRL, PORT_FORCE_FLOW_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				     false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int ksz8795_setup(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	struct ksz_device *dev = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	struct alu_struct alu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 				       dev->num_vlans, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	if (!dev->vlan_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	ret = ksz8795_reset_switch(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		dev_err(ds->dev, "failed to reset switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	ksz_cfg(dev, S_REPLACE_VID_CTRL, SW_FLOW_CTRL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	/* Enable automatic fast aging when link changed detected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	ksz_cfg(dev, S_LINK_AGING_CTRL, SW_LINK_AUTO_AGING, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	/* Enable aggressive back off algorithm in half duplex mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	regmap_update_bits(dev->regmap[0], REG_SW_CTRL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			   SW_AGGR_BACKOFF, SW_AGGR_BACKOFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	 * Make sure unicast VLAN boundary is set as default and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	 * enable no excessive collision drop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	regmap_update_bits(dev->regmap[0], REG_SW_CTRL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			   UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 			   UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	ksz8795_config_cpu_port(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	ksz_cfg(dev, REG_SW_CTRL_2, MULTICAST_STORM_DISABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	ksz_cfg(dev, S_REPLACE_VID_CTRL, SW_REPLACE_VID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	ksz_cfg(dev, S_MIRROR_CTRL, SW_MIRROR_RX_TX, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	ksz_cfg(dev, REG_SW_CTRL_19, SW_INS_TAG_ENABLE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	/* set broadcast storm protection 10% rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	regmap_update_bits(dev->regmap[1], S_REPLACE_VID_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 			   BROADCAST_STORM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			   (BROADCAST_STORM_VALUE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			   BROADCAST_STORM_PROT_RATE) / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	for (i = 0; i < VLAN_TABLE_ENTRIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		ksz8795_r_vlan_entries(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	/* Setup STP address for STP operation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	memset(&alu, 0, sizeof(alu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	ether_addr_copy(alu.mac, eth_stp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	alu.is_static = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	alu.is_override = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	alu.port_forward = dev->host_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	ksz8795_w_sta_mac_table(dev, 0, &alu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	ksz_init_mib_timer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static const struct dsa_switch_ops ksz8795_switch_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	.get_tag_protocol	= ksz8795_get_tag_protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	.setup			= ksz8795_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	.phy_read		= ksz_phy_read16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	.phy_write		= ksz_phy_write16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	.phylink_mac_link_down	= ksz_mac_link_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	.port_enable		= ksz_enable_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	.get_strings		= ksz8795_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	.get_ethtool_stats	= ksz_get_ethtool_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	.get_sset_count		= ksz_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	.port_bridge_join	= ksz_port_bridge_join,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	.port_bridge_leave	= ksz_port_bridge_leave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	.port_stp_state_set	= ksz8795_port_stp_state_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	.port_fast_age		= ksz_port_fast_age,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	.port_vlan_filtering	= ksz8795_port_vlan_filtering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	.port_vlan_prepare	= ksz8795_port_vlan_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	.port_vlan_add		= ksz8795_port_vlan_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	.port_vlan_del		= ksz8795_port_vlan_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	.port_fdb_dump		= ksz_port_fdb_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	.port_mdb_prepare       = ksz_port_mdb_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	.port_mdb_add           = ksz_port_mdb_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	.port_mdb_del           = ksz_port_mdb_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	.port_mirror_add	= ksz8795_port_mirror_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	.port_mirror_del	= ksz8795_port_mirror_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static u32 ksz8795_get_port_addr(int port, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	return PORT_CTRL_ADDR(port, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static int ksz8795_switch_detect(struct ksz_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	u8 id1, id2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	u16 id16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	/* read chip id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	ret = ksz_read16(dev, REG_CHIP_ID0, &id16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	id1 = id16 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	id2 = id16 & SW_CHIP_ID_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	if (id1 != FAMILY_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	    (id2 != CHIP_ID_94 && id2 != CHIP_ID_95))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	dev->mib_port_cnt = TOTAL_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	dev->phy_port_cnt = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	dev->port_cnt = SWITCH_PORT_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	if (id2 == CHIP_ID_95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		id2 = 0x95;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		ksz_read8(dev, REG_PORT_1_STATUS_0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		if (val & PORT_FIBER_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			id2 = 0x65;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	} else if (id2 == CHIP_ID_94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		dev->port_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		dev->last_port = dev->port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		id2 = 0x94;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	id16 &= ~0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	id16 |= id2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	dev->chip_id = id16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	dev->cpu_port = dev->mib_port_cnt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	dev->host_mask = BIT(dev->cpu_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct ksz_chip_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	u16 chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	const char *dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	int num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	int num_alus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	int num_statics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	int cpu_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	int port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static const struct ksz_chip_data ksz8795_switch_chips[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		.chip_id = 0x8795,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		.dev_name = "KSZ8795",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		.num_vlans = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		.num_alus = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		.num_statics = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		.cpu_ports = 0x10,	/* can be configured as cpu port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		.port_cnt = 4,		/* total physical port count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		.chip_id = 0x8794,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		.dev_name = "KSZ8794",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		.num_vlans = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		.num_alus = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		.num_statics = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		.cpu_ports = 0x10,	/* can be configured as cpu port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		.port_cnt = 3,		/* total physical port count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		.chip_id = 0x8765,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		.dev_name = "KSZ8765",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 		.num_vlans = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		.num_alus = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		.num_statics = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		.cpu_ports = 0x10,	/* can be configured as cpu port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		.port_cnt = 4,		/* total physical port count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static int ksz8795_switch_init(struct ksz_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	dev->ds->ops = &ksz8795_switch_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	for (i = 0; i < ARRAY_SIZE(ksz8795_switch_chips); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		const struct ksz_chip_data *chip = &ksz8795_switch_chips[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		if (dev->chip_id == chip->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			dev->name = chip->dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			dev->num_vlans = chip->num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 			dev->num_alus = chip->num_alus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			dev->num_statics = chip->num_statics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			dev->port_cnt = chip->port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 			dev->cpu_ports = chip->cpu_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	/* no switch found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	if (!dev->cpu_ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	dev->port_mask = BIT(dev->port_cnt) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	dev->port_mask |= dev->host_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	dev->reg_mib_cnt = SWITCH_COUNTER_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	dev->mib_cnt = TOTAL_SWITCH_COUNTER_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	i = dev->mib_port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	dev->ports = devm_kzalloc(dev->dev, sizeof(struct ksz_port) * i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (!dev->ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	for (i = 0; i < dev->mib_port_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		mutex_init(&dev->ports[i].mib.cnt_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		dev->ports[i].mib.counters =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 			devm_kzalloc(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 				     sizeof(u64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 				     (TOTAL_SWITCH_COUNTER_NUM + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 				     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 		if (!dev->ports[i].mib.counters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	/* set the real number of ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	dev->ds->num_ports = dev->port_cnt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	/* We rely on software untagging on the CPU port, so that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	 * can support both tagged and untagged VLANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	dev->ds->untag_bridge_pvid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	/* VLAN filtering is partly controlled by the global VLAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	 * Enable flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	dev->ds->vlan_filtering_is_global = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static void ksz8795_switch_exit(struct ksz_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	ksz8795_reset_switch(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static const struct ksz_dev_ops ksz8795_dev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	.get_port_addr = ksz8795_get_port_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	.cfg_port_member = ksz8795_cfg_port_member,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	.flush_dyn_mac_table = ksz8795_flush_dyn_mac_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	.port_setup = ksz8795_port_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	.r_phy = ksz8795_r_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	.w_phy = ksz8795_w_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	.r_dyn_mac_table = ksz8795_r_dyn_mac_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	.r_sta_mac_table = ksz8795_r_sta_mac_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	.w_sta_mac_table = ksz8795_w_sta_mac_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	.r_mib_cnt = ksz8795_r_mib_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	.r_mib_pkt = ksz8795_r_mib_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	.freeze_mib = ksz8795_freeze_mib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	.port_init_cnt = ksz8795_port_init_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	.shutdown = ksz8795_reset_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	.detect = ksz8795_switch_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	.init = ksz8795_switch_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	.exit = ksz8795_switch_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int ksz8795_switch_register(struct ksz_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	return ksz_switch_register(dev, &ksz8795_dev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) EXPORT_SYMBOL(ksz8795_switch_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) MODULE_DESCRIPTION("Microchip KSZ8795 Series Switch DSA Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) MODULE_LICENSE("GPL");