ocelot.c (68bb4665a2ce1338a74867e71bd5182f5b214a91) | ocelot.c (75e5a554c87fd48f67d1674cfd34e47e3b454fb3) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/if_bridge.h> 8#include <soc/mscc/ocelot_vcap.h> --- 185 unchanged lines hidden (view full) --- 194 } 195 ocelot_rmw_gix(ocelot, val, 196 REW_TAG_CFG_TAG_CFG_M, 197 REW_TAG_CFG, port); 198 199 return 0; 200} 201 | 1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/if_bridge.h> 8#include <soc/mscc/ocelot_vcap.h> --- 185 unchanged lines hidden (view full) --- 194 } 195 ocelot_rmw_gix(ocelot, val, 196 REW_TAG_CFG_TAG_CFG_M, 197 REW_TAG_CFG, port); 198 199 return 0; 200} 201 |
202/* Default vlan to clasify for untagged frames (may be zero) */ 203static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid) 204{ 205 struct ocelot_port *ocelot_port = ocelot->ports[port]; 206 207 ocelot_port->pvid = pvid; 208 209 if (!ocelot_port->vlan_aware) 210 pvid = 0; 211 212 ocelot_rmw_gix(ocelot, 213 ANA_PORT_VLAN_CFG_VLAN_VID(pvid), 214 ANA_PORT_VLAN_CFG_VLAN_VID_M, 215 ANA_PORT_VLAN_CFG, port); 216} 217 |
|
202int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 203 bool vlan_aware, struct switchdev_trans *trans) 204{ 205 struct ocelot_port *ocelot_port = ocelot->ports[port]; 206 u32 val; 207 208 if (switchdev_trans_ph_prepare(trans)) { 209 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; --- 18 unchanged lines hidden (view full) --- 228 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1); 229 else 230 val = 0; 231 ocelot_rmw_gix(ocelot, val, 232 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | 233 ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M, 234 ANA_PORT_VLAN_CFG, port); 235 | 218int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 219 bool vlan_aware, struct switchdev_trans *trans) 220{ 221 struct ocelot_port *ocelot_port = ocelot->ports[port]; 222 u32 val; 223 224 if (switchdev_trans_ph_prepare(trans)) { 225 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; --- 18 unchanged lines hidden (view full) --- 244 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1); 245 else 246 val = 0; 247 ocelot_rmw_gix(ocelot, val, 248 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | 249 ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M, 250 ANA_PORT_VLAN_CFG, port); 251 |
252 ocelot_port_set_pvid(ocelot, port, ocelot_port->pvid); |
|
236 ocelot_port_set_native_vlan(ocelot, port, ocelot_port->vid); 237 238 return 0; 239} 240EXPORT_SYMBOL(ocelot_port_vlan_filtering); 241 | 253 ocelot_port_set_native_vlan(ocelot, port, ocelot_port->vid); 254 255 return 0; 256} 257EXPORT_SYMBOL(ocelot_port_vlan_filtering); 258 |
242/* Default vlan to clasify for untagged frames (may be zero) */ 243static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid) 244{ 245 struct ocelot_port *ocelot_port = ocelot->ports[port]; 246 247 ocelot_rmw_gix(ocelot, 248 ANA_PORT_VLAN_CFG_VLAN_VID(pvid), 249 ANA_PORT_VLAN_CFG_VLAN_VID_M, 250 ANA_PORT_VLAN_CFG, port); 251 252 ocelot_port->pvid = pvid; 253} 254 | |
255int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, 256 bool untagged) 257{ 258 int ret; 259 260 /* Make the port a member of the VLAN */ 261 ocelot->vlan_mask[vid] |= BIT(port); 262 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]); --- 274 unchanged lines hidden (view full) --- 537 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); 538 } 539} 540EXPORT_SYMBOL(ocelot_get_txtstamp); 541 542int ocelot_fdb_add(struct ocelot *ocelot, int port, 543 const unsigned char *addr, u16 vid) 544{ | 259int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, 260 bool untagged) 261{ 262 int ret; 263 264 /* Make the port a member of the VLAN */ 265 ocelot->vlan_mask[vid] |= BIT(port); 266 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]); --- 274 unchanged lines hidden (view full) --- 541 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); 542 } 543} 544EXPORT_SYMBOL(ocelot_get_txtstamp); 545 546int ocelot_fdb_add(struct ocelot *ocelot, int port, 547 const unsigned char *addr, u16 vid) 548{ |
545 struct ocelot_port *ocelot_port = ocelot->ports[port]; | |
546 int pgid = port; 547 548 if (port == ocelot->npi) 549 pgid = PGID_CPU; 550 | 549 int pgid = port; 550 551 if (port == ocelot->npi) 552 pgid = PGID_CPU; 553 |
551 if (!vid) { 552 if (!ocelot_port->vlan_aware) 553 /* If the bridge is not VLAN aware and no VID was 554 * provided, set it to pvid to ensure the MAC entry 555 * matches incoming untagged packets 556 */ 557 vid = ocelot_port->pvid; 558 else 559 /* If the bridge is VLAN aware a VID must be provided as 560 * otherwise the learnt entry wouldn't match any frame. 561 */ 562 return -EINVAL; 563 } 564 | |
565 return ocelot_mact_learn(ocelot, pgid, addr, vid, ENTRYTYPE_LOCKED); 566} 567EXPORT_SYMBOL(ocelot_fdb_add); 568 569int ocelot_fdb_del(struct ocelot *ocelot, int port, 570 const unsigned char *addr, u16 vid) 571{ 572 return ocelot_mact_forget(ocelot, addr, vid); --- 470 unchanged lines hidden (view full) --- 1043 addr[0] = mc->ports >> 8; 1044 addr[1] = mc->ports & 0xff; 1045 } 1046} 1047 1048int ocelot_port_mdb_add(struct ocelot *ocelot, int port, 1049 const struct switchdev_obj_port_mdb *mdb) 1050{ | 554 return ocelot_mact_learn(ocelot, pgid, addr, vid, ENTRYTYPE_LOCKED); 555} 556EXPORT_SYMBOL(ocelot_fdb_add); 557 558int ocelot_fdb_del(struct ocelot *ocelot, int port, 559 const unsigned char *addr, u16 vid) 560{ 561 return ocelot_mact_forget(ocelot, addr, vid); --- 470 unchanged lines hidden (view full) --- 1032 addr[0] = mc->ports >> 8; 1033 addr[1] = mc->ports & 0xff; 1034 } 1035} 1036 1037int ocelot_port_mdb_add(struct ocelot *ocelot, int port, 1038 const struct switchdev_obj_port_mdb *mdb) 1039{ |
1051 struct ocelot_port *ocelot_port = ocelot->ports[port]; | |
1052 unsigned char addr[ETH_ALEN]; 1053 struct ocelot_multicast *mc; 1054 struct ocelot_pgid *pgid; 1055 u16 vid = mdb->vid; 1056 1057 if (port == ocelot->npi) 1058 port = ocelot->num_phys_ports; 1059 | 1040 unsigned char addr[ETH_ALEN]; 1041 struct ocelot_multicast *mc; 1042 struct ocelot_pgid *pgid; 1043 u16 vid = mdb->vid; 1044 1045 if (port == ocelot->npi) 1046 port = ocelot->num_phys_ports; 1047 |
1060 if (!vid) 1061 vid = ocelot_port->pvid; 1062 | |
1063 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); 1064 if (!mc) { 1065 /* New entry */ 1066 mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL); 1067 if (!mc) 1068 return -ENOMEM; 1069 1070 mc->entry_type = ocelot_classify_mdb(mdb->addr); --- 32 unchanged lines hidden (view full) --- 1103 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, 1104 mc->entry_type); 1105} 1106EXPORT_SYMBOL(ocelot_port_mdb_add); 1107 1108int ocelot_port_mdb_del(struct ocelot *ocelot, int port, 1109 const struct switchdev_obj_port_mdb *mdb) 1110{ | 1048 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); 1049 if (!mc) { 1050 /* New entry */ 1051 mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL); 1052 if (!mc) 1053 return -ENOMEM; 1054 1055 mc->entry_type = ocelot_classify_mdb(mdb->addr); --- 32 unchanged lines hidden (view full) --- 1088 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, 1089 mc->entry_type); 1090} 1091EXPORT_SYMBOL(ocelot_port_mdb_add); 1092 1093int ocelot_port_mdb_del(struct ocelot *ocelot, int port, 1094 const struct switchdev_obj_port_mdb *mdb) 1095{ |
1111 struct ocelot_port *ocelot_port = ocelot->ports[port]; | |
1112 unsigned char addr[ETH_ALEN]; 1113 struct ocelot_multicast *mc; 1114 struct ocelot_pgid *pgid; 1115 u16 vid = mdb->vid; 1116 1117 if (port == ocelot->npi) 1118 port = ocelot->num_phys_ports; 1119 | 1096 unsigned char addr[ETH_ALEN]; 1097 struct ocelot_multicast *mc; 1098 struct ocelot_pgid *pgid; 1099 u16 vid = mdb->vid; 1100 1101 if (port == ocelot->npi) 1102 port = ocelot->num_phys_ports; 1103 |
1120 if (!vid) 1121 vid = ocelot_port->pvid; 1122 | |
1123 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); 1124 if (!mc) 1125 return -ENOENT; 1126 1127 ocelot_encode_ports_to_mdb(addr, mc); 1128 ocelot_mact_forget(ocelot, addr, vid); 1129 1130 ocelot_pgid_free(ocelot, mc->pgid); --- 496 unchanged lines hidden --- | 1104 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); 1105 if (!mc) 1106 return -ENOENT; 1107 1108 ocelot_encode_ports_to_mdb(addr, mc); 1109 ocelot_mact_forget(ocelot, addr, vid); 1110 1111 ocelot_pgid_free(ocelot, mc->pgid); --- 496 unchanged lines hidden --- |