diff options
author | John Crispin <john@phrozen.org> | 2019-08-28 15:20:22 +0200 |
---|---|---|
committer | John Crispin <john@phrozen.org> | 2019-08-28 15:20:22 +0200 |
commit | 4685fc0cf161f40cac638b11a03b4c2761416a22 (patch) | |
tree | 7c40e7bc9c4937ecb179cc60f98c9ef9fbc78bba /target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c | |
parent | 5cc942a80eff3b41df164d5e875befa4fc12b183 (diff) | |
download | upstream-4685fc0cf161f40cac638b11a03b4c2761416a22.tar.gz upstream-4685fc0cf161f40cac638b11a03b4c2761416a22.tar.bz2 upstream-4685fc0cf161f40cac638b11a03b4c2761416a22.zip |
mediatek: update v4.19 switch support to latest vendor version
Signed-off-by: John Crispin <john@phrozen.org>
Diffstat (limited to 'target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c')
-rw-r--r-- | target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c | 195 |
1 files changed, 5 insertions, 190 deletions
diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c index fb2ee1c1b7..b601b90fb1 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * OpenWrt swconfig support for MediaTek MT753x Gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao <weijie.gao@mediatek.com> - * - * SPDX-License-Identifier: GPL-2.0+ */ #include <linux/if.h> @@ -93,64 +89,6 @@ enum { MT753X_ATTR_ENABLE_VLAN, }; -struct mt753x_mapping { - char *name; - u16 pvids[MT753X_NUM_PORTS]; - u8 members[MT753X_NUM_VLANS]; - u8 etags[MT753X_NUM_VLANS]; - u16 vids[MT753X_NUM_VLANS]; -} mt753x_defaults[] = { - { - .name = "llllw", - .pvids = { 1, 1, 1, 1, 2, 2, 1 }, - .members = { 0, 0x4f, 0x30 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, { - .name = "wllll", - .pvids = { 2, 1, 1, 1, 1, 2, 1 }, - .members = { 0, 0x5e, 0x21 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, { - .name = "lwlll", - .pvids = { 1, 2, 1, 1, 1, 2, 1 }, - .members = { 0, 0x5d, 0x22 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, -}; - -struct mt753x_mapping *mt753x_find_mapping(struct device_node *np) -{ - const char *map; - int i; - - if (of_property_read_string(np, "mediatek,portmap", &map)) - return NULL; - - for (i = 0; i < ARRAY_SIZE(mt753x_defaults); i++) - if (!strcmp(map, mt753x_defaults[i].name)) - return &mt753x_defaults[i]; - - return NULL; -} - -static void mt753x_apply_mapping(struct gsw_mt753x *gsw, - struct mt753x_mapping *map) -{ - int i = 0; - - for (i = 0; i < MT753X_NUM_PORTS; i++) - gsw->port_entries[i].pvid = map->pvids[i]; - - for (i = 0; i < MT753X_NUM_VLANS; i++) { - gsw->vlan_entries[i].member = map->members[i]; - gsw->vlan_entries[i].etags = map->etags[i]; - gsw->vlan_entries[i].vid = map->vids[i]; - } -} - static int mt753x_get_vlan_enable(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -201,27 +139,6 @@ static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid) return 0; } -static void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val) -{ - int i; - - mt753x_reg_write(gsw, VTCR, - VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) | - (val & VTCR_VID_M)); - - for (i = 0; i < 300; i++) { - u32 val = mt753x_reg_read(gsw, VTCR); - - if ((val & VTCR_BUSY) == 0) - break; - - usleep_range(1000, 1100); - } - - if (i == 300) - dev_info(gsw->dev, "vtcr timeout\n"); -} - static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) { struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); @@ -447,114 +364,16 @@ static void mt753x_port_isolation(struct gsw_mt753x *gsw) (VA_TRANSPARENT_PORT << VLAN_ATTR_S)); } -static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid, - u8 ports, u8 etags) -{ - int port; - u32 val; - - /* vlan port membership */ - if (ports) - mt753x_reg_write(gsw, VAWD1, - IVL_MAC | VTAG_EN | VENTRY_VALID | - ((ports << PORT_MEM_S) & PORT_MEM_M)); - else - mt753x_reg_write(gsw, VAWD1, 0); - - /* egress mode */ - val = 0; - for (port = 0; port < MT753X_NUM_PORTS; port++) { - if (etags & BIT(port)) - val |= ETAG_CTRL_TAG << PORT_ETAG_S(port); - else - val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port); - } - mt753x_reg_write(gsw, VAWD2, val); - - /* write to vlan table */ - mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid); -} - static int mt753x_apply_config(struct switch_dev *dev) { struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); - int i, j; - u8 tag_ports; - u8 untag_ports; if (!gsw->global_vlan_enable) { mt753x_port_isolation(gsw); return 0; } - /* set all ports as security mode */ - for (i = 0; i < MT753X_NUM_PORTS; i++) - mt753x_reg_write(gsw, PCR(i), - PORT_MATRIX_M | SECURITY_MODE); - - /* check if a port is used in tag/untag vlan egress mode */ - tag_ports = 0; - untag_ports = 0; - - for (i = 0; i < MT753X_NUM_VLANS; i++) { - u8 member = gsw->vlan_entries[i].member; - u8 etags = gsw->vlan_entries[i].etags; - - if (!member) - continue; - - for (j = 0; j < MT753X_NUM_PORTS; j++) { - if (!(member & BIT(j))) - continue; - - if (etags & BIT(j)) - tag_ports |= 1u << j; - else - untag_ports |= 1u << j; - } - } - - /* set all untag-only ports as transparent and the rest as user port */ - for (i = 0; i < MT753X_NUM_PORTS; i++) { - u32 pvc_mode = 0x8100 << STAG_VPID_S; - - if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) - pvc_mode = (0x8100 << STAG_VPID_S) | - (VA_TRANSPARENT_PORT << VLAN_ATTR_S); - - mt753x_reg_write(gsw, PVC(i), pvc_mode); - } - - /* first clear the swtich vlan table */ - for (i = 0; i < MT753X_NUM_VLANS; i++) - mt753x_write_vlan_entry(gsw, i, i, 0, 0); - - /* now program only vlans with members to avoid - * clobbering remapped entries in later iterations - */ - for (i = 0; i < MT753X_NUM_VLANS; i++) { - u16 vid = gsw->vlan_entries[i].vid; - u8 member = gsw->vlan_entries[i].member; - u8 etags = gsw->vlan_entries[i].etags; - - if (member) - mt753x_write_vlan_entry(gsw, i, vid, member, etags); - } - - /* Port Default PVID */ - for (i = 0; i < MT753X_NUM_PORTS; i++) { - int vlan = gsw->port_entries[i].pvid; - u16 pvid = 0; - u32 val; - - if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member) - pvid = gsw->vlan_entries[vlan].vid; - - val = mt753x_reg_read(gsw, PPBV1(i)); - val &= ~GRP_PORT_VID_M; - val |= pvid; - mt753x_reg_write(gsw, PPBV1(i), val); - } + mt753x_apply_vlan_config(gsw); return 0; } @@ -659,7 +478,6 @@ int mt753x_swconfig_init(struct gsw_mt753x *gsw) { struct device_node *np = gsw->dev->of_node; struct switch_dev *swdev; - struct mt753x_mapping *map; int ret; if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port)) @@ -676,14 +494,11 @@ int mt753x_swconfig_init(struct gsw_mt753x *gsw) ret = register_switch(swdev, NULL); if (ret) { - dev_err(gsw->dev, "Failed to register switch %s\n", - swdev->name); + dev_notice(gsw->dev, "Failed to register switch %s\n", + swdev->name); return ret; } - map = mt753x_find_mapping(gsw->dev->of_node); - if (map) - mt753x_apply_mapping(gsw, map); mt753x_apply_config(swdev); return 0; |