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 ---