From patchwork Fri Apr 23 08:02:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426700 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08492C43460 for ; Fri, 23 Apr 2021 08:03:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE2E66141C for ; Fri, 23 Apr 2021 08:03:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241454AbhDWIDf (ORCPT ); Fri, 23 Apr 2021 04:03:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241304AbhDWIDG (ORCPT ); Fri, 23 Apr 2021 04:03:06 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47E68C06138F for ; Fri, 23 Apr 2021 01:02:30 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007ak-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlX-0006v2-PF; Fri, 23 Apr 2021 10:02:19 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Michael Grzeschik , Oleksij Rempel , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 01/10] net: dsa: microchip: ksz8795: change drivers prefix to be generic Date: Fri, 23 Apr 2021 10:02:09 +0200 Message-Id: <20210423080218.26526-2-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Grzeschik The driver can be used on other chips of this type. To reflect this we rename the drivers prefix from ksz8795 to ksz8. Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn --- v1 -> v4: - extracted this change from bigger previous patch v4 -> v5: - removed extra unavailable variables in ksz8_r_vlan_entries v5 -> v6: - move vlan variable size changes to other patch --- drivers/net/dsa/microchip/ksz8795.c | 224 ++++++++++++------------ drivers/net/dsa/microchip/ksz8795_spi.c | 2 +- drivers/net/dsa/microchip/ksz_common.h | 2 +- 3 files changed, 111 insertions(+), 117 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index b4b7de63ca79..91297df4371c 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -74,7 +74,7 @@ static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits, bits, set ? bits : 0); } -static int ksz8795_reset_switch(struct ksz_device *dev) +static int ksz8_reset_switch(struct ksz_device *dev) { /* reset switch */ ksz_write8(dev, REG_POWER_MANAGEMENT_1, @@ -117,8 +117,7 @@ static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue) true); } -static void ksz8795_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, - u64 *cnt) +static void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) { u16 ctrl_addr; u32 data; @@ -148,8 +147,8 @@ static void ksz8795_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, mutex_unlock(&dev->alu_mutex); } -static void ksz8795_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, - u64 *dropped, u64 *cnt) +static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, + u64 *dropped, u64 *cnt) { u16 ctrl_addr; u32 data; @@ -195,7 +194,7 @@ static void ksz8795_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, mutex_unlock(&dev->alu_mutex); } -static void ksz8795_freeze_mib(struct ksz_device *dev, int port, bool freeze) +static void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) { /* enable the port for flush/freeze function */ if (freeze) @@ -207,7 +206,7 @@ static void ksz8795_freeze_mib(struct ksz_device *dev, int port, bool freeze) ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false); } -static void ksz8795_port_init_cnt(struct ksz_device *dev, int port) +static void ksz8_port_init_cnt(struct ksz_device *dev, int port) { struct ksz_port_mib *mib = &dev->ports[port].mib; @@ -235,8 +234,7 @@ static void ksz8795_port_init_cnt(struct ksz_device *dev, int port) memset(mib->counters, 0, dev->mib_cnt * sizeof(u64)); } -static void ksz8795_r_table(struct ksz_device *dev, int table, u16 addr, - u64 *data) +static void ksz8_r_table(struct ksz_device *dev, int table, u16 addr, u64 *data) { u16 ctrl_addr; @@ -248,8 +246,7 @@ static void ksz8795_r_table(struct ksz_device *dev, int table, u16 addr, mutex_unlock(&dev->alu_mutex); } -static void ksz8795_w_table(struct ksz_device *dev, int table, u16 addr, - u64 data) +static void ksz8_w_table(struct ksz_device *dev, int table, u16 addr, u64 data) { u16 ctrl_addr; @@ -261,7 +258,7 @@ static void ksz8795_w_table(struct ksz_device *dev, int table, u16 addr, mutex_unlock(&dev->alu_mutex); } -static int ksz8795_valid_dyn_entry(struct ksz_device *dev, u8 *data) +static int ksz8_valid_dyn_entry(struct ksz_device *dev, u8 *data) { int timeout = 100; @@ -284,9 +281,9 @@ static int ksz8795_valid_dyn_entry(struct ksz_device *dev, u8 *data) return 0; } -static int ksz8795_r_dyn_mac_table(struct ksz_device *dev, u16 addr, - u8 *mac_addr, u8 *fid, u8 *src_port, - u8 *timestamp, u16 *entries) +static int ksz8_r_dyn_mac_table(struct ksz_device *dev, u16 addr, + u8 *mac_addr, u8 *fid, u8 *src_port, + u8 *timestamp, u16 *entries) { u32 data_hi, data_lo; u16 ctrl_addr; @@ -298,7 +295,7 @@ static int ksz8795_r_dyn_mac_table(struct ksz_device *dev, u16 addr, mutex_lock(&dev->alu_mutex); ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr); - rc = ksz8795_valid_dyn_entry(dev, &data); + rc = ksz8_valid_dyn_entry(dev, &data); if (rc == -EAGAIN) { if (addr == 0) *entries = 0; @@ -341,13 +338,13 @@ static int ksz8795_r_dyn_mac_table(struct ksz_device *dev, u16 addr, return rc; } -static int ksz8795_r_sta_mac_table(struct ksz_device *dev, u16 addr, - struct alu_struct *alu) +static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr, + struct alu_struct *alu) { u32 data_hi, data_lo; u64 data; - ksz8795_r_table(dev, TABLE_STATIC_MAC, addr, &data); + ksz8_r_table(dev, TABLE_STATIC_MAC, addr, &data); data_hi = data >> 32; data_lo = (u32)data; if (data_hi & (STATIC_MAC_TABLE_VALID | STATIC_MAC_TABLE_OVERRIDE)) { @@ -370,8 +367,8 @@ static int ksz8795_r_sta_mac_table(struct ksz_device *dev, u16 addr, return -ENXIO; } -static void ksz8795_w_sta_mac_table(struct ksz_device *dev, u16 addr, - struct alu_struct *alu) +static void ksz8_w_sta_mac_table(struct ksz_device *dev, u16 addr, + struct alu_struct *alu) { u32 data_hi, data_lo; u64 data; @@ -394,17 +391,17 @@ static void ksz8795_w_sta_mac_table(struct ksz_device *dev, u16 addr, data_hi &= ~STATIC_MAC_TABLE_OVERRIDE; data = (u64)data_hi << 32 | data_lo; - ksz8795_w_table(dev, TABLE_STATIC_MAC, addr, data); + ksz8_w_table(dev, TABLE_STATIC_MAC, addr, data); } -static void ksz8795_from_vlan(u16 vlan, u8 *fid, u8 *member, u8 *valid) +static void ksz8_from_vlan(u16 vlan, u8 *fid, u8 *member, u8 *valid) { *fid = vlan & VLAN_TABLE_FID; *member = (vlan & VLAN_TABLE_MEMBERSHIP) >> VLAN_TABLE_MEMBERSHIP_S; *valid = !!(vlan & VLAN_TABLE_VALID); } -static void ksz8795_to_vlan(u8 fid, u8 member, u8 valid, u16 *vlan) +static void ksz8_to_vlan(u8 fid, u8 member, u8 valid, u16 *vlan) { *vlan = fid; *vlan |= (u16)member << VLAN_TABLE_MEMBERSHIP_S; @@ -412,12 +409,12 @@ static void ksz8795_to_vlan(u8 fid, u8 member, u8 valid, u16 *vlan) *vlan |= VLAN_TABLE_VALID; } -static void ksz8795_r_vlan_entries(struct ksz_device *dev, u16 addr) +static void ksz8_r_vlan_entries(struct ksz_device *dev, u16 addr) { u64 data; int i; - ksz8795_r_table(dev, TABLE_VLAN, addr, &data); + ksz8_r_table(dev, TABLE_VLAN, addr, &data); addr *= dev->phy_port_cnt; for (i = 0; i < dev->phy_port_cnt; i++) { dev->vlan_cache[addr + i].table[0] = (u16)data; @@ -425,7 +422,7 @@ static void ksz8795_r_vlan_entries(struct ksz_device *dev, u16 addr) } } -static void ksz8795_r_vlan_table(struct ksz_device *dev, u16 vid, u16 *vlan) +static void ksz8_r_vlan_table(struct ksz_device *dev, u16 vid, u16 *vlan) { int index; u16 *data; @@ -435,11 +432,11 @@ static void ksz8795_r_vlan_table(struct ksz_device *dev, u16 vid, u16 *vlan) data = (u16 *)&buf; addr = vid / dev->phy_port_cnt; index = vid & 3; - ksz8795_r_table(dev, TABLE_VLAN, addr, &buf); + ksz8_r_table(dev, TABLE_VLAN, addr, &buf); *vlan = data[index]; } -static void ksz8795_w_vlan_table(struct ksz_device *dev, u16 vid, u16 vlan) +static void ksz8_w_vlan_table(struct ksz_device *dev, u16 vid, u16 vlan) { int index; u16 *data; @@ -449,13 +446,13 @@ static void ksz8795_w_vlan_table(struct ksz_device *dev, u16 vid, u16 vlan) data = (u16 *)&buf; addr = vid / dev->phy_port_cnt; index = vid & 3; - ksz8795_r_table(dev, TABLE_VLAN, addr, &buf); + ksz8_r_table(dev, TABLE_VLAN, addr, &buf); data[index] = vlan; dev->vlan_cache[vid].table[0] = vlan; - ksz8795_w_table(dev, TABLE_VLAN, addr, buf); + ksz8_w_table(dev, TABLE_VLAN, addr, buf); } -static void ksz8795_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) +static void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) { u8 restart, speed, ctrl, link; int processed = true; @@ -546,7 +543,7 @@ static void ksz8795_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) *val = data; } -static void ksz8795_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) +static void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) { u8 p = phy; u8 restart, speed, ctrl, data; @@ -644,15 +641,15 @@ static void ksz8795_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) } } -static enum dsa_tag_protocol ksz8795_get_tag_protocol(struct dsa_switch *ds, - int port, - enum dsa_tag_protocol mp) +static enum dsa_tag_protocol ksz8_get_tag_protocol(struct dsa_switch *ds, + int port, + enum dsa_tag_protocol mp) { return DSA_TAG_PROTO_KSZ8795; } -static void ksz8795_get_strings(struct dsa_switch *ds, int port, - u32 stringset, uint8_t *buf) +static void ksz8_get_strings(struct dsa_switch *ds, int port, + u32 stringset, uint8_t *buf) { struct ksz_device *dev = ds->priv; int i; @@ -663,8 +660,7 @@ static void ksz8795_get_strings(struct dsa_switch *ds, int port, } } -static void ksz8795_cfg_port_member(struct ksz_device *dev, int port, - u8 member) +static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) { u8 data; @@ -675,8 +671,7 @@ static void ksz8795_cfg_port_member(struct ksz_device *dev, int port, dev->ports[port].member = member; } -static void ksz8795_port_stp_state_set(struct dsa_switch *ds, int port, - u8 state) +static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) { struct ksz_device *dev = ds->priv; int forward = dev->member; @@ -734,7 +729,7 @@ static void ksz8795_port_stp_state_set(struct dsa_switch *ds, int port, p->stp_state = state; /* Port membership may share register with STP state. */ if (member >= 0 && member != p->member) - ksz8795_cfg_port_member(dev, port, (u8)member); + ksz8_cfg_port_member(dev, port, (u8)member); /* Check if forwarding needs to be updated. */ if (state != BR_STATE_FORWARDING) { @@ -749,7 +744,7 @@ static void ksz8795_port_stp_state_set(struct dsa_switch *ds, int port, ksz_update_port_member(dev, port); } -static void ksz8795_flush_dyn_mac_table(struct ksz_device *dev, int port) +static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) { u8 learn[DSA_MAX_PORTS]; int first, index, cnt; @@ -782,9 +777,8 @@ static void ksz8795_flush_dyn_mac_table(struct ksz_device *dev, int port) } } -static int ksz8795_port_vlan_filtering(struct dsa_switch *ds, int port, - bool flag, - struct netlink_ext_ack *extack) +static int ksz8_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag, + struct netlink_ext_ack *extack) { struct ksz_device *dev = ds->priv; @@ -793,9 +787,9 @@ static int ksz8795_port_vlan_filtering(struct dsa_switch *ds, int port, return 0; } -static int ksz8795_port_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) +static int ksz8_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; @@ -804,8 +798,8 @@ static int ksz8795_port_vlan_add(struct dsa_switch *ds, int port, ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); - ksz8795_r_vlan_table(dev, vlan->vid, &data); - ksz8795_from_vlan(data, &fid, &member, &valid); + ksz8_r_vlan_table(dev, vlan->vid, &data); + ksz8_from_vlan(data, &fid, &member, &valid); /* First time to setup the VLAN entry. */ if (!valid) { @@ -815,8 +809,8 @@ static int ksz8795_port_vlan_add(struct dsa_switch *ds, int port, } member |= BIT(port); - ksz8795_to_vlan(fid, member, valid, &data); - ksz8795_w_vlan_table(dev, vlan->vid, data); + ksz8_to_vlan(fid, member, valid, &data); + ksz8_w_vlan_table(dev, vlan->vid, data); /* change PVID */ if (vlan->flags & BRIDGE_VLAN_INFO_PVID) @@ -834,8 +828,8 @@ static int ksz8795_port_vlan_add(struct dsa_switch *ds, int port, return 0; } -static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) +static int ksz8_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; @@ -847,8 +841,8 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); - ksz8795_r_vlan_table(dev, vlan->vid, &data); - ksz8795_from_vlan(data, &fid, &member, &valid); + ksz8_r_vlan_table(dev, vlan->vid, &data); + ksz8_from_vlan(data, &fid, &member, &valid); member &= ~BIT(port); @@ -861,8 +855,8 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, if (pvid == vlan->vid) new_pvid = 1; - ksz8795_to_vlan(fid, member, valid, &data); - ksz8795_w_vlan_table(dev, vlan->vid, data); + ksz8_to_vlan(fid, member, valid, &data); + ksz8_w_vlan_table(dev, vlan->vid, data); if (new_pvid != pvid) ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, pvid); @@ -870,9 +864,9 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, return 0; } -static int ksz8795_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress) +static int ksz8_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress) { struct ksz_device *dev = ds->priv; @@ -894,8 +888,8 @@ static int ksz8795_port_mirror_add(struct dsa_switch *ds, int port, return 0; } -static void ksz8795_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror) +static void ksz8_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) { struct ksz_device *dev = ds->priv; u8 data; @@ -915,7 +909,7 @@ static void ksz8795_port_mirror_del(struct dsa_switch *ds, int port, PORT_MIRROR_SNIFFER, false); } -static void ksz8795_port_setup(struct ksz_device *dev, int port, bool cpu_port) +static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) { struct ksz_port *p = &dev->ports[port]; u8 data8, member; @@ -981,10 +975,10 @@ static void ksz8795_port_setup(struct ksz_device *dev, int port, bool cpu_port) } else { member = dev->host_mask | p->vid_member; } - ksz8795_cfg_port_member(dev, port, member); + ksz8_cfg_port_member(dev, port, member); } -static void ksz8795_config_cpu_port(struct dsa_switch *ds) +static void ksz8_config_cpu_port(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct ksz_port *p; @@ -999,7 +993,7 @@ static void ksz8795_config_cpu_port(struct dsa_switch *ds) p->vid_member = dev->port_mask; p->on = 1; - ksz8795_port_setup(dev, dev->cpu_port, true); + ksz8_port_setup(dev, dev->cpu_port, true); dev->member = dev->host_mask; for (i = 0; i < dev->phy_port_cnt; i++) { @@ -1010,7 +1004,7 @@ static void ksz8795_config_cpu_port(struct dsa_switch *ds) */ p->vid_member = BIT(i); p->member = dev->port_mask; - ksz8795_port_stp_state_set(ds, i, BR_STATE_DISABLED); + ksz8_port_stp_state_set(ds, i, BR_STATE_DISABLED); /* Last port may be disabled. */ if (i == dev->phy_port_cnt) @@ -1034,7 +1028,7 @@ static void ksz8795_config_cpu_port(struct dsa_switch *ds) } } -static int ksz8795_setup(struct dsa_switch *ds) +static int ksz8_setup(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; struct alu_struct alu; @@ -1045,7 +1039,7 @@ static int ksz8795_setup(struct dsa_switch *ds) if (!dev->vlan_cache) return -ENOMEM; - ret = ksz8795_reset_switch(dev); + ret = ksz8_reset_switch(dev); if (ret) { dev_err(ds->dev, "failed to reset switch\n"); return ret; @@ -1068,7 +1062,7 @@ static int ksz8795_setup(struct dsa_switch *ds) UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP, UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP); - ksz8795_config_cpu_port(ds); + ksz8_config_cpu_port(ds); ksz_cfg(dev, REG_SW_CTRL_2, MULTICAST_STORM_DISABLE, true); @@ -1083,7 +1077,7 @@ static int ksz8795_setup(struct dsa_switch *ds) BROADCAST_STORM_PROT_RATE) / 100); for (i = 0; i < (dev->num_vlans / 4); i++) - ksz8795_r_vlan_entries(dev, i); + ksz8_r_vlan_entries(dev, i); /* Setup STP address for STP operation. */ memset(&alu, 0, sizeof(alu)); @@ -1092,7 +1086,7 @@ static int ksz8795_setup(struct dsa_switch *ds) alu.is_override = true; alu.port_forward = dev->host_mask; - ksz8795_w_sta_mac_table(dev, 0, &alu); + ksz8_w_sta_mac_table(dev, 0, &alu); ksz_init_mib_timer(dev); @@ -1101,36 +1095,36 @@ static int ksz8795_setup(struct dsa_switch *ds) return 0; } -static const struct dsa_switch_ops ksz8795_switch_ops = { - .get_tag_protocol = ksz8795_get_tag_protocol, - .setup = ksz8795_setup, +static const struct dsa_switch_ops ksz8_switch_ops = { + .get_tag_protocol = ksz8_get_tag_protocol, + .setup = ksz8_setup, .phy_read = ksz_phy_read16, .phy_write = ksz_phy_write16, .phylink_mac_link_down = ksz_mac_link_down, .port_enable = ksz_enable_port, - .get_strings = ksz8795_get_strings, + .get_strings = ksz8_get_strings, .get_ethtool_stats = ksz_get_ethtool_stats, .get_sset_count = ksz_sset_count, .port_bridge_join = ksz_port_bridge_join, .port_bridge_leave = ksz_port_bridge_leave, - .port_stp_state_set = ksz8795_port_stp_state_set, + .port_stp_state_set = ksz8_port_stp_state_set, .port_fast_age = ksz_port_fast_age, - .port_vlan_filtering = ksz8795_port_vlan_filtering, - .port_vlan_add = ksz8795_port_vlan_add, - .port_vlan_del = ksz8795_port_vlan_del, + .port_vlan_filtering = ksz8_port_vlan_filtering, + .port_vlan_add = ksz8_port_vlan_add, + .port_vlan_del = ksz8_port_vlan_del, .port_fdb_dump = ksz_port_fdb_dump, .port_mdb_add = ksz_port_mdb_add, .port_mdb_del = ksz_port_mdb_del, - .port_mirror_add = ksz8795_port_mirror_add, - .port_mirror_del = ksz8795_port_mirror_del, + .port_mirror_add = ksz8_port_mirror_add, + .port_mirror_del = ksz8_port_mirror_del, }; -static u32 ksz8795_get_port_addr(int port, int offset) +static u32 ksz8_get_port_addr(int port, int offset) { return PORT_CTRL_ADDR(port, offset); } -static int ksz8795_switch_detect(struct ksz_device *dev) +static int ksz8_switch_detect(struct ksz_device *dev) { u8 id1, id2; u16 id16; @@ -1174,7 +1168,7 @@ struct ksz_chip_data { int port_cnt; }; -static const struct ksz_chip_data ksz8795_switch_chips[] = { +static const struct ksz_chip_data ksz8_switch_chips[] = { { .chip_id = 0x8795, .dev_name = "KSZ8795", @@ -1218,14 +1212,14 @@ static const struct ksz_chip_data ksz8795_switch_chips[] = { }, }; -static int ksz8795_switch_init(struct ksz_device *dev) +static int ksz8_switch_init(struct ksz_device *dev) { int i; - dev->ds->ops = &ksz8795_switch_ops; + dev->ds->ops = &ksz8_switch_ops; - for (i = 0; i < ARRAY_SIZE(ksz8795_switch_chips); i++) { - const struct ksz_chip_data *chip = &ksz8795_switch_chips[i]; + for (i = 0; i < ARRAY_SIZE(ksz8_switch_chips); i++) { + const struct ksz_chip_data *chip = &ksz8_switch_chips[i]; if (dev->chip_id == chip->chip_id) { dev->name = chip->dev_name; @@ -1272,36 +1266,36 @@ static int ksz8795_switch_init(struct ksz_device *dev) return 0; } -static void ksz8795_switch_exit(struct ksz_device *dev) +static void ksz8_switch_exit(struct ksz_device *dev) { - ksz8795_reset_switch(dev); + ksz8_reset_switch(dev); } -static const struct ksz_dev_ops ksz8795_dev_ops = { - .get_port_addr = ksz8795_get_port_addr, - .cfg_port_member = ksz8795_cfg_port_member, - .flush_dyn_mac_table = ksz8795_flush_dyn_mac_table, - .port_setup = ksz8795_port_setup, - .r_phy = ksz8795_r_phy, - .w_phy = ksz8795_w_phy, - .r_dyn_mac_table = ksz8795_r_dyn_mac_table, - .r_sta_mac_table = ksz8795_r_sta_mac_table, - .w_sta_mac_table = ksz8795_w_sta_mac_table, - .r_mib_cnt = ksz8795_r_mib_cnt, - .r_mib_pkt = ksz8795_r_mib_pkt, - .freeze_mib = ksz8795_freeze_mib, - .port_init_cnt = ksz8795_port_init_cnt, - .shutdown = ksz8795_reset_switch, - .detect = ksz8795_switch_detect, - .init = ksz8795_switch_init, - .exit = ksz8795_switch_exit, +static const struct ksz_dev_ops ksz8_dev_ops = { + .get_port_addr = ksz8_get_port_addr, + .cfg_port_member = ksz8_cfg_port_member, + .flush_dyn_mac_table = ksz8_flush_dyn_mac_table, + .port_setup = ksz8_port_setup, + .r_phy = ksz8_r_phy, + .w_phy = ksz8_w_phy, + .r_dyn_mac_table = ksz8_r_dyn_mac_table, + .r_sta_mac_table = ksz8_r_sta_mac_table, + .w_sta_mac_table = ksz8_w_sta_mac_table, + .r_mib_cnt = ksz8_r_mib_cnt, + .r_mib_pkt = ksz8_r_mib_pkt, + .freeze_mib = ksz8_freeze_mib, + .port_init_cnt = ksz8_port_init_cnt, + .shutdown = ksz8_reset_switch, + .detect = ksz8_switch_detect, + .init = ksz8_switch_init, + .exit = ksz8_switch_exit, }; -int ksz8795_switch_register(struct ksz_device *dev) +int ksz8_switch_register(struct ksz_device *dev) { - return ksz_switch_register(dev, &ksz8795_dev_ops); + return ksz_switch_register(dev, &ksz8_dev_ops); } -EXPORT_SYMBOL(ksz8795_switch_register); +EXPORT_SYMBOL(ksz8_switch_register); MODULE_AUTHOR("Tristram Ha "); MODULE_DESCRIPTION("Microchip KSZ8795 Series Switch DSA Driver"); diff --git a/drivers/net/dsa/microchip/ksz8795_spi.c b/drivers/net/dsa/microchip/ksz8795_spi.c index f98432a3e2b5..45420c07c99f 100644 --- a/drivers/net/dsa/microchip/ksz8795_spi.c +++ b/drivers/net/dsa/microchip/ksz8795_spi.c @@ -55,7 +55,7 @@ static int ksz8795_spi_probe(struct spi_device *spi) if (ret) return ret; - ret = ksz8795_switch_register(dev); + ret = ksz8_switch_register(dev); /* Main DSA driver may not be started yet. */ if (ret) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index f212775372ce..f0681a891cca 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -142,7 +142,7 @@ int ksz_switch_register(struct ksz_device *dev, const struct ksz_dev_ops *ops); void ksz_switch_remove(struct ksz_device *dev); -int ksz8795_switch_register(struct ksz_device *dev); +int ksz8_switch_register(struct ksz_device *dev); int ksz9477_switch_register(struct ksz_device *dev); void ksz_update_port_member(struct ksz_device *dev, int port); From patchwork Fri Apr 23 08:02:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426704 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C817CC43460 for ; Fri, 23 Apr 2021 08:02:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85B6A6145F for ; Fri, 23 Apr 2021 08:02:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241298AbhDWIDH (ORCPT ); Fri, 23 Apr 2021 04:03:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241147AbhDWIDF (ORCPT ); Fri, 23 Apr 2021 04:03:05 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBD7FC06174A for ; Fri, 23 Apr 2021 01:02:29 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007al-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlX-0006vB-QC; Fri, 23 Apr 2021 10:02:19 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Michael Grzeschik , Oleksij Rempel , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 02/10] net: dsa: microchip: ksz8795: move cpu_select_interface to extra function Date: Fri, 23 Apr 2021 10:02:10 +0200 Message-Id: <20210423080218.26526-3-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Grzeschik This patch moves the cpu interface selection code to a individual function specific for ksz8795. It will make it simpler to customize the code path for different switches supported by this driver. Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn --- v1 -> v5: - extracted this from previous bigger patch --- drivers/net/dsa/microchip/ksz8795.c | 92 ++++++++++++++++------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index 91297df4371c..85fb727c13eb 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -909,10 +909,58 @@ static void ksz8_port_mirror_del(struct dsa_switch *ds, int port, PORT_MIRROR_SNIFFER, false); } +static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port) +{ + struct ksz_port *p = &dev->ports[port]; + u8 data8; + + if (!p->interface && dev->compat_interface) { + dev_warn(dev->dev, + "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. " + "Please update your device tree.\n", + port); + p->interface = dev->compat_interface; + } + + /* Configure MII interface for proper network communication. */ + ksz_read8(dev, REG_PORT_5_CTRL_6, &data8); + data8 &= ~PORT_INTERFACE_TYPE; + data8 &= ~PORT_GMII_1GPS_MODE; + switch (p->interface) { + case PHY_INTERFACE_MODE_MII: + p->phydev.speed = SPEED_100; + break; + case PHY_INTERFACE_MODE_RMII: + data8 |= PORT_INTERFACE_RMII; + p->phydev.speed = SPEED_100; + break; + case PHY_INTERFACE_MODE_GMII: + data8 |= PORT_GMII_1GPS_MODE; + data8 |= PORT_INTERFACE_GMII; + p->phydev.speed = SPEED_1000; + break; + default: + data8 &= ~PORT_RGMII_ID_IN_ENABLE; + data8 &= ~PORT_RGMII_ID_OUT_ENABLE; + if (p->interface == PHY_INTERFACE_MODE_RGMII_ID || + p->interface == PHY_INTERFACE_MODE_RGMII_RXID) + data8 |= PORT_RGMII_ID_IN_ENABLE; + if (p->interface == PHY_INTERFACE_MODE_RGMII_ID || + p->interface == PHY_INTERFACE_MODE_RGMII_TXID) + data8 |= PORT_RGMII_ID_OUT_ENABLE; + data8 |= PORT_GMII_1GPS_MODE; + data8 |= PORT_INTERFACE_RGMII; + p->phydev.speed = SPEED_1000; + break; + } + ksz_write8(dev, REG_PORT_5_CTRL_6, data8); + p->phydev.duplex = 1; +} + static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) { struct ksz_port *p = &dev->ports[port]; - u8 data8, member; + u8 member; /* enable broadcast storm limit */ ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true); @@ -929,47 +977,7 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true); if (cpu_port) { - if (!p->interface && dev->compat_interface) { - dev_warn(dev->dev, - "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. " - "Please update your device tree.\n", - port); - p->interface = dev->compat_interface; - } - - /* Configure MII interface for proper network communication. */ - ksz_read8(dev, REG_PORT_5_CTRL_6, &data8); - data8 &= ~PORT_INTERFACE_TYPE; - data8 &= ~PORT_GMII_1GPS_MODE; - switch (p->interface) { - case PHY_INTERFACE_MODE_MII: - p->phydev.speed = SPEED_100; - break; - case PHY_INTERFACE_MODE_RMII: - data8 |= PORT_INTERFACE_RMII; - p->phydev.speed = SPEED_100; - break; - case PHY_INTERFACE_MODE_GMII: - data8 |= PORT_GMII_1GPS_MODE; - data8 |= PORT_INTERFACE_GMII; - p->phydev.speed = SPEED_1000; - break; - default: - data8 &= ~PORT_RGMII_ID_IN_ENABLE; - data8 &= ~PORT_RGMII_ID_OUT_ENABLE; - if (p->interface == PHY_INTERFACE_MODE_RGMII_ID || - p->interface == PHY_INTERFACE_MODE_RGMII_RXID) - data8 |= PORT_RGMII_ID_IN_ENABLE; - if (p->interface == PHY_INTERFACE_MODE_RGMII_ID || - p->interface == PHY_INTERFACE_MODE_RGMII_TXID) - data8 |= PORT_RGMII_ID_OUT_ENABLE; - data8 |= PORT_GMII_1GPS_MODE; - data8 |= PORT_INTERFACE_RGMII; - p->phydev.speed = SPEED_1000; - break; - } - ksz_write8(dev, REG_PORT_5_CTRL_6, data8); - p->phydev.duplex = 1; + ksz8795_cpu_interface_select(dev, port); member = dev->port_mask; } else { From patchwork Fri Apr 23 08:02:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426702 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 749EFC43461 for ; Fri, 23 Apr 2021 08:02:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 44F83611C2 for ; Fri, 23 Apr 2021 08:02:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241523AbhDWIDX (ORCPT ); Fri, 23 Apr 2021 04:03:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241296AbhDWIDG (ORCPT ); Fri, 23 Apr 2021 04:03:06 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3921AC06138D for ; Fri, 23 Apr 2021 01:02:30 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007ao-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlX-0006vT-SG; Fri, 23 Apr 2021 10:02:19 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Oleksij Rempel , Michael Grzeschik , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 04/10] net: dsa: microchip: ksz8795: add support for ksz88xx chips Date: Fri, 23 Apr 2021 10:02:12 +0200 Message-Id: <20210423080218.26526-5-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org We add support for the ksz8863 and ksz8873 chips which are using the same register patterns but other offsets as the ksz8795. Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel --- v1 -> v4: - extracted this change from bigger previous patch v4 -> v5: - added clear of reset bit for ksz8863 reset code - using extra device flag IS_KSZ88x3 instead of is_ksz8795 function - using DSA_TAG_PROTO_KSZ9893 protocol for ksz88x3 instead v5 -> v6: - changed variable order to revers christmas tree - added back missed dropped handling in init_cnt for ksz8863 - disable VLAN support for ksz8863. Currently it need more work. --- drivers/net/dsa/microchip/ksz8795.c | 321 ++++++++++++++++++++---- drivers/net/dsa/microchip/ksz8795_reg.h | 40 ++- drivers/net/dsa/microchip/ksz_common.h | 1 + 3 files changed, 286 insertions(+), 76 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index 8835217e2804..78181d29db12 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -22,6 +22,9 @@ #include "ksz8795_reg.h" #include "ksz8.h" +/* Used with variable features to indicate capabilities. */ +#define IS_88X3 BIT(0) + static const u8 ksz8795_regs[] = { [REG_IND_CTRL_0] = 0x6E, [REG_IND_DATA_8] = 0x70, @@ -72,9 +75,60 @@ static const u8 ksz8795_shifts[] = { [DYNAMIC_MAC_SRC_PORT] = 24, }; -static const struct { +static const u8 ksz8863_regs[] = { + [REG_IND_CTRL_0] = 0x79, + [REG_IND_DATA_8] = 0x7B, + [REG_IND_DATA_CHECK] = 0x7B, + [REG_IND_DATA_HI] = 0x7C, + [REG_IND_DATA_LO] = 0x80, + [REG_IND_MIB_CHECK] = 0x80, + [P_FORCE_CTRL] = 0x0C, + [P_LINK_STATUS] = 0x0E, + [P_LOCAL_CTRL] = 0x0C, + [P_NEG_RESTART_CTRL] = 0x0D, + [P_REMOTE_STATUS] = 0x0E, + [P_SPEED_STATUS] = 0x0F, + [S_TAIL_TAG_CTRL] = 0x03, +}; + +static const u32 ksz8863_masks[] = { + [PORT_802_1P_REMAPPING] = BIT(3), + [SW_TAIL_TAG_ENABLE] = BIT(6), + [MIB_COUNTER_OVERFLOW] = BIT(7), + [MIB_COUNTER_VALID] = BIT(6), + [VLAN_TABLE_FID] = GENMASK(15, 12), + [VLAN_TABLE_MEMBERSHIP] = GENMASK(18, 16), + [VLAN_TABLE_VALID] = BIT(19), + [STATIC_MAC_TABLE_VALID] = BIT(19), + [STATIC_MAC_TABLE_USE_FID] = BIT(21), + [STATIC_MAC_TABLE_FID] = GENMASK(29, 26), + [STATIC_MAC_TABLE_OVERRIDE] = BIT(20), + [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(18, 16), + [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(5, 0), + [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7), + [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7), + [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 28), + [DYNAMIC_MAC_TABLE_FID] = GENMASK(19, 16), + [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(21, 20), + [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(23, 22), +}; + +static u8 ksz8863_shifts[] = { + [VLAN_TABLE_MEMBERSHIP_S] = 16, + [STATIC_MAC_FWD_PORTS] = 16, + [STATIC_MAC_FID] = 22, + [DYNAMIC_MAC_ENTRIES_H] = 3, + [DYNAMIC_MAC_ENTRIES] = 24, + [DYNAMIC_MAC_FID] = 16, + [DYNAMIC_MAC_TIMESTAMP] = 24, + [DYNAMIC_MAC_SRC_PORT] = 20, +}; + +struct mib_names { char string[ETH_GSTRING_LEN]; -} mib_names[] = { +}; + +static const struct mib_names ksz87xx_mib_names[] = { { "rx_hi" }, { "rx_undersize" }, { "rx_fragments" }, @@ -113,6 +167,43 @@ static const struct { { "tx_discards" }, }; +static const struct mib_names ksz88xx_mib_names[] = { + { "rx" }, + { "rx_hi" }, + { "rx_undersize" }, + { "rx_fragments" }, + { "rx_oversize" }, + { "rx_jabbers" }, + { "rx_symbol_err" }, + { "rx_crc_err" }, + { "rx_align_err" }, + { "rx_mac_ctrl" }, + { "rx_pause" }, + { "rx_bcast" }, + { "rx_mcast" }, + { "rx_ucast" }, + { "rx_64_or_less" }, + { "rx_65_127" }, + { "rx_128_255" }, + { "rx_256_511" }, + { "rx_512_1023" }, + { "rx_1024_1522" }, + { "tx" }, + { "tx_hi" }, + { "tx_late_col" }, + { "tx_pause" }, + { "tx_bcast" }, + { "tx_mcast" }, + { "tx_ucast" }, + { "tx_deferred" }, + { "tx_total_col" }, + { "tx_exc_col" }, + { "tx_single_col" }, + { "tx_mult_col" }, + { "rx_discards" }, + { "tx_discards" }, +}; + static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) { regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); @@ -127,10 +218,18 @@ static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits, static int ksz8_reset_switch(struct ksz_device *dev) { - /* reset switch */ - ksz_write8(dev, REG_POWER_MANAGEMENT_1, - SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S); - ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0); + if (dev->features & IS_88X3) { + /* reset switch */ + ksz_cfg(dev, KSZ8863_REG_SW_RESET, + KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET, true); + ksz_cfg(dev, KSZ8863_REG_SW_RESET, + KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET, false); + } else { + /* reset switch */ + ksz_write8(dev, REG_POWER_MANAGEMENT_1, + SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S); + ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0); + } return 0; } @@ -201,8 +300,8 @@ static void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) mutex_unlock(&dev->alu_mutex); } -static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, - u64 *dropped, u64 *cnt) +static void ksz8795_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, + u64 *dropped, u64 *cnt) { struct ksz8 *ksz8 = dev->priv; const u32 *masks = ksz8->masks; @@ -213,8 +312,8 @@ static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, int loop; addr -= dev->reg_mib_cnt; - ctrl_addr = (KS_MIB_TOTAL_RX_1 - KS_MIB_TOTAL_RX_0) * port; - ctrl_addr += addr + KS_MIB_TOTAL_RX_0; + ctrl_addr = (KSZ8795_MIB_TOTAL_RX_1 - KSZ8795_MIB_TOTAL_RX_0) * port; + ctrl_addr += addr + KSZ8795_MIB_TOTAL_RX_0; ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ); mutex_lock(&dev->alu_mutex); @@ -251,8 +350,53 @@ static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, mutex_unlock(&dev->alu_mutex); } +static void ksz8863_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, + u64 *dropped, u64 *cnt) +{ + struct ksz8 *ksz8 = dev->priv; + const u8 *regs = ksz8->regs; + u32 *last = (u32 *)dropped; + u16 ctrl_addr; + u32 data; + u32 cur; + + addr -= dev->reg_mib_cnt; + ctrl_addr = addr ? KSZ8863_MIB_PACKET_DROPPED_TX_0 : + KSZ8863_MIB_PACKET_DROPPED_RX_0; + ctrl_addr += port; + ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ); + + mutex_lock(&dev->alu_mutex); + ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr); + ksz_read32(dev, regs[REG_IND_DATA_LO], &data); + mutex_unlock(&dev->alu_mutex); + + data &= MIB_PACKET_DROPPED; + cur = last[addr]; + if (data != cur) { + last[addr] = data; + if (data < cur) + data += MIB_PACKET_DROPPED + 1; + data -= cur; + *cnt += data; + } +} + +static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, + u64 *dropped, u64 *cnt) +{ + if (dev->features & IS_88X3) { + ksz8863_r_mib_pkt(dev, port, addr, dropped, cnt); + } else { + ksz8795_r_mib_pkt(dev, port, addr, dropped, cnt); + } +} + static void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) { + if (dev->features & IS_88X3) + return; + /* enable the port for flush/freeze function */ if (freeze) ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), true); @@ -266,11 +410,14 @@ static void ksz8_freeze_mib(struct ksz_device *dev, int port, bool freeze) static void ksz8_port_init_cnt(struct ksz_device *dev, int port) { struct ksz_port_mib *mib = &dev->ports[port].mib; + u64 *dropped; - /* flush all enabled port MIB counters */ - ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), true); - ksz_cfg(dev, REG_SW_CTRL_6, SW_MIB_COUNTER_FLUSH, true); - ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false); + if (!(dev->features & IS_88X3)) { + /* flush all enabled port MIB counters */ + ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), true); + ksz_cfg(dev, REG_SW_CTRL_6, SW_MIB_COUNTER_FLUSH, true); + ksz_cfg(dev, REG_SW_CTRL_6, BIT(port), false); + } mib->cnt_ptr = 0; @@ -281,10 +428,13 @@ static void ksz8_port_init_cnt(struct ksz_device *dev, int port) ++mib->cnt_ptr; } + /* last one in storage */ + dropped = &mib->counters[dev->mib_cnt]; + /* Some ports may not have MIB counters after SWITCH_COUNTER_NUM. */ while (mib->cnt_ptr < dev->mib_cnt) { dev->dev_ops->r_mib_pkt(dev, port, mib->cnt_ptr, - NULL, &mib->counters[mib->cnt_ptr]); + dropped, &mib->counters[mib->cnt_ptr]); ++mib->cnt_ptr; } mib->cnt_ptr = 0; @@ -486,7 +636,7 @@ static void ksz8_from_vlan(struct ksz_device *dev, u32 vlan, u8 *fid, } static void ksz8_to_vlan(struct ksz_device *dev, u8 fid, u8 member, u8 valid, - u32 *vlan) + u16 *vlan) { struct ksz8 *ksz8 = dev->priv; const u8 *shifts = ksz8->shifts; @@ -561,8 +711,13 @@ static void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data |= PHY_LOOPBACK; if (ctrl & PORT_FORCE_100_MBIT) data |= PHY_SPEED_100MBIT; - if (!(ctrl & PORT_AUTO_NEG_DISABLE)) - data |= PHY_AUTO_NEG_ENABLE; + if (dev->features & IS_88X3) { + if ((ctrl & PORT_AUTO_NEG_ENABLE)) + data |= PHY_AUTO_NEG_ENABLE; + } else { + if (!(ctrl & PORT_AUTO_NEG_DISABLE)) + data |= PHY_AUTO_NEG_ENABLE; + } if (restart & PORT_POWER_DOWN) data |= PHY_POWER_DOWN; if (restart & PORT_AUTO_NEG_RESTART) @@ -596,7 +751,10 @@ static void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data = KSZ8795_ID_HI; break; case PHY_REG_ID_2: - data = KSZ8795_ID_LO; + if (dev->features & IS_88X3) + data = KSZ8863_ID_LO; + else + data = KSZ8795_ID_LO; break; case PHY_REG_AUTO_NEGOTIATION: ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl); @@ -659,14 +817,22 @@ static void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) ksz_pwrite8(dev, p, regs[P_SPEED_STATUS], data); ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl); data = ctrl; - if (!(val & PHY_AUTO_NEG_ENABLE)) - data |= PORT_AUTO_NEG_DISABLE; - else - data &= ~PORT_AUTO_NEG_DISABLE; + if (dev->features & IS_88X3) { + if ((val & PHY_AUTO_NEG_ENABLE)) + data |= PORT_AUTO_NEG_ENABLE; + else + data &= ~PORT_AUTO_NEG_ENABLE; + } else { + if (!(val & PHY_AUTO_NEG_ENABLE)) + data |= PORT_AUTO_NEG_DISABLE; + else + data &= ~PORT_AUTO_NEG_DISABLE; + + /* Fiber port does not support auto-negotiation. */ + if (dev->ports[p].fiber) + data |= PORT_AUTO_NEG_DISABLE; + } - /* Fiber port does not support auto-negotiation. */ - if (dev->ports[p].fiber) - data |= PORT_AUTO_NEG_DISABLE; if (val & PHY_SPEED_100MBIT) data |= PORT_FORCE_100_MBIT; else @@ -740,7 +906,11 @@ static enum dsa_tag_protocol ksz8_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp) { - return DSA_TAG_PROTO_KSZ8795; + struct ksz_device *dev = ds->priv; + + /* ksz88x3 uses the same tag schema as KSZ9893 */ + return (dev->features & IS_88X3) ? + DSA_TAG_PROTO_KSZ9893 : DSA_TAG_PROTO_KSZ8795; } static void ksz8_get_strings(struct dsa_switch *ds, int port, @@ -750,8 +920,8 @@ static void ksz8_get_strings(struct dsa_switch *ds, int port, int i; for (i = 0; i < dev->mib_cnt; i++) { - memcpy(buf + i * ETH_GSTRING_LEN, mib_names[i].string, - ETH_GSTRING_LEN); + memcpy(buf + i * ETH_GSTRING_LEN, + dev->mib_names[i].string, ETH_GSTRING_LEN); } } @@ -877,6 +1047,9 @@ static int ksz8_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag, { struct ksz_device *dev = ds->priv; + if (dev->features & IS_88X3) + return -ENOTSUPP; + ksz_cfg(dev, S_MIRROR_CTRL, SW_VLAN_ENABLE, flag); return 0; @@ -888,10 +1061,12 @@ static int ksz8_port_vlan_add(struct dsa_switch *ds, int port, { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; - u16 new_pvid = 0; - u32 data = 0; + u16 data, new_pvid = 0; u8 fid, member, valid; + if (dev->features & IS_88X3) + return -ENOTSUPP; + ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); ksz8_r_vlan_table(dev, vlan->vid, &data); @@ -929,10 +1104,12 @@ static int ksz8_port_vlan_del(struct dsa_switch *ds, int port, { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; - u16 pvid, new_pvid = 0; - u32 data = 0; + u16 data, pvid, new_pvid = 0; u8 fid, member, valid; + if (dev->features & IS_88X3) + return -ENOTSUPP; + ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid); pvid = pvid & 0xFFF; @@ -1064,7 +1241,8 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) /* enable broadcast storm limit */ ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true); - ksz8795_set_prio_queue(dev, port, 4); + if (!(dev->features & IS_88X3)) + ksz8795_set_prio_queue(dev, port, 4); /* disable DiffServ priority */ ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false); @@ -1077,7 +1255,8 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true); if (cpu_port) { - ksz8795_cpu_interface_select(dev, port); + if (!(dev->features & IS_88X3)) + ksz8795_cpu_interface_select(dev, port); member = dev->port_mask; } else { @@ -1127,9 +1306,11 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds) p = &dev->ports[i]; if (!p->on) continue; - ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote); - if (remote & PORT_FIBER_MODE) - p->fiber = 1; + if (!(dev->features & IS_88X3)) { + ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote); + if (remote & PORT_FIBER_MODE) + p->fiber = 1; + } if (p->fiber) ksz_port_cfg(dev, i, P_STP_CTRL, PORT_FORCE_FLOW_CTRL, true); @@ -1248,19 +1429,33 @@ static int ksz8_switch_detect(struct ksz_device *dev) id1 = id16 >> 8; id2 = id16 & SW_CHIP_ID_M; - if (id1 != FAMILY_ID || - (id2 != CHIP_ID_94 && id2 != CHIP_ID_95)) - return -ENODEV; - if (id2 == CHIP_ID_95) { - u8 val; + switch (id1) { + case KSZ87_FAMILY_ID: + if ((id2 != CHIP_ID_94 && id2 != CHIP_ID_95)) + return -ENODEV; + + if (id2 == CHIP_ID_95) { + u8 val; - id2 = 0x95; - ksz_read8(dev, REG_PORT_1_STATUS_0, &val); - if (val & PORT_FIBER_MODE) - id2 = 0x65; - } else if (id2 == CHIP_ID_94) { - id2 = 0x94; + id2 = 0x95; + ksz_read8(dev, REG_PORT_STATUS_0, &val); + if (val & PORT_FIBER_MODE) + id2 = 0x65; + } else if (id2 == CHIP_ID_94) { + id2 = 0x94; + } + break; + case KSZ88_FAMILY_ID: + if (id2 != CHIP_ID_63) + return -ENODEV; + + dev->features |= IS_88X3; + + break; + default: + dev_err(dev->dev, "invalid family id: %d\n", id1); + return -ENODEV; } id16 &= ~0xff; id16 |= id2; @@ -1321,6 +1516,15 @@ static const struct ksz_chip_data ksz8_switch_chips[] = { .cpu_ports = 0x10, /* can be configured as cpu port */ .port_cnt = 5, /* total cpu and user ports */ }, + { + .chip_id = 0x8830, + .dev_name = "KSZ8863/KSZ8873", + .num_vlans = 16, + .num_alus = 0, + .num_statics = 8, + .cpu_ports = 0x4, /* can be configured as cpu port */ + .port_cnt = 3, + }, }; static int ksz8_switch_init(struct ksz_device *dev) @@ -1353,12 +1557,21 @@ static int ksz8_switch_init(struct ksz_device *dev) if (!dev->cpu_ports) return -ENODEV; - ksz8->regs = ksz8795_regs; - ksz8->masks = ksz8795_masks; - ksz8->shifts = ksz8795_shifts; + if (dev->features & IS_88X3) { + ksz8->regs = ksz8863_regs; + ksz8->masks = ksz8863_masks; + ksz8->shifts = ksz8863_shifts; + dev->mib_cnt = ARRAY_SIZE(ksz88xx_mib_names); + dev->mib_names = ksz88xx_mib_names; + } else { + ksz8->regs = ksz8795_regs; + ksz8->masks = ksz8795_masks; + ksz8->shifts = ksz8795_shifts; + dev->mib_cnt = ARRAY_SIZE(ksz87xx_mib_names); + dev->mib_names = ksz87xx_mib_names; + } - dev->reg_mib_cnt = KSZ8795_COUNTER_NUM; - dev->mib_cnt = ARRAY_SIZE(mib_names); + dev->reg_mib_cnt = MIB_COUNTER_NUM; dev->ports = devm_kzalloc(dev->dev, dev->port_cnt * sizeof(struct ksz_port), diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h index eea78c5636a0..c2e52c40a54c 100644 --- a/drivers/net/dsa/microchip/ksz8795_reg.h +++ b/drivers/net/dsa/microchip/ksz8795_reg.h @@ -16,7 +16,8 @@ #define REG_CHIP_ID0 0x00 -#define FAMILY_ID 0x87 +#define KSZ87_FAMILY_ID 0x87 +#define KSZ88_FAMILY_ID 0x88 #define REG_CHIP_ID1 0x01 @@ -28,6 +29,12 @@ #define CHIP_ID_94 0x60 #define CHIP_ID_95 0x90 +#define CHIP_ID_63 0x30 + +#define KSZ8863_REG_SW_RESET 0x43 + +#define KSZ8863_GLOBAL_SOFTWARE_RESET BIT(4) +#define KSZ8863_PCS_RESET BIT(0) #define REG_SW_CTRL_0 0x02 @@ -267,6 +274,7 @@ #define REG_PORT_3_CTRL_9 0x3C #define REG_PORT_4_CTRL_9 0x4C +#define PORT_AUTO_NEG_ENABLE BIT(7) #define PORT_AUTO_NEG_DISABLE BIT(7) #define PORT_FORCE_100_MBIT BIT(6) #define PORT_FORCE_FULL_DUPLEX BIT(5) @@ -800,6 +808,7 @@ #define KSZ8795_ID_HI 0x0022 #define KSZ8795_ID_LO 0x1550 +#define KSZ8863_ID_LO 0x1430 #define KSZ8795_SW_ID 0x8795 @@ -830,7 +839,7 @@ #define KS_PRIO_IN_REG 4 -#define KSZ8795_COUNTER_NUM 0x20 +#define MIB_COUNTER_NUM 0x20 /* Common names used by other drivers */ @@ -876,26 +885,13 @@ #define MIB_COUNTER_VALUE 0x3FFFFFFF -#define KS_MIB_TOTAL_RX_0 0x100 -#define KS_MIB_TOTAL_TX_0 0x101 -#define KS_MIB_PACKET_DROPPED_RX_0 0x102 -#define KS_MIB_PACKET_DROPPED_TX_0 0x103 -#define KS_MIB_TOTAL_RX_1 0x104 -#define KS_MIB_TOTAL_TX_1 0x105 -#define KS_MIB_PACKET_DROPPED_TX_1 0x106 -#define KS_MIB_PACKET_DROPPED_RX_1 0x107 -#define KS_MIB_TOTAL_RX_2 0x108 -#define KS_MIB_TOTAL_TX_2 0x109 -#define KS_MIB_PACKET_DROPPED_TX_2 0x10A -#define KS_MIB_PACKET_DROPPED_RX_2 0x10B -#define KS_MIB_TOTAL_RX_3 0x10C -#define KS_MIB_TOTAL_TX_3 0x10D -#define KS_MIB_PACKET_DROPPED_TX_3 0x10E -#define KS_MIB_PACKET_DROPPED_RX_3 0x10F -#define KS_MIB_TOTAL_RX_4 0x110 -#define KS_MIB_TOTAL_TX_4 0x111 -#define KS_MIB_PACKET_DROPPED_TX_4 0x112 -#define KS_MIB_PACKET_DROPPED_RX_4 0x113 +#define KSZ8795_MIB_TOTAL_RX_0 0x100 +#define KSZ8795_MIB_TOTAL_TX_0 0x101 +#define KSZ8795_MIB_TOTAL_RX_1 0x104 +#define KSZ8795_MIB_TOTAL_TX_1 0x105 + +#define KSZ8863_MIB_PACKET_DROPPED_TX_0 0x100 +#define KSZ8863_MIB_PACKET_DROPPED_RX_0 0x105 #define MIB_PACKET_DROPPED 0x0000FFFF diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index f0681a891cca..e0bbdca64375 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -71,6 +71,7 @@ struct ksz_device { int port_cnt; int reg_mib_cnt; int mib_cnt; + const struct mib_names *mib_names; phy_interface_t compat_interface; u32 regs_size; bool phy_errata_9477; From patchwork Fri Apr 23 08:02:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 153C4C433B4 for ; Fri, 23 Apr 2021 08:02:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF977611C1 for ; Fri, 23 Apr 2021 08:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241450AbhDWIDQ (ORCPT ); Fri, 23 Apr 2021 04:03:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241196AbhDWIDF (ORCPT ); Fri, 23 Apr 2021 04:03:05 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E317CC061756 for ; Fri, 23 Apr 2021 01:02:29 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007ap-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlX-0006vd-TD; Fri, 23 Apr 2021 10:02:19 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Michael Grzeschik , Oleksij Rempel , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 05/10] net: dsa: microchip: Add Microchip KSZ8863 SPI based driver support Date: Fri, 23 Apr 2021 10:02:13 +0200 Message-Id: <20210423080218.26526-6-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Grzeschik Add KSZ88X3 driver support. We add support for the KXZ88X3 three port switches using the SPI Interface. Reviewed-by: Florian Fainelli Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel --- v1 -> v2: - this glue was not implemented v2 -> v3: - this glue was part of previous bigger patch v3 -> v4: - this glue was moved to this separate patch v4 -> v5: - added reviewed by from f.fainelli - using device_get_match_data instead of own matching code --- drivers/net/dsa/microchip/ksz8795_spi.c | 44 ++++++++++++++++++------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795_spi.c b/drivers/net/dsa/microchip/ksz8795_spi.c index 45420c07c99f..708f8daaedbc 100644 --- a/drivers/net/dsa/microchip/ksz8795_spi.c +++ b/drivers/net/dsa/microchip/ksz8795_spi.c @@ -14,34 +14,52 @@ #include #include +#include "ksz8.h" #include "ksz_common.h" -#define SPI_ADDR_SHIFT 12 -#define SPI_ADDR_ALIGN 3 -#define SPI_TURNAROUND_SHIFT 1 +#define KSZ8795_SPI_ADDR_SHIFT 12 +#define KSZ8795_SPI_ADDR_ALIGN 3 +#define KSZ8795_SPI_TURNAROUND_SHIFT 1 -KSZ_REGMAP_TABLE(ksz8795, 16, SPI_ADDR_SHIFT, - SPI_TURNAROUND_SHIFT, SPI_ADDR_ALIGN); +#define KSZ8863_SPI_ADDR_SHIFT 8 +#define KSZ8863_SPI_ADDR_ALIGN 8 +#define KSZ8863_SPI_TURNAROUND_SHIFT 0 + +KSZ_REGMAP_TABLE(ksz8795, 16, KSZ8795_SPI_ADDR_SHIFT, + KSZ8795_SPI_TURNAROUND_SHIFT, KSZ8795_SPI_ADDR_ALIGN); + +KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT, + KSZ8863_SPI_TURNAROUND_SHIFT, KSZ8863_SPI_ADDR_ALIGN); static int ksz8795_spi_probe(struct spi_device *spi) { + const struct regmap_config *regmap_config; + struct device *ddev = &spi->dev; + struct ksz8 *ksz8; struct regmap_config rc; struct ksz_device *dev; - int i, ret; + int i, ret = 0; - dev = ksz_switch_alloc(&spi->dev, spi); + ksz8 = devm_kzalloc(&spi->dev, sizeof(struct ksz8), GFP_KERNEL); + ksz8->priv = spi; + + dev = ksz_switch_alloc(&spi->dev, ksz8); if (!dev) return -ENOMEM; + regmap_config = device_get_match_data(ddev); + if (!regmap_config) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { - rc = ksz8795_regmap_config[i]; + rc = regmap_config[i]; rc.lock_arg = &dev->regmap_mutex; dev->regmap[i] = devm_regmap_init_spi(spi, &rc); if (IS_ERR(dev->regmap[i])) { ret = PTR_ERR(dev->regmap[i]); dev_err(&spi->dev, "Failed to initialize regmap%i: %d\n", - ksz8795_regmap_config[i].val_bits, ret); + regmap_config[i].val_bits, ret); return ret; } } @@ -85,9 +103,11 @@ static void ksz8795_spi_shutdown(struct spi_device *spi) } static const struct of_device_id ksz8795_dt_ids[] = { - { .compatible = "microchip,ksz8765" }, - { .compatible = "microchip,ksz8794" }, - { .compatible = "microchip,ksz8795" }, + { .compatible = "microchip,ksz8765", .data = &ksz8795_regmap_config }, + { .compatible = "microchip,ksz8794", .data = &ksz8795_regmap_config }, + { .compatible = "microchip,ksz8795", .data = &ksz8795_regmap_config }, + { .compatible = "microchip,ksz8863", .data = &ksz8863_regmap_config }, + { .compatible = "microchip,ksz8873", .data = &ksz8863_regmap_config }, {}, }; MODULE_DEVICE_TABLE(of, ksz8795_dt_ids); From patchwork Fri Apr 23 08:02:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70F25C43460 for ; Fri, 23 Apr 2021 08:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2FDF2611C2 for ; Fri, 23 Apr 2021 08:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241376AbhDWIDK (ORCPT ); Fri, 23 Apr 2021 04:03:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241184AbhDWIDF (ORCPT ); Fri, 23 Apr 2021 04:03:05 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8411C061574 for ; Fri, 23 Apr 2021 01:02:29 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007as-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlY-0006w4-0E; Fri, 23 Apr 2021 10:02:20 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Michael Grzeschik , Oleksij Rempel , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 08/10] net: dsa: microchip: Add Microchip KSZ8863 SMI based driver support Date: Fri, 23 Apr 2021 10:02:16 +0200 Message-Id: <20210423080218.26526-9-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Grzeschik Add KSZ88X3 driver support. We add support for the KXZ88X3 three port switches using the Microchip SMI Interface. They are supported using the MDIO-Bitbang Interface. Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel --- v1 -> v2: - this code was part of previuos patch v2 -> v3: - this code was part of previuos patch v3 -> v4: - moved this glue code so separate patch - fixed locking in regmap and mdio_read/mdio_write v4 -> v5: - removed extra default y in Kconfig - fixed capitalization in Kconfig description - removed unnecessary cast - added back the define for READ operation - added KSZ88x3 to help text for KSZ8795 Kconfig entry --- drivers/net/dsa/microchip/Kconfig | 10 +- drivers/net/dsa/microchip/Makefile | 1 + drivers/net/dsa/microchip/ksz8863_smi.c | 206 ++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 drivers/net/dsa/microchip/ksz8863_smi.c diff --git a/drivers/net/dsa/microchip/Kconfig b/drivers/net/dsa/microchip/Kconfig index 4ec6a47b7f72..c9e2a8989556 100644 --- a/drivers/net/dsa/microchip/Kconfig +++ b/drivers/net/dsa/microchip/Kconfig @@ -29,7 +29,7 @@ menuconfig NET_DSA_MICROCHIP_KSZ8795 depends on NET_DSA select NET_DSA_MICROCHIP_KSZ_COMMON help - This driver adds support for Microchip KSZ8795 switch chips. + This driver adds support for Microchip KSZ8795/KSZ88X3 switch chips. config NET_DSA_MICROCHIP_KSZ8795_SPI tristate "KSZ8795 series SPI connected switch driver" @@ -40,3 +40,11 @@ config NET_DSA_MICROCHIP_KSZ8795_SPI It is required to use the KSZ8795 switch driver as the only access is through SPI. + +config NET_DSA_MICROCHIP_KSZ8863_SMI + tristate "KSZ series SMI connected switch driver" + depends on NET_DSA_MICROCHIP_KSZ8795 + select MDIO_BITBANG + help + Select to enable support for registering switches configured through + Microchip SMI. It supports the KSZ8863 and KSZ8873 switch. diff --git a/drivers/net/dsa/microchip/Makefile b/drivers/net/dsa/microchip/Makefile index 929caa81e782..2a03b21a3386 100644 --- a/drivers/net/dsa/microchip/Makefile +++ b/drivers/net/dsa/microchip/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C) += ksz9477_i2c.o obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI) += ksz9477_spi.o obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8795) += ksz8795.o obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI) += ksz8795_spi.o +obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI) += ksz8863_smi.o diff --git a/drivers/net/dsa/microchip/ksz8863_smi.c b/drivers/net/dsa/microchip/ksz8863_smi.c new file mode 100644 index 000000000000..c5400b96571b --- /dev/null +++ b/drivers/net/dsa/microchip/ksz8863_smi.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Microchip KSZ8863 series register access through SMI + * + * Copyright (C) 2019 Pengutronix, Michael Grzeschik + */ + +#include "ksz8.h" +#include "ksz_common.h" + +/* Serial Management Interface (SMI) uses the following frame format: + * + * preamble|start|Read/Write| PHY | REG |TA| Data bits | Idle + * |frame| OP code |address |address| | | + * read | 32x1´s | 01 | 00 | 1xRRR | RRRRR |Z0| 00000000DDDDDDDD | Z + * write| 32x1´s | 01 | 00 | 0xRRR | RRRRR |10| xxxxxxxxDDDDDDDD | Z + * + */ + +#define SMI_KSZ88XX_READ_PHY BIT(4) + +static int ksz8863_mdio_read(void *ctx, const void *reg_buf, size_t reg_len, + void *val_buf, size_t val_len) +{ + struct ksz_device *dev = ctx; + struct ksz8 *ksz8 = dev->priv; + struct mdio_device *mdev = ksz8->priv; + u8 reg = *(u8 *)reg_buf; + u8 *val = val_buf; + int ret = 0; + int i; + + mutex_lock_nested(&mdev->bus->mdio_lock, MDIO_MUTEX_NESTED); + for (i = 0; i < val_len; i++) { + int tmp = reg + i; + + ret = __mdiobus_read(mdev->bus, ((tmp & 0xE0) >> 5) | + SMI_KSZ88XX_READ_PHY, tmp); + if (ret < 0) + goto out; + + val[i] = ret; + } + ret = 0; + + out: + mutex_unlock(&mdev->bus->mdio_lock); + + return ret; +} + +static int ksz8863_mdio_write(void *ctx, const void *data, size_t count) +{ + struct ksz_device *dev = ctx; + struct ksz8 *ksz8 = dev->priv; + struct mdio_device *mdev = ksz8->priv; + u8 *val = (u8 *)(data + 4); + u32 reg = *(u32 *)data; + int ret = 0; + int i; + + mutex_lock_nested(&mdev->bus->mdio_lock, MDIO_MUTEX_NESTED); + for (i = 0; i < (count - 4); i++) { + int tmp = reg + i; + + ret = __mdiobus_write(mdev->bus, ((tmp & 0xE0) >> 5), + tmp, val[i]); + if (ret < 0) + goto out; + } + + out: + mutex_unlock(&mdev->bus->mdio_lock); + + return ret; +} + +static const struct regmap_bus regmap_smi[] = { + { + .read = ksz8863_mdio_read, + .write = ksz8863_mdio_write, + .max_raw_read = 1, + .max_raw_write = 1, + }, + { + .read = ksz8863_mdio_read, + .write = ksz8863_mdio_write, + .val_format_endian_default = REGMAP_ENDIAN_BIG, + .max_raw_read = 2, + .max_raw_write = 2, + }, + { + .read = ksz8863_mdio_read, + .write = ksz8863_mdio_write, + .val_format_endian_default = REGMAP_ENDIAN_BIG, + .max_raw_read = 4, + .max_raw_write = 4, + } +}; + +static const struct regmap_config ksz8863_regmap_config[] = { + { + .name = "#8", + .reg_bits = 8, + .pad_bits = 24, + .val_bits = 8, + .cache_type = REGCACHE_NONE, + .use_single_read = 1, + .lock = ksz_regmap_lock, + .unlock = ksz_regmap_unlock, + }, + { + .name = "#16", + .reg_bits = 8, + .pad_bits = 24, + .val_bits = 16, + .cache_type = REGCACHE_NONE, + .use_single_read = 1, + .lock = ksz_regmap_lock, + .unlock = ksz_regmap_unlock, + }, + { + .name = "#32", + .reg_bits = 8, + .pad_bits = 24, + .val_bits = 32, + .cache_type = REGCACHE_NONE, + .use_single_read = 1, + .lock = ksz_regmap_lock, + .unlock = ksz_regmap_unlock, + } +}; + +static int ksz8863_smi_probe(struct mdio_device *mdiodev) +{ + struct regmap_config rc; + struct ksz_device *dev; + struct ksz8 *ksz8; + int ret; + int i; + + ksz8 = devm_kzalloc(&mdiodev->dev, sizeof(struct ksz8), GFP_KERNEL); + ksz8->priv = mdiodev; + + dev = ksz_switch_alloc(&mdiodev->dev, ksz8); + if (!dev) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ksz8863_regmap_config); i++) { + rc = ksz8863_regmap_config[i]; + rc.lock_arg = &dev->regmap_mutex; + dev->regmap[i] = devm_regmap_init(&mdiodev->dev, + ®map_smi[i], dev, + &rc); + if (IS_ERR(dev->regmap[i])) { + ret = PTR_ERR(dev->regmap[i]); + dev_err(&mdiodev->dev, + "Failed to initialize regmap%i: %d\n", + ksz8863_regmap_config[i].val_bits, ret); + return ret; + } + } + + if (mdiodev->dev.platform_data) + dev->pdata = mdiodev->dev.platform_data; + + ret = ksz8_switch_register(dev); + + /* Main DSA driver may not be started yet. */ + if (ret) + return ret; + + dev_set_drvdata(&mdiodev->dev, dev); + + return 0; +} + +static void ksz8863_smi_remove(struct mdio_device *mdiodev) +{ + struct ksz_device *dev = dev_get_drvdata(&mdiodev->dev); + + if (dev) + ksz_switch_remove(dev); +} + +static const struct of_device_id ksz8863_dt_ids[] = { + { .compatible = "microchip,ksz8863" }, + { .compatible = "microchip,ksz8873" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ksz8863_dt_ids); + +static struct mdio_driver ksz8863_driver = { + .probe = ksz8863_smi_probe, + .remove = ksz8863_smi_remove, + .mdiodrv.driver = { + .name = "ksz8863-switch", + .of_match_table = ksz8863_dt_ids, + }, +}; + +mdio_module_driver(ksz8863_driver); + +MODULE_AUTHOR("Michael Grzeschik "); +MODULE_DESCRIPTION("Microchip KSZ8863 SMI Switch driver"); +MODULE_LICENSE("GPL v2"); From patchwork Fri Apr 23 08:02:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 426701 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4F63C433ED for ; Fri, 23 Apr 2021 08:02:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 985346120F for ; Fri, 23 Apr 2021 08:02:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241603AbhDWIDa (ORCPT ); Fri, 23 Apr 2021 04:03:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241147AbhDWIDI (ORCPT ); Fri, 23 Apr 2021 04:03:08 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0530C06138E for ; Fri, 23 Apr 2021 01:02:31 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lZqlZ-0007at-C9; Fri, 23 Apr 2021 10:02:21 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1lZqlY-0006wD-1E; Fri, 23 Apr 2021 10:02:20 +0200 From: Oleksij Rempel To: Woojung Huh , UNGLinuxDriver@microchip.com, Andrew Lunn , Florian Fainelli , Vivien Didelot , Vladimir Oltean , "David S. Miller" , Jakub Kicinski Cc: Michael Grzeschik , devicetree@vger.kernel.org, Rob Herring , Oleksij Rempel , kernel@pengutronix.de, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Russell King Subject: [PATCH net-next v6 09/10] dt-bindings: net: mdio-gpio: add compatible for microchip, mdio-smi0 Date: Fri, 23 Apr 2021 10:02:17 +0200 Message-Id: <20210423080218.26526-10-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210423080218.26526-1-o.rempel@pengutronix.de> References: <20210423080218.26526-1-o.rempel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Grzeschik Microchip SMI0 Mode is a special mode, where the MDIO Read/Write commands are part of the PHY Address and the OP Code is always 0. We add the compatible for this special mode of the bitbanged mdio driver. Cc: devicetree@vger.kernel.org Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Acked-by: Rob Herring Signed-off-by: Michael Grzeschik Signed-off-by: Oleksij Rempel --- v1 -> v2: - patch not present v2 -> v3: - first patch v3 -> v4: - no changes --- Documentation/devicetree/bindings/net/mdio-gpio.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt index 8dbcf8295c6c..4d91a36c5cf5 100644 --- a/Documentation/devicetree/bindings/net/mdio-gpio.txt +++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt @@ -2,6 +2,7 @@ MDIO on GPIOs Currently defined compatibles: - virtual,gpio-mdio +- microchip,mdio-smi0 MDC and MDIO lines connected to GPIO controllers are listed in the gpios property as described in section VIII.1 in the following order: