From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:15
VSC9959 hardware supports Per-Stream Filtering and Policing(PSFP).
This patch series add PSFP support on tc flower offload of ocelot
driver. Use chain 30000 to distinguish PSFP from VCAP blocks. Add gate
and police set to support PSFP in VSC9959 driver.
v3->v4 changes:
- Introduce vsc9959_psfp_sfi_table_get() function in patch where it is
used to fix compile warning.
- Store MAC entry type before FRER set, and recover it after FRER
disabled.
v2->v3 changes:
- Reorder first two patches. Export struct ocelot_mact_entry, then add
ocelot_mact_lookup() and ocelot_mact_write() functions.
- Add PSFP list to struct ocelot, and init it by using
ocelot->ops->psfp_init().
v1->v2 changes:
- Use tc flower offload of ocelot driver to support PSFP add and delete.
- Add PSFP tables add/del functions in felix_vsc9959.c.
- Use list_for_each_entry to simplify the code.
Vladimir Oltean (2):
net: mscc: ocelot: export struct ocelot_mact_entry
net: mscc: ocelot: add MAC table write and lookup operations
Xiaoliang Yang (6):
net: mscc: ocelot: set vcap IS2 chain to goto PSFP chain
net: mscc: ocelot: add gate and police action offload to PSFP
net: dsa: felix: support psfp filter on vsc9959
net: dsa: felix: add stream gate settings for psfp
net: mscc: ocelot: use index to set vcap policer
net: dsa: felix: use vcap policer to set flow meter for psfp
drivers/net/dsa/ocelot/felix.c | 2 +
drivers/net/dsa/ocelot/felix.h | 2 +
drivers/net/dsa/ocelot/felix_vsc9959.c | 697 ++++++++++++++++++++-
drivers/net/ethernet/mscc/ocelot.c | 56 +-
drivers/net/ethernet/mscc/ocelot.h | 13 -
drivers/net/ethernet/mscc/ocelot_flower.c | 74 ++-
drivers/net/ethernet/mscc/ocelot_vcap.c | 103 +--
drivers/net/ethernet/mscc/ocelot_vsc7514.c | 7 +
include/soc/mscc/ocelot.h | 49 +-
include/soc/mscc/ocelot_ana.h | 10 +
include/soc/mscc/ocelot_vcap.h | 1 +
11 files changed, 942 insertions(+), 72 deletions(-)
--
2.17.1
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:18
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Felix DSA needs to use this struct to export MAC table write and lookup
operations as well, for its stream identification functions, so export
them in preparation of that.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/ethernet/mscc/ocelot.c | 6 ------
drivers/net/ethernet/mscc/ocelot.h | 13 -------------
include/soc/mscc/ocelot.h | 19 +++++++++++++++++++
3 files changed, 19 insertions(+), 19 deletions(-)
@@ -54,19 +54,6 @@ struct ocelot_dump_ctx {intidx;};-/* MAC table entry types.-*ENTRYTYPE_NORMALissubjecttoaging.-*ENTRYTYPE_LOCKEDisnotsubjecttoaging.-*ENTRYTYPE_MACv4isnotsubjecttoaging.ForIPv4multicast.-*ENTRYTYPE_MACv6isnotsubjecttoaging.ForIPv6multicast.-*/-enummacaccess_entry_type{-ENTRYTYPE_NORMAL=0,-ENTRYTYPE_LOCKED,-ENTRYTYPE_MACv4,-ENTRYTYPE_MACv6,-};-/* A (PGID) port mask structure, encoding the 2^ocelot->num_phys_ports*possibilitiesofegressportmasksforL2multicasttraffic.*Foraswitchwith9userports,thereare512possibleportmasks,butthe
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:20
From: Vladimir Oltean <vladimir.oltean@nxp.com>
ocelot_mact_write() can be used for directly modifying an FDB entry
situated at a given row and column, as opposed to the current
ocelot_mact_learn() which calculates the row and column indices
automatically (based on a 11-bit hash derived from the {DMAC, VID} key).
ocelot_mact_lookup() can be used to retrieve the row and column at which
an FDB entry with the given {DMAC, VID} key is found.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/ethernet/mscc/ocelot.c | 47 ++++++++++++++++++++++++++++++
include/soc/mscc/ocelot.h | 6 ++++
2 files changed, 53 insertions(+)
@@ -96,6 +96,53 @@ int ocelot_mact_forget(struct ocelot *ocelot,}EXPORT_SYMBOL(ocelot_mact_forget);+intocelot_mact_lookup(structocelot*ocelot,constunsignedcharmac[ETH_ALEN],+unsignedintvid,int*row,int*col)+{+intval;++ocelot_mact_select(ocelot,mac,vid);++/* Issue a read command with MACACCESS_VALID=1. */+ocelot_write(ocelot,ANA_TABLES_MACACCESS_VALID|+ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),+ANA_TABLES_MACACCESS);++if(ocelot_mact_wait_for_completion(ocelot))+return-ETIMEDOUT;++/* Read back the entry flags */+val=ocelot_read(ocelot,ANA_TABLES_MACACCESS);+if(!(val&ANA_TABLES_MACACCESS_VALID))+return-ENOENT;++ocelot_field_read(ocelot,ANA_TABLES_MACTINDX_M_INDEX,row);+ocelot_field_read(ocelot,ANA_TABLES_MACTINDX_BUCKET,col);++return0;+}+EXPORT_SYMBOL(ocelot_mact_lookup);++/* Like ocelot_mact_learn, except at a specific row and col. */+voidocelot_mact_write(structocelot*ocelot,intport,+conststructocelot_mact_entry*entry,+introw,intcol)+{+ocelot_mact_select(ocelot,entry->mac,entry->vid);++ocelot_field_write(ocelot,ANA_TABLES_MACTINDX_M_INDEX,row);+ocelot_field_write(ocelot,ANA_TABLES_MACTINDX_BUCKET,col);++ocelot_write(ocelot,ANA_TABLES_MACACCESS_VALID|+ANA_TABLES_MACACCESS_ENTRYTYPE(entry->type)|+ANA_TABLES_MACACCESS_DEST_IDX(port)|+ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_WRITE),+ANA_TABLES_MACACCESS);++ocelot_mact_wait_for_completion(ocelot);+}+EXPORT_SYMBOL(ocelot_mact_write);+staticvoidocelot_mact_init(structocelot*ocelot){/* Configure the learning mode entries attributes:
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:30
Some chips in the ocelot series such as VSC9959 support Per-Stream
Filtering and Policing(PSFP), which is processing after VCAP blocks.
We set this block on chain 30000 and set vcap IS2 chain to goto PSFP
chain if hardware support.
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/ethernet/mscc/ocelot_flower.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:36
PSFP support gate and police action. This patch add the gate and police
action to flower parse action, check chain ID to determine which block
to offload. Adding psfp callback functions to add, delete and update gate
and police in PSFP table if hardware supports it.
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/ethernet/mscc/ocelot.c | 3 ++
drivers/net/ethernet/mscc/ocelot_flower.c | 52 ++++++++++++++++++++++-
include/soc/mscc/ocelot.h | 5 +++
include/soc/mscc/ocelot_vcap.h | 1 +
4 files changed, 59 insertions(+), 2 deletions(-)
@@ -220,10 +220,14 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,filter->type=OCELOT_VCAP_FILTER_OFFLOAD;break;caseFLOW_ACTION_POLICE:+if(filter->block_id==PSFP_BLOCK_ID){+filter->type=OCELOT_PSFP_FILTER_OFFLOAD;+break;+}if(filter->block_id!=VCAP_IS2||filter->lookup!=0){NL_SET_ERR_MSG_MOD(extack,-"Police action can only be offloaded to VCAP IS2 lookup 0");+"Police action can only be offloaded to VCAP IS2 lookup 0 or PSFP");return-EOPNOTSUPP;}if(filter->goto_target!=-1){
@@ -356,6 +360,14 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,filter->action.pcp_a_val=a->vlan.prio;filter->type=OCELOT_VCAP_FILTER_OFFLOAD;break;+caseFLOW_ACTION_GATE:+if(filter->block_id!=PSFP_BLOCK_ID){+NL_SET_ERR_MSG_MOD(extack,+"Gate action can only be offloaded to PSFP chain");+return-EOPNOTSUPP;+}+filter->type=OCELOT_PSFP_FILTER_OFFLOAD;+break;default:NL_SET_ERR_MSG_MOD(extack,"Cannot offload action");return-EOPNOTSUPP;
@@ -646,6 +658,10 @@ static int ocelot_flower_parse(struct ocelot *ocelot, int port, bool ingress,if(ret)returnret;+/* PSFP filter need to parse key by stream identification function. */+if(filter->type==OCELOT_PSFP_FILTER_OFFLOAD)+return0;+returnocelot_flower_parse_key(ocelot,port,ingress,f,filter);}
@@ -718,6 +734,15 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,if(filter->type==OCELOT_VCAP_FILTER_DUMMY)returnocelot_vcap_dummy_filter_add(ocelot,filter);+if(filter->type==OCELOT_PSFP_FILTER_OFFLOAD){+kfree(filter);+if(ocelot->ops->psfp_filter_add)+returnocelot->ops->psfp_filter_add(ocelot,f);++NL_SET_ERR_MSG_MOD(extack,"PSFP chain is not supported in HW");+return-EOPNOTSUPP;+}+returnocelot_vcap_filter_add(ocelot,filter,f->common.extack);}EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
@@ -733,6 +758,13 @@ int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,if(block_id<0)return0;+if(block_id==PSFP_BLOCK_ID){+if(ocelot->ops->psfp_filter_del)+returnocelot->ops->psfp_filter_del(ocelot,f);++return-EOPNOTSUPP;+}+block=&ocelot->block[block_id];filter=ocelot_vcap_block_find_filter_by_id(block,f->cookie,true);
@@ -751,12 +783,25 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,{structocelot_vcap_filter*filter;structocelot_vcap_block*block;+structflow_statsstats;intblock_id,ret;block_id=ocelot_chain_to_block(f->common.chain_index,ingress);if(block_id<0)return0;+if(block_id==PSFP_BLOCK_ID){+if(ocelot->ops->psfp_stats_get){+ret=ocelot->ops->psfp_stats_get(ocelot,f,&stats);+if(ret)+returnret;++gotostats_update;+}++return-EOPNOTSUPP;+}+block=&ocelot->block[block_id];filter=ocelot_vcap_block_find_filter_by_id(block,f->cookie,true);
@@ -767,7 +812,10 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,if(ret)returnret;-flow_stats_update(&f->stats,0x0,filter->stats.pkts,0,0x0,+stats.pkts=filter->stats.pkts;++stats_update:+flow_stats_update(&f->stats,0x0,stats.pkts,0,0x0,FLOW_ACTION_HW_STATS_IMMEDIATE);return0;}
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:40
VSC9959 supports Per-Stream Filtering and Policing(PSFP) that complies
with the IEEE 802.1Qci standard. The stream is identified by Null stream
identification(DMAC and VLAN ID) defined in IEEE802.1CB.
For PSFP, four tables need to be set up: stream table, stream filter
table, stream gate table, and flow meter table. Identify the stream by
parsing the tc flower keys and add it to the stream table. The stream
filter table is automatically maintained, and its index is determined by
SGID(flow gate index) and FMID(flow meter index).
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/dsa/ocelot/felix_vsc9959.c | 454 ++++++++++++++++++++++++-
include/soc/mscc/ocelot.h | 8 +
include/soc/mscc/ocelot_ana.h | 10 +
3 files changed, 462 insertions(+), 10 deletions(-)
@@ -1346,6 +1338,448 @@ static int vsc9959_port_setup_tc(struct dsa_switch *ds, int port,}}+#define VSC9959_PSFP_SFID_MAX 175+#define VSC9959_PSFP_GATE_ID_MAX 183+#define VSC9959_PSFP_POLICER_MAX 383++structfelix_stream{+structlist_headlist;+unsignedlongid;+u8dmac[ETH_ALEN];+u16vid;+s8prio;+u8sfid_valid;+u32sfid;+u8rsv_type;+};++structfelix_stream_filter{+structlist_headlist;+refcount_trefcount;+u32index;+u8enable;+u8sg_valid;+u32sgid;+u8fm_valid;+u32fmid;+u8prio_valid;+u8prio;+u32maxsdu;+};++structfelix_stream_filter_counters{+u32match;+u32not_pass_gate;+u32not_pass_sdu;+u32red;+};++staticintvsc9959_stream_identify(structflow_cls_offload*f,+structfelix_stream*stream)+{+structflow_rule*rule=flow_cls_offload_flow_rule(f);+structflow_dissector*dissector=rule->match.dissector;++if(dissector->used_keys&+~(BIT(FLOW_DISSECTOR_KEY_CONTROL)|+BIT(FLOW_DISSECTOR_KEY_BASIC)|+BIT(FLOW_DISSECTOR_KEY_VLAN)|+BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS)))+return-EOPNOTSUPP;++if(flow_rule_match_key(rule,FLOW_DISSECTOR_KEY_ETH_ADDRS)){+structflow_match_eth_addrsmatch;++flow_rule_match_eth_addrs(rule,&match);+ether_addr_copy(stream->dmac,match.key->dst);+if(!is_zero_ether_addr(match.mask->src))+return-EOPNOTSUPP;+}else{+return-EOPNOTSUPP;+}++if(flow_rule_match_key(rule,FLOW_DISSECTOR_KEY_VLAN)){+structflow_match_vlanmatch;++flow_rule_match_vlan(rule,&match);+if(match.mask->vlan_priority)+stream->prio=match.key->vlan_priority;+else+stream->prio=-1;++if(!match.mask->vlan_id)+return-EOPNOTSUPP;+stream->vid=match.key->vlan_id;+}else{+return-EOPNOTSUPP;+}++stream->id=f->cookie;++return0;+}++staticintvsc9959_mact_stream_set(structocelot*ocelot,+structfelix_stream*stream,+structnetlink_ext_ack*extack)+{+structocelot_mact_entryentry;+u32row,col,reg,dst_idx;+u8type;+intret;++/* Stream identification desn't support to add a stream with non+*existentMAC(TheMACentryhasnotbeenlearnedinMACtable).+*/+ret=ocelot_mact_lookup(ocelot,stream->dmac,stream->vid,&row,&col);+if(ret){+if(extack)+NL_SET_ERR_MSG_MOD(extack,"Stream is not learned in MAC table");+return-EOPNOTSUPP;+}++ocelot_rmw(ocelot,+(stream->sfid_valid?ANA_TABLES_STREAMDATA_SFID_VALID:0)|+ANA_TABLES_STREAMDATA_SFID(stream->sfid),+ANA_TABLES_STREAMDATA_SFID_VALID|+ANA_TABLES_STREAMDATA_SFID_M,+ANA_TABLES_STREAMDATA);++reg=ocelot_read(ocelot,ANA_TABLES_MACACCESS);+dst_idx=(reg&ANA_TABLES_MACACCESS_DEST_IDX_M)>>3;+type=ANA_TABLES_MACACCESS_ENTRYTYPE_X(reg);++reg=ocelot_read(ocelot,ANA_TABLES_STREAMDATA);+if((ANA_TABLES_STREAMDATA_SFID_VALID|+ANA_TABLES_STREAMDATA_SSID_VALID)®){+entry.type=(type?type:ENTRYTYPE_LOCKED);+stream->rsv_type=type;+}else{+entry.type=stream->rsv_type;+}++ether_addr_copy(entry.mac,stream->dmac);+entry.vid=stream->vid;++ocelot_mact_write(ocelot,dst_idx,&entry,row,col);++return0;+}++staticstructfelix_stream*+vsc9959_stream_table_lookup(structlist_head*stream_list,+structfelix_stream*stream)+{+structfelix_stream*tmp;++list_for_each_entry(tmp,stream_list,list)+if(ether_addr_equal(tmp->dmac,stream->dmac)&&+tmp->vid==stream->vid)+returntmp;++returnNULL;+}++staticintvsc9959_stream_table_add(structocelot*ocelot,+structlist_head*stream_list,+structfelix_stream*stream,+structnetlink_ext_ack*extack)+{+structfelix_stream*stream_entry;+intret;++stream_entry=kzalloc(sizeof(*stream_entry),GFP_KERNEL);+if(!stream_entry)+return-ENOMEM;++memcpy(stream_entry,stream,sizeof(*stream_entry));++ret=vsc9959_mact_stream_set(ocelot,stream_entry,extack);+if(ret){+kfree(stream_entry);+returnret;+}++list_add_tail(&stream_entry->list,stream_list);++return0;+}++staticstructfelix_stream*+vsc9959_stream_table_get(structlist_head*stream_list,unsignedlongid)+{+structfelix_stream*tmp;++list_for_each_entry(tmp,stream_list,list)+if(tmp->id==id)+returntmp;++returnNULL;+}++staticvoidvsc9959_stream_table_del(structocelot*ocelot,+structfelix_stream*stream)+{+vsc9959_mact_stream_set(ocelot,stream,NULL);++list_del(&stream->list);+kfree(stream);+}++staticu32vsc9959_sfi_access_status(structocelot*ocelot)+{+returnocelot_read(ocelot,ANA_TABLES_SFIDACCESS);+}++staticintvsc9959_psfp_sfi_set(structocelot*ocelot,+structfelix_stream_filter*sfi)+{+u32val;++if(sfi->index>VSC9959_PSFP_SFID_MAX)+return-EINVAL;++if(!sfi->enable){+ocelot_write(ocelot,ANA_TABLES_SFIDTIDX_SFID_INDEX(sfi->index),+ANA_TABLES_SFIDTIDX);++val=ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE);+ocelot_write(ocelot,val,ANA_TABLES_SFIDACCESS);++returnreadx_poll_timeout(vsc9959_sfi_access_status,ocelot,val,+(!ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(val)),+10,100000);+}++if(sfi->sgid>VSC9959_PSFP_GATE_ID_MAX||+sfi->fmid>VSC9959_PSFP_POLICER_MAX)+return-EINVAL;++ocelot_write(ocelot,+(sfi->sg_valid?ANA_TABLES_SFIDTIDX_SGID_VALID:0)|+ANA_TABLES_SFIDTIDX_SGID(sfi->sgid)|+(sfi->fm_valid?ANA_TABLES_SFIDTIDX_POL_ENA:0)|+ANA_TABLES_SFIDTIDX_POL_IDX(sfi->fmid)|+ANA_TABLES_SFIDTIDX_SFID_INDEX(sfi->index),+ANA_TABLES_SFIDTIDX);++ocelot_write(ocelot,+(sfi->prio_valid?ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA:0)|+ANA_TABLES_SFIDACCESS_IGR_PRIO(sfi->prio)|+ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(sfi->maxsdu)|+ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE),+ANA_TABLES_SFIDACCESS);++returnreadx_poll_timeout(vsc9959_sfi_access_status,ocelot,val,+(!ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(val)),+10,100000);+}++staticintvsc9959_psfp_sfi_table_add(structocelot*ocelot,+structfelix_stream_filter*sfi)+{+structfelix_stream_filter*sfi_entry,*tmp;+structlist_head*pos,*q,*last;+structocelot_psfp_list*psfp;+u32insert=0;+intret;++psfp=&ocelot->psfp;+last=&psfp->sfi_list;++list_for_each_safe(pos,q,&psfp->sfi_list){+tmp=list_entry(pos,structfelix_stream_filter,list);+if(sfi->sg_valid==tmp->sg_valid&&+sfi->fm_valid==tmp->fm_valid&&+tmp->sgid==sfi->sgid&&+tmp->fmid==sfi->fmid){+sfi->index=tmp->index;+refcount_inc(&tmp->refcount);+return0;+}+/* Make sure that the index is increasing in order. */+if(tmp->index==insert){+last=pos;+insert++;+}+}+sfi->index=insert;++sfi_entry=kzalloc(sizeof(*sfi_entry),GFP_KERNEL);+if(!sfi_entry)+return-ENOMEM;++memcpy(sfi_entry,sfi,sizeof(*sfi_entry));+refcount_set(&sfi_entry->refcount,1);++ret=vsc9959_psfp_sfi_set(ocelot,sfi_entry);+if(ret){+kfree(sfi_entry);+returnret;+}++list_add(&sfi_entry->list,last);++return0;+}++staticvoidvsc9959_psfp_sfi_table_del(structocelot*ocelot,u32index)+{+structfelix_stream_filter*tmp,*n;+structocelot_psfp_list*psfp;+u8z;++psfp=&ocelot->psfp;++list_for_each_entry_safe(tmp,n,&psfp->sfi_list,list)+if(tmp->index==index){+z=refcount_dec_and_test(&tmp->refcount);+if(z){+tmp->enable=0;+vsc9959_psfp_sfi_set(ocelot,tmp);+list_del(&tmp->list);+kfree(tmp);+}+break;+}+}++staticvoidvsc9959_psfp_counters_get(structocelot*ocelot,u32index,+structfelix_stream_filter_counters*counters)+{+ocelot_rmw(ocelot,SYS_STAT_CFG_STAT_VIEW(index),+SYS_STAT_CFG_STAT_VIEW_M,+SYS_STAT_CFG);++counters->match=ocelot_read_gix(ocelot,SYS_CNT,0x200);+counters->not_pass_gate=ocelot_read_gix(ocelot,SYS_CNT,0x201);+counters->not_pass_sdu=ocelot_read_gix(ocelot,SYS_CNT,0x202);+counters->red=ocelot_read_gix(ocelot,SYS_CNT,0x203);++/* Clear the PSFP counter. */+ocelot_write(ocelot,+SYS_STAT_CFG_STAT_VIEW(index)|+SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),+SYS_STAT_CFG);+}++staticintvsc9959_psfp_filter_add(structocelot*ocelot,+structflow_cls_offload*f)+{+structnetlink_ext_ack*extack=f->common.extack;+structfelix_stream_filtersfi={0};+conststructflow_action_entry*a;+structfelix_stream*stream_entry;+structfelix_streamstream={0};+structocelot_psfp_list*psfp;+intret,i;++psfp=&ocelot->psfp;++ret=vsc9959_stream_identify(f,&stream);+if(ret){+NL_SET_ERR_MSG_MOD(extack,"Only can match on VID, PCP, and dest MAC");+returnret;+}++flow_action_for_each(i,a,&f->rule->action){+switch(a->id){+caseFLOW_ACTION_GATE:+caseFLOW_ACTION_POLICE:+default:+return-EOPNOTSUPP;+}+}++/* Check if stream is set. */+stream_entry=vsc9959_stream_table_lookup(&psfp->stream_list,&stream);+if(stream_entry){+NL_SET_ERR_MSG_MOD(extack,"This stream is already added");+return-EEXIST;+}++sfi.prio_valid=(stream.prio<0?0:1);+sfi.prio=(sfi.prio_valid?stream.prio:0);+sfi.enable=1;++ret=vsc9959_psfp_sfi_table_add(ocelot,&sfi);+if(ret)+returnret;++stream.sfid=sfi.index;+stream.sfid_valid=1;+ret=vsc9959_stream_table_add(ocelot,&psfp->stream_list,+&stream,extack);+if(ret)+vsc9959_psfp_sfi_table_del(ocelot,stream.sfid);++returnret;+}++staticintvsc9959_psfp_filter_del(structocelot*ocelot,+structflow_cls_offload*f)+{+structocelot_psfp_list*psfp;+structfelix_stream*stream;++psfp=&ocelot->psfp;++stream=vsc9959_stream_table_get(&psfp->stream_list,f->cookie);+if(!stream)+return-ENOMEM;++vsc9959_psfp_sfi_table_del(ocelot,stream->sfid);++stream->sfid_valid=0;+vsc9959_stream_table_del(ocelot,stream);++return0;+}++staticintvsc9959_psfp_stats_get(structocelot*ocelot,+structflow_cls_offload*f,+structflow_stats*stats)+{+structfelix_stream_filter_counterscounters;+structocelot_psfp_list*psfp;+structfelix_stream*stream;++psfp=&ocelot->psfp;+stream=vsc9959_stream_table_get(&psfp->stream_list,f->cookie);+if(!stream)+return-ENOMEM;++vsc9959_psfp_counters_get(ocelot,stream->sfid,&counters);++stats->pkts=counters.match;+stats->drops=counters.not_pass_gate+counters.not_pass_sdu++counters.red;++return0;+}++staticvoidvsc9959_psfp_init(structocelot*ocelot)+{+structocelot_psfp_list*psfp=&ocelot->psfp;++INIT_LIST_HEAD(&psfp->stream_list);+INIT_LIST_HEAD(&psfp->sfi_list);+INIT_LIST_HEAD(&psfp->sgi_list);+}++staticconststructocelot_opsvsc9959_ops={+.reset=vsc9959_reset,+.wm_enc=vsc9959_wm_enc,+.wm_dec=vsc9959_wm_dec,+.wm_stat=vsc9959_wm_stat,+.port_to_netdev=felix_port_to_netdev,+.netdev_to_port=felix_netdev_to_port,+.psfp_init=vsc9959_psfp_init,+.psfp_filter_add=vsc9959_psfp_filter_add,+.psfp_filter_del=vsc9959_psfp_filter_del,+.psfp_stats_get=vsc9959_psfp_stats_get,+};+staticconststructfelix_infofelix_info_vsc9959={.target_io_res=vsc9959_target_io_res,.port_io_res=vsc9959_port_io_res,
@@ -673,6 +679,8 @@ struct ocelot {structocelot_vcap_blockblock[3];structvcap_props*vcap;+structocelot_psfp_listpsfp;+/* Workqueue to check statistics for overflow with its lock */structmutexstats_lock;u64*stats;
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:44
This patch add police action to set flow meter table which is defined
in IEEE802.1Qci. Flow metering is two rates two buckets and three color
marker to policing the frames, we only enable one rate one bucket in
this patch.
Flow metering shares a same policer pool with VCAP policers, so the PSFP
policer calls ocelot_vcap_policer_add() and ocelot_vcap_policer_del() to
set flow meter police.
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/dsa/ocelot/felix_vsc9959.c | 32 +++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:49
Policer was previously automatically assigned from the highest index to
the lowest index from policer pool. But police action of tc flower now
uses index to set an police entry. This patch uses the police index to
set vcap policers, so that one policer can be shared by multiple rules.
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/dsa/ocelot/felix.c | 2 +
drivers/net/dsa/ocelot/felix.h | 2 +
drivers/net/dsa/ocelot/felix_vsc9959.c | 4 +
drivers/net/ethernet/mscc/ocelot_flower.c | 5 +
drivers/net/ethernet/mscc/ocelot_vcap.c | 103 +++++++++++++--------
drivers/net/ethernet/mscc/ocelot_vsc7514.c | 7 ++
include/soc/mscc/ocelot.h | 11 ++-
7 files changed, 96 insertions(+), 38 deletions(-)
@@ -984,6 +984,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)ocelot->num_stats=felix->info->num_stats;ocelot->num_mact_rows=felix->info->num_mact_rows;ocelot->vcap=felix->info->vcap;+ocelot->vcap_pol.base=felix->info->vcap_pol_base;+ocelot->vcap_pol.max=felix->info->vcap_pol_max;ocelot->ops=felix->info->ops;ocelot->npi_inj_prefix=OCELOT_TAG_PREFIX_SHORT;ocelot->npi_xtr_prefix=OCELOT_TAG_PREFIX_SHORT;
@@ -1132,7 +1159,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,structnetlink_ext_ack*extack){structocelot_vcap_block*block=&ocelot->block[filter->block_id];-inti,index;+inti,index,ret;if(!ocelot_exclusive_mac_etype_filter_rules(ocelot,filter)){NL_SET_ERR_MSG_MOD(extack,
@@ -1141,7 +1168,9 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,}/* Add filter to the linked list */-ocelot_vcap_filter_add_to_block(ocelot,block,filter);+ret=ocelot_vcap_filter_add_to_block(ocelot,block,filter);+if(ret)+returnret;/* Get the index of the inserted filter */index=ocelot_vcap_block_get_filter_index(block,filter);
From: Xiaoliang Yang <hidden> Date: 2021-09-22 10:42:53
This patch adds stream gate settings for PSFP. Use SGI table to store
stream gate entries. Disable the gate entry when it is not used by any
stream.
Signed-off-by: Xiaoliang Yang <redacted>
---
drivers/net/dsa/ocelot/felix_vsc9959.c | 217 ++++++++++++++++++++++++-
1 file changed, 213 insertions(+), 4 deletions(-)
Remember this discussion we had a while ago?
| Let's take the function below.
|
| static void ocelot_prove_mac_table_entries_can_move(struct ocelot *ocelot)
| {
| unsigned char mac1[ETH_ALEN] = {0x00, 0x04, 0x9f, 0x63, 0x35, 0xea};
| unsigned char mac2[ETH_ALEN] = {0x00, 0x04, 0x9f, 0x63, 0x35, 0xeb};
| int row, bucket, arbitrary_pgid = 4;
| int vid1 = 102;
| int vid2 = 103;
| int err;
|
| err = ocelot_mact_learn(ocelot, arbitrary_pgid, mac1, vid1,
| ENTRYTYPE_LOCKED);
| if (err)
| return;
|
| err = ocelot_mact_lookup(ocelot, mac1, vid1, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 1 (mac %pM vid %d) is in MAC table row %d bucket %d\n",
| mac1, vid1, row, bucket);
|
| err = ocelot_mact_learn(ocelot, arbitrary_pgid, mac2, vid2,
| ENTRYTYPE_LOCKED);
| if (err)
| return;
|
| err = ocelot_mact_lookup(ocelot, mac2, vid2, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 2 (mac %pM vid %d) is in MAC table row %d bucket %d\n",
| mac2, vid2, row, bucket);
|
| err = ocelot_mact_lookup(ocelot, mac1, vid1, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 1 (mac %pM vid %d) is in MAC table row %d bucket %d\n",
| mac1, vid1, row, bucket);
| }
|
| What will it print?
|
| Address 1 (mac 00:04:9f:63:35:ea vid 102) is in MAC table row 917 bucket 0
| Address 2 (mac 00:04:9f:63:35:eb vid 103) is in MAC table row 917 bucket 0
| Address 1 (mac 00:04:9f:63:35:ea vid 102) is in MAC table row 917 bucket 1
|
| What does this mean?
|
| The ROW portion of a FDB entry's position within the MAC table is
| statically determined using an 11-bit hash derived from the {DMAC, VID}
| key. Within a row, there can be up to 4 buckets, each bucket holding 1
| MAC table entry.
|
| But when the hashes of 2 addresses collide and they end up in the same
| row (as in the above example, with address 1 = "mac 00:04:9f:63:35:ea
| vid 102" and address 2 = "mac 00:04:9f:63:35:eb vid 103"), things don't
| happen quite as you might expect. Namely, the second address appears to
| be installed by the switch at the same row and bucket as the first
| address. So is the first address overwritten? No, it has been moved by
| the switch, automatically, to bucket 1.
So if the autonomous and concurrent learning of one MAC address might
move existing MAC table entries from a row to the right, then who
guarantees exactly that the {row, col} for which you are setting up the
SFID is the {row, col} that belongs to the {stream->dmac, stream->vid}
you have searched for?
Microchip people, do we need to temporarily disable hardware address
learning on all ports, and take a lock with the FDB add and delete
operations to ensure they are serialized?
From: Vladimir Oltean <vladimir.oltean@nxp.com> Date: 2021-09-22 13:18:44
On Wed, Sep 22, 2021 at 06:52:01PM +0800, Xiaoliang Yang wrote:
Policer was previously automatically assigned from the highest index to
the lowest index from policer pool. But police action of tc flower now
uses index to set an police entry. This patch uses the police index to
set vcap policers, so that one policer can be shared by multiple rules.
Signed-off-by: Xiaoliang Yang <redacted>
---
+#define VSC9959_VCAP_POLICER_BASE 63
+#define VSC9959_VCAP_POLICER_MAX 383
I think this deserves an explanation.
The VSC7514 driver uses the max number of policers as 383 (0x17f) ever
since commit b596229448dd ("net: mscc: ocelot: Add support for tcam"),
aka the very beginning.
Yet, the documentation at "3.10.1 Policer Allocation"
https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10491.pdf
says very clearly that there are only 192 policers indeed.
What's going on?
Also, FWIW, Seville has this policer allocation:
0 ----+----------------------+
| Port Policers (11) |
11 ----+----------------------+
| VCAP Policers (21) |
32 ----+----------------------+
| QoS Policers (88) |
120 ----+----------------------+
| VCAP Policers (43) |
162 ----+----------------------+
From: Xiaoliang Yang <hidden> Date: 2021-09-23 01:52:45
On Wed, Sep 22, 2021 at 13:18:37 +0000, Vladimir Oltean wrote:
quoted
Policer was previously automatically assigned from the highest index
to the lowest index from policer pool. But police action of tc flower
now uses index to set an police entry. This patch uses the police
index to set vcap policers, so that one policer can be shared by multiple
I think this deserves an explanation.
The VSC7514 driver uses the max number of policers as 383 (0x17f) ever since
commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), aka the
very beginning.
Yet, the documentation at "3.10.1 Policer Allocation"
https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10491.pdf
says very clearly that there are only 192 policers indeed.
What's going on?
In commit commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), Horatiu Vultur define the max number of policers as 383:
+#define OCELOT_POLICER_DISCARD 0x17f
VCAP IS2 use this policer to set drop action. I did not change this and set the VCAP policers with 128-191 according to the VSC7514 document.
I don't know why 383 was used as the maximum value of policer in the original code. Can Microchip people check the code or the documentation for errors?
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Felix DSA needs to use this struct to export MAC table write and lookup
operations as well, for its stream identification functions, so export
them in preparation of that.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Xiaoliang Yang <redacted>
From: Vladimir Oltean <vladimir.oltean@nxp.com>
ocelot_mact_write() can be used for directly modifying an FDB entry
situated at a given row and column, as opposed to the current
ocelot_mact_learn() which calculates the row and column indices
automatically (based on a 11-bit hash derived from the {DMAC, VID} key).
ocelot_mact_lookup() can be used to retrieve the row and column at which
an FDB entry with the given {DMAC, VID} key is found.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Xiaoliang Yang <redacted>
From: Xiaoliang Yang <hidden> Date: 2021-09-23 02:30:34
Hi Vladimir,
On Wed, Sep 22, 2021 at 12:47:59 +0000, Vladimir Oltean wrote:
quoted
+static int vsc9959_mact_stream_set(struct ocelot *ocelot,
+ struct felix_stream *stream,
+ struct netlink_ext_ack *extack) {
+ struct ocelot_mact_entry entry;
+ u32 row, col, reg, dst_idx;
+ u8 type;
+ int ret;
+
+ /* Stream identification desn't support to add a stream with non
+ * existent MAC (The MAC entry has not been learned in MAC table).
+ */
+ ret = ocelot_mact_lookup(ocelot, stream->dmac, stream->vid, &row,
&col);
quoted
+ if (ret) {
+ if (extack)
+ NL_SET_ERR_MSG_MOD(extack, "Stream is not learned in MAC
Remember this discussion we had a while ago?
| Let's take the function below.
|
| static void ocelot_prove_mac_table_entries_can_move(struct ocelot
| *ocelot) {
| unsigned char mac1[ETH_ALEN] = {0x00, 0x04, 0x9f, 0x63, 0x35, 0xea};
| unsigned char mac2[ETH_ALEN] = {0x00, 0x04, 0x9f, 0x63, 0x35, 0xeb};
| int row, bucket, arbitrary_pgid = 4;
| int vid1 = 102;
| int vid2 = 103;
| int err;
|
| err = ocelot_mact_learn(ocelot, arbitrary_pgid, mac1, vid1,
| ENTRYTYPE_LOCKED);
| if (err)
| return;
|
| err = ocelot_mact_lookup(ocelot, mac1, vid1, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 1 (mac %pM vid %d) is in MAC table row %d
bucket %d\n",
| mac1, vid1, row, bucket);
|
| err = ocelot_mact_learn(ocelot, arbitrary_pgid, mac2, vid2,
| ENTRYTYPE_LOCKED);
| if (err)
| return;
|
| err = ocelot_mact_lookup(ocelot, mac2, vid2, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 2 (mac %pM vid %d) is in MAC table row %d
bucket %d\n",
| mac2, vid2, row, bucket);
|
| err = ocelot_mact_lookup(ocelot, mac1, vid1, &row, &bucket);
| if (err)
| return;
|
| dev_info(ocelot->dev,
| "Address 1 (mac %pM vid %d) is in MAC table row %d
bucket %d\n",
| mac1, vid1, row, bucket);
| }
|
| What will it print?
|
| Address 1 (mac 00:04:9f:63:35:ea vid 102) is in MAC table row 917
| bucket 0 Address 2 (mac 00:04:9f:63:35:eb vid 103) is in MAC table row
| 917 bucket 0 Address 1 (mac 00:04:9f:63:35:ea vid 102) is in MAC table
| row 917 bucket 1
|
| What does this mean?
|
| The ROW portion of a FDB entry's position within the MAC table is
| statically determined using an 11-bit hash derived from the {DMAC,
| VID} key. Within a row, there can be up to 4 buckets, each bucket
| holding 1 MAC table entry.
|
| But when the hashes of 2 addresses collide and they end up in the same
| row (as in the above example, with address 1 = "mac 00:04:9f:63:35:ea
| vid 102" and address 2 = "mac 00:04:9f:63:35:eb vid 103"), things
| don't happen quite as you might expect. Namely, the second address
| appears to be installed by the switch at the same row and bucket as
| the first address. So is the first address overwritten? No, it has
| been moved by the switch, automatically, to bucket 1.
So if the autonomous and concurrent learning of one MAC address might
move existing MAC table entries from a row to the right, then who guarantees
exactly that the {row, col} for which you are setting up the SFID is the {row, col}
that belongs to the {stream->dmac, stream->vid} you have searched for?
Microchip people, do we need to temporarily disable hardware address
learning on all ports, and take a lock with the FDB add and delete operations
to ensure they are serialized?
Maybe we need to use ocelot_mact_learn() instead of ocelot_mact_write() after setting SFID in StreamData. I think this can avoid writing a wrong entry.
Regards,
Xiaoliang
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On Wed, Sep 22, 2021 at 13:18:37 +0000, Vladimir Oltean wrote:
quoted
quoted
Policer was previously automatically assigned from the highest index
to the lowest index from policer pool. But police action of tc flower
now uses index to set an police entry. This patch uses the police
index to set vcap policers, so that one policer can be shared by multiple
I think this deserves an explanation.
The VSC7514 driver uses the max number of policers as 383 (0x17f) ever since
commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), aka the
very beginning.
Yet, the documentation at "3.10.1 Policer Allocation"
https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10491.pdf
says very clearly that there are only 192 policers indeed.
What's going on?
In commit commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), Horatiu Vultur define the max number of policers as 383:
+#define OCELOT_POLICER_DISCARD 0x17f
VCAP IS2 use this policer to set drop action. I did not change this and set the VCAP policers with 128-191 according to the VSC7514 document.
I don't know why 383 was used as the maximum value of policer in the original code. Can Microchip people check the code or the documentation for errors?
It was defined as 383 because the HW actually support this number of
policers. But for this SKU it is recomended to use 191, but no one will
stop you from using 383.
From: Vladimir Oltean <vladimir.oltean@nxp.com> Date: 2021-09-23 09:22:33
On Thu, Sep 23, 2021 at 09:30:59AM +0200, Horatiu Vultur wrote:
quoted
In commit commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), Horatiu Vultur define the max number of policers as 383:
+#define OCELOT_POLICER_DISCARD 0x17f
VCAP IS2 use this policer to set drop action. I did not change this and set the VCAP policers with 128-191 according to the VSC7514 document.
I don't know why 383 was used as the maximum value of policer in the original code. Can Microchip people check the code or the documentation for errors?
It was defined as 383 because the HW actually support this number of
policers. But for this SKU it is recomended to use 191, but no one will
stop you from using 383.
So if it is recommended to use 191, why did you use 383? Should Xiaoliang
change that to 191, or leave it alone?
I didn't find Seville's document, if this allocation is right, I will add it in Seville driver.
Strange enough, I don't remember having reports about the VCAP IS2
policers on Seville not working, and of course being in the common code,
we'd start with a count of 384 policers for that hardware too, and
counting from the end. I think I even tested the policers when adding
the VCAP IS2 constants, and they worked. Is there any sort of index
wraparound that takes place?
From: Vladimir Oltean <vladimir.oltean@nxp.com> Date: 2021-09-23 09:44:43
On Thu, Sep 23, 2021 at 02:30:16AM +0000, Xiaoliang Yang wrote:
Maybe we need to use ocelot_mact_learn() instead of
ocelot_mact_write() after setting SFID in StreamData. I think this can
avoid writing a wrong entry.
So you're thinking of introducing a new ocelot_mact_learn_with_streamdata(),
that writes the SFID and SSID of the STREAMDATA too, instead of editing
them in-place for an existing MAC table entry, and then issuing a LEARN
MAC Table command which would hopefully transfer the entire data
structure to the MAC table?
Have you tried that?
In the documentation for the LEARN MAC Table command, I see:
Purpose: Insert/learn new entry in MAC table. Position given by (MAC, VID)
Use: Configure MAC and VID of the new entry in MACHDATA and MACLDATA.
Configure remaining entry fields in MACACCESS. The location in the MAC
table is calculated based on (MAC, VID).
I just hope it will transfer the STREAMDATA too, it doesn't explicitly
say that it will...
And assuming it does, will the LEARN command overwrite an existing
static FDB entry which has the same MAC DA and VLAN ID, but not SFID?
I haven't tried that either.
From: Xiaoliang Yang <hidden> Date: 2021-09-23 11:23:53
Hi Vladimir,
On Thu, Sep 23, 2021 at 15:45:16 +0000, Vladimir Oltean wrote:
quoted
Maybe we need to use ocelot_mact_learn() instead of
ocelot_mact_write() after setting SFID in StreamData. I think this can
avoid writing a wrong entry.
So you're thinking of introducing a new ocelot_mact_learn_with_streamdata(),
that writes the SFID and SSID of the STREAMDATA too, instead of editing them
in-place for an existing MAC table entry, and then issuing a LEARN MAC Table
command which would hopefully transfer the entire data structure to the MAC
table?
Have you tried that?
Yes, I have tried. I mean writes SFID of STREAMDATA in vsc9959_mact_stream_set() first, then calls ocelot_mact_learn() function to write VID, mac and STREAMDATA in MAC table. We don't need to introduce a new function. Once we call ocelot_mact_learn() function, STREAMDATA will be stored in the learned entry.
In the documentation for the LEARN MAC Table command, I see:
Purpose: Insert/learn new entry in MAC table. Position given by (MAC, VID)
Use: Configure MAC and VID of the new entry in MACHDATA and MACLDATA.
Configure remaining entry fields in MACACCESS. The location in the MAC
table is calculated based on (MAC, VID).
I just hope it will transfer the STREAMDATA too, it doesn't explicitly say that it
will...
And assuming it does, will the LEARN command overwrite an existing static
FDB entry which has the same MAC DA and VLAN ID, but not SFID?
I haven't tried that either.
I tried the case that when MAC table index has changed, STREAMDATA will keep move with VID and MAC. The entry { STREAMDATA , VID, MAC} also can overwrite a static exist entry. I think we can do like this.
From: Vladimir Oltean <vladimir.oltean@nxp.com> Date: 2021-09-23 11:35:37
On Thu, Sep 23, 2021 at 11:23:45AM +0000, Xiaoliang Yang wrote:
Hi Vladimir,
On Thu, Sep 23, 2021 at 15:45:16 +0000, Vladimir Oltean wrote:
quoted
quoted
Maybe we need to use ocelot_mact_learn() instead of
ocelot_mact_write() after setting SFID in StreamData. I think this can
avoid writing a wrong entry.
So you're thinking of introducing a new ocelot_mact_learn_with_streamdata(),
that writes the SFID and SSID of the STREAMDATA too, instead of editing them
in-place for an existing MAC table entry, and then issuing a LEARN MAC Table
command which would hopefully transfer the entire data structure to the MAC
table?
Have you tried that?
Yes, I have tried. I mean writes SFID of STREAMDATA in
vsc9959_mact_stream_set() first, then calls ocelot_mact_learn()
function to write VID, mac and STREAMDATA in MAC table. We don't need
to introduce a new function. Once we call ocelot_mact_learn()
function, STREAMDATA will be stored in the learned entry.
quoted
In the documentation for the LEARN MAC Table command, I see:
Purpose: Insert/learn new entry in MAC table. Position given by (MAC, VID)
Use: Configure MAC and VID of the new entry in MACHDATA and MACLDATA.
Configure remaining entry fields in MACACCESS. The location in the MAC
table is calculated based on (MAC, VID).
I just hope it will transfer the STREAMDATA too, it doesn't explicitly say that it
will...
And assuming it does, will the LEARN command overwrite an existing static
FDB entry which has the same MAC DA and VLAN ID, but not SFID?
I haven't tried that either.
I tried the case that when MAC table index has changed, STREAMDATA
will keep move with VID and MAC. The entry { STREAMDATA , VID, MAC}
also can overwrite a static exist entry. I think we can do like this.
Ok, so maybe we should do that?
Even though I must say I don't really like the idea of partially writing
MAC table entry data from the vsc9959 driver, and partially from
ocelot_mact_learn. I also have this patch pending:
https://patchwork.kernel.org/project/netdevbpf/patch/20210824114049.3814660-4-vladimir.oltean@nxp.com/
and concurrency will be an absolute mess. The ocelot->mact_lock will
need to be taken _before_ we start writing the STREAMDATA, so this
variant of ocelot_mact_learn will still have to stay somewhere in the
ocelot library, and be organized something like this:
__ocelot_mact_learn()
{
do what ocelot_mact_learn() currently does
}
ocelot_mact_learn()
{
mutex_lock(&ocelot->mact_lock);
__ocelot_mact_learn();
mutex_unlock(&ocelot->mact_lock);
}
ocelot_mact_learn_streamdata()
{
mutex_lock(&ocelot->mact_lock);
write_streamdata();
__ocelot_mact_learn();
mutex_unlock(&ocelot->mact_lock);
}
otherwise I would need to introduce avoidable refactoring in the driver.
In fact, could you please pick up that mact_lock patch? Even if the
rtnl_mutex was not dropped yet, the extra lock should not hurt anyone.
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On Thu, Sep 23, 2021 at 09:30:59AM +0200, Horatiu Vultur wrote:
quoted
quoted
In commit commit b596229448dd ("net: mscc: ocelot: Add support for tcam"), Horatiu Vultur define the max number of policers as 383:
+#define OCELOT_POLICER_DISCARD 0x17f
VCAP IS2 use this policer to set drop action. I did not change this and set the VCAP policers with 128-191 according to the VSC7514 document.
I don't know why 383 was used as the maximum value of policer in the original code. Can Microchip people check the code or the documentation for errors?
It was defined as 383 because the HW actually support this number of
policers. But for this SKU it is recomended to use 191, but no one will
stop you from using 383.
So if it is recommended to use 191, why did you use 383? Should Xiaoliang
change that to 191, or leave it alone?
I think is better to leave it alone. I am not aware of doing any hard if
the value is 383.
I didn't find Seville's document, if this allocation is right, I will add it in Seville driver.
Strange enough, I don't remember having reports about the VCAP IS2
policers on Seville not working, and of course being in the common code,
we'd start with a count of 384 policers for that hardware too, and
counting from the end. I think I even tested the policers when adding
the VCAP IS2 constants, and they worked. Is there any sort of index
wraparound that takes place?
I don't think there is any wraparound.
--
/Horatiu