From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:05
Hi,
add support for dumping the VLAN and FDB table via devlink. As the driver uses
internal VLANs and static FDB entries, this is a useful debugging feature. Also
report the current memory and descriptor usage.
Thanks,
Kurt
Kurt Kanzenbach (6):
net: dsa: hellcreek: Report RAM usage
net: dsa: hellcreek: Report META data usage
net: dsa: hellcreek: Add devlink VLAN region
net: dsa: hellcreek: Use boolean value
net: dsa: hellcreek: Move common code to helper
net: dsa: hellcreek: Add devlink FDB region
drivers/net/dsa/hirschmann/hellcreek.c | 293 +++++++++++++++++++++----
drivers/net/dsa/hirschmann/hellcreek.h | 11 +
2 files changed, 258 insertions(+), 46 deletions(-)
--
2.30.2
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:04
There are two functions which need to populate fdb entries. Move that to a
helper function.
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 85 +++++++++++++-------------
1 file changed, 43 insertions(+), 42 deletions(-)
@@ -674,6 +674,40 @@ static int __hellcreek_fdb_del(struct hellcreek *hellcreek,returnhellcreek_wait_fdb_ready(hellcreek);}+staticvoidhellcreek_populate_fdb_entry(structhellcreek*hellcreek,+structhellcreek_fdb_entry*entry,+size_tidx)+{+unsignedcharaddr[ETH_ALEN];+u16meta,mac;++/* Read values */+meta=hellcreek_read(hellcreek,HR_FDBMDRD);+mac=hellcreek_read(hellcreek,HR_FDBRDL);+addr[5]=mac&0xff;+addr[4]=(mac&0xff00)>>8;+mac=hellcreek_read(hellcreek,HR_FDBRDM);+addr[3]=mac&0xff;+addr[2]=(mac&0xff00)>>8;+mac=hellcreek_read(hellcreek,HR_FDBRDH);+addr[1]=mac&0xff;+addr[0]=(mac&0xff00)>>8;++/* Populate @entry */+memcpy(entry->mac,addr,sizeof(addr));+entry->idx=idx;+entry->portmask=(meta&HR_FDBMDRD_PORTMASK_MASK)>>+HR_FDBMDRD_PORTMASK_SHIFT;+entry->age=(meta&HR_FDBMDRD_AGE_MASK)>>+HR_FDBMDRD_AGE_SHIFT;+entry->is_obt=!!(meta&HR_FDBMDRD_OBT);+entry->pass_blocked=!!(meta&HR_FDBMDRD_PASS_BLOCKED);+entry->is_static=!!(meta&HR_FDBMDRD_STATIC);+entry->reprio_tc=(meta&HR_FDBMDRD_REPRIO_TC_MASK)>>+HR_FDBMDRD_REPRIO_TC_SHIFT;+entry->reprio_en=!!(meta&HR_FDBMDRD_REPRIO_EN);+}+/* Retrieve the index of a FDB entry by mac address. Currently we search through*thecompletetableinhardware.Ifthat'stooslow,wemighthavetocache*thecompleteFDBtableinsoftware.
@@ -695,39 +729,19 @@ static int hellcreek_fdb_get(struct hellcreek *hellcreek,*enternewentriesanywhere.*/for(i=0;i<hellcreek->fdb_entries;++i){-unsignedcharaddr[ETH_ALEN];-u16meta,mac;--meta=hellcreek_read(hellcreek,HR_FDBMDRD);-mac=hellcreek_read(hellcreek,HR_FDBRDL);-addr[5]=mac&0xff;-addr[4]=(mac&0xff00)>>8;-mac=hellcreek_read(hellcreek,HR_FDBRDM);-addr[3]=mac&0xff;-addr[2]=(mac&0xff00)>>8;-mac=hellcreek_read(hellcreek,HR_FDBRDH);-addr[1]=mac&0xff;-addr[0]=(mac&0xff00)>>8;+structhellcreek_fdb_entrytmp={0};++/* Read entry */+hellcreek_populate_fdb_entry(hellcreek,&tmp,i);/* Force next entry */hellcreek_write(hellcreek,0x00,HR_FDBRDH);-if(memcmp(addr,dest,ETH_ALEN))+if(memcmp(tmp.mac,dest,ETH_ALEN))continue;/* Match found */-entry->idx=i;-entry->portmask=(meta&HR_FDBMDRD_PORTMASK_MASK)>>-HR_FDBMDRD_PORTMASK_SHIFT;-entry->age=(meta&HR_FDBMDRD_AGE_MASK)>>-HR_FDBMDRD_AGE_SHIFT;-entry->is_obt=!!(meta&HR_FDBMDRD_OBT);-entry->pass_blocked=!!(meta&HR_FDBMDRD_PASS_BLOCKED);-entry->is_static=!!(meta&HR_FDBMDRD_STATIC);-entry->reprio_tc=(meta&HR_FDBMDRD_REPRIO_TC_MASK)>>-HR_FDBMDRD_REPRIO_TC_SHIFT;-entry->reprio_en=!!(meta&HR_FDBMDRD_REPRIO_EN);-memcpy(entry->mac,addr,sizeof(addr));+memcpy(entry,&tmp,sizeof(*entry));return0;}
@@ -842,18 +856,9 @@ static int hellcreek_fdb_dump(struct dsa_switch *ds, int port,for(i=0;i<hellcreek->fdb_entries;++i){unsignedcharnull_addr[ETH_ALEN]={0};structhellcreek_fdb_entryentry={0};-u16meta,mac;--meta=hellcreek_read(hellcreek,HR_FDBMDRD);-mac=hellcreek_read(hellcreek,HR_FDBRDL);-entry.mac[5]=mac&0xff;-entry.mac[4]=(mac&0xff00)>>8;-mac=hellcreek_read(hellcreek,HR_FDBRDM);-entry.mac[3]=mac&0xff;-entry.mac[2]=(mac&0xff00)>>8;-mac=hellcreek_read(hellcreek,HR_FDBRDH);-entry.mac[1]=mac&0xff;-entry.mac[0]=(mac&0xff00)>>8;++/* Read entry */+hellcreek_populate_fdb_entry(hellcreek,&entry,i);/* Force next entry */hellcreek_write(hellcreek,0x00,HR_FDBRDH);
@@ -862,10 +867,6 @@ static int hellcreek_fdb_dump(struct dsa_switch *ds, int port,if(!memcmp(entry.mac,null_addr,ETH_ALEN))continue;-entry.portmask=(meta&HR_FDBMDRD_PORTMASK_MASK)>>-HR_FDBMDRD_PORTMASK_SHIFT;-entry.is_static=!!(meta&HR_FDBMDRD_STATIC);-/* Check port mask */if(!(entry.portmask&BIT(port)))continue;
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:05
Allow to dump the FDB table via devlink. This is a useful debugging feature.
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 63 ++++++++++++++++++++++++++
drivers/net/dsa/hirschmann/hellcreek.h | 1 +
2 files changed, 64 insertions(+)
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:05
Report the RAM usage via devlink. This is a useful debug feature. The actual
size depends on the used Hellcreek version:
|root@tsn:~# devlink resource show platform/ff240000.switch
|platform/ff240000.switch:
| name VLAN size 4096 occ 3 unit entry dpipe_tables none
| name FDB size 256 occ 6 unit entry dpipe_tables none
| name RAM size 320 occ 14 unit entry dpipe_tables none
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 38 ++++++++++++++++++++++++--
drivers/net/dsa/hirschmann/hellcreek.h | 2 ++
2 files changed, 37 insertions(+), 3 deletions(-)
@@ -221,11 +221,13 @@ static void hellcreek_feature_detect(struct hellcreek *hellcreek)features=hellcreek_read(hellcreek,HR_FEABITS0);-/* Only detect the size of the FDB table. The size and current-*utilizationcanbequeriedviadevlink.+/* Detect the FDB table size and the maximum RAM page count. The size+*andcurrentutilizationcanbequeriedviadevlink.*/hellcreek->fdb_entries=((features&HR_FEABITS0_FDBBINS_MASK)>>-HR_FEABITS0_FDBBINS_SHIFT)*32;+HR_FEABITS0_FDBBINS_SHIFT)*32;+hellcreek->page_count=((features&HR_FEABITS0_PCNT_MASK)>>+HR_FEABITS0_PCNT_SHIFT)*32;}staticenumdsa_tag_protocolhellcreek_get_tag_protocol(structdsa_switch*ds,
@@ -1034,10 +1036,23 @@ static u64 hellcreek_devlink_fdb_table_get(void *priv)returncount;}+staticu64hellcreek_devlink_ram_usage_get(void*priv)+{+structhellcreek*hellcreek=priv;+u64usage=0;++/* Indicates how many free ram pages are available. */+usage=hellcreek_read(hellcreek,HR_PFREE);+usage=hellcreek->page_count-usage;++returnusage;+}+staticinthellcreek_setup_devlink_resources(structdsa_switch*ds){structdevlink_resource_size_paramssize_vlan_params;structdevlink_resource_size_paramssize_fdb_params;+structdevlink_resource_size_paramssize_ram_params;structhellcreek*hellcreek=ds->priv;interr;
@@ -1050,6 +1065,11 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)hellcreek->fdb_entries,1,DEVLINK_RESOURCE_UNIT_ENTRY);+devlink_resource_size_params_init(&size_ram_params,+hellcreek->page_count,+hellcreek->page_count,+1,DEVLINK_RESOURCE_UNIT_ENTRY);+err=dsa_devlink_resource_register(ds,"VLAN",VLAN_N_VID,HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,DEVLINK_RESOURCE_ID_PARENT_TOP,
@@ -1064,6 +1084,13 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)if(err)gotoout;+err=dsa_devlink_resource_register(ds,"RAM",hellcreek->page_count,+HELLCREEK_DEVLINK_PARAM_ID_RAM_USAGE,+DEVLINK_RESOURCE_ID_PARENT_TOP,+&size_ram_params);+if(err)+gotoout;+dsa_devlink_resource_occ_get_register(ds,HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,hellcreek_devlink_vlan_table_get,
@@ -1074,6 +1101,11 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)hellcreek_devlink_fdb_table_get,hellcreek);+dsa_devlink_resource_occ_get_register(ds,+HELLCREEK_DEVLINK_PARAM_ID_RAM_USAGE,+hellcreek_devlink_ram_usage_get,+hellcreek);+return0;out:
@@ -286,6 +286,7 @@ struct hellcreek {u64last_ts;/* Used for overflow detection */u16status_out;/* ptp.status_out shadow */size_tfdb_entries;+size_tpage_count;};/* A Qbv schedule can only started up to 8 seconds in the future. If the delta
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:05
Allow to dump the VLAN table via devlink. This especially useful, because the
driver internally leverages VLANs for the port separation. These are not visible
via the bridge utility.
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 73 ++++++++++++++++++++++++++
drivers/net/dsa/hirschmann/hellcreek.h | 6 +++
2 files changed, 79 insertions(+)
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:06
hellcreek_select_vlan() takes a boolean instead of an integer.
So, use false accordingly.
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Kurt Kanzenbach <hidden> Date: 2021-03-11 18:23:06
Report the META data descriptor usage via devlink. This is a useful debug
feature. The actual size depends on the used Hellcreek version:
|root@tsn:~# devlink resource show platform/ff240000.switch
|platform/ff240000.switch:
| name VLAN size 4096 occ 3 unit entry dpipe_tables none
| name FDB size 256 occ 6 unit entry dpipe_tables none
| name RAM size 320 occ 14 unit entry dpipe_tables none
| name META size 320 occ 5 unit entry dpipe_tables none
Signed-off-by: Kurt Kanzenbach <redacted>
---
drivers/net/dsa/hirschmann/hellcreek.c | 36 ++++++++++++++++++++++++--
drivers/net/dsa/hirschmann/hellcreek.h | 2 ++
2 files changed, 36 insertions(+), 2 deletions(-)
@@ -221,13 +221,15 @@ static void hellcreek_feature_detect(struct hellcreek *hellcreek)features=hellcreek_read(hellcreek,HR_FEABITS0);-/* Detect the FDB table size and the maximum RAM page count. The size-*andcurrentutilizationcanbequeriedviadevlink.+/* Detect the FDB table size and the maximum RAM page and meta data+*count.Thesizeandcurrentutilizationcanbequeriedviadevlink.*/hellcreek->fdb_entries=((features&HR_FEABITS0_FDBBINS_MASK)>>HR_FEABITS0_FDBBINS_SHIFT)*32;hellcreek->page_count=((features&HR_FEABITS0_PCNT_MASK)>>HR_FEABITS0_PCNT_SHIFT)*32;+hellcreek->meta_count=((features&HR_FEABITS0_MCNT_MASK)>>+HR_FEABITS0_MCNT_SHIFT)*32;}staticenumdsa_tag_protocolhellcreek_get_tag_protocol(structdsa_switch*ds,
@@ -1048,9 +1050,22 @@ static u64 hellcreek_devlink_ram_usage_get(void *priv)returnusage;}+staticu64hellcreek_devlink_meta_usage_get(void*priv)+{+structhellcreek*hellcreek=priv;+u64usage=0;++/* Indicates how many free meta data descriptors are available. */+usage=hellcreek_read(hellcreek,HR_MFREE);+usage=hellcreek->meta_count-usage;++returnusage;+}+staticinthellcreek_setup_devlink_resources(structdsa_switch*ds){structdevlink_resource_size_paramssize_vlan_params;+structdevlink_resource_size_paramssize_meta_params;structdevlink_resource_size_paramssize_fdb_params;structdevlink_resource_size_paramssize_ram_params;structhellcreek*hellcreek=ds->priv;
@@ -1070,6 +1085,11 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)hellcreek->page_count,1,DEVLINK_RESOURCE_UNIT_ENTRY);+devlink_resource_size_params_init(&size_meta_params,+hellcreek->meta_count,+hellcreek->meta_count,+1,DEVLINK_RESOURCE_UNIT_ENTRY);+err=dsa_devlink_resource_register(ds,"VLAN",VLAN_N_VID,HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,DEVLINK_RESOURCE_ID_PARENT_TOP,
@@ -1091,6 +1111,13 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)if(err)gotoout;+err=dsa_devlink_resource_register(ds,"META",hellcreek->meta_count,+HELLCREEK_DEVLINK_PARAM_ID_METADATA_USAGE,+DEVLINK_RESOURCE_ID_PARENT_TOP,+&size_meta_params);+if(err)+gotoout;+dsa_devlink_resource_occ_get_register(ds,HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,hellcreek_devlink_vlan_table_get,
@@ -1106,6 +1133,11 @@ static int hellcreek_setup_devlink_resources(struct dsa_switch *ds)hellcreek_devlink_ram_usage_get,hellcreek);+dsa_devlink_resource_occ_get_register(ds,+HELLCREEK_DEVLINK_PARAM_ID_METADATA_USAGE,+hellcreek_devlink_meta_usage_get,+hellcreek);+return0;out:
@@ -287,6 +287,7 @@ struct hellcreek {u16status_out;/* ptp.status_out shadow */size_tfdb_entries;size_tpage_count;+size_tmeta_count;};/* A Qbv schedule can only started up to 8 seconds in the future. If the delta
From: Jakub Kicinski <kuba@kernel.org> Date: 2021-03-11 20:36:09
On Thu, 11 Mar 2021 18:53:39 +0100 Kurt Kanzenbach wrote:
Report the RAM usage via devlink. This is a useful debug feature. The actual
size depends on the used Hellcreek version:
|root@tsn:~# devlink resource show platform/ff240000.switch
|platform/ff240000.switch:
| name VLAN size 4096 occ 3 unit entry dpipe_tables none
| name FDB size 256 occ 6 unit entry dpipe_tables none
| name RAM size 320 occ 14 unit entry dpipe_tables none
From: Vladimir Oltean <olteanv@gmail.com> Date: 2021-03-11 23:18:18
On Thu, Mar 11, 2021 at 11:52:41PM +0100, Andrew Lunn wrote:
On Thu, Mar 11, 2021 at 06:53:40PM +0100, Kurt Kanzenbach wrote:
quoted
Report the META data descriptor usage via devlink.
Jakubs question is also relevant here. Please could you give a bit
more background about what the meta data is?
Not having seen any documentation for this device, my guess is that
metadata descriptors are frame references, and the RAM page count is for
packet memory buffers. Nonetheless, I would still like to hear it from
Kurt. There is still a lot unknown even if I am correct. For example, if
the frame references or buffers can be partitioned, or if watermarks for
things like congestion/flow control can be set, then maybe devlink-sb is
a better choice (as that has an occupancy facility as well)?
Fully understand that it is not as trivial as exposing a devlink
resource, but on Ocelot/Felix I quite appreciate having the feature
(drivers/net/ethernet/mscc/ocelot_devlink.c). And knowing that this is a
TSN switch, I expect that sooner or later, the need to have control over
resource partitioning per traffic class will arise anyway.
From: Kurt Kanzenbach <hidden> Date: 2021-03-12 16:12:03
On Fri Mar 12 2021, Vladimir Oltean wrote:
On Thu, Mar 11, 2021 at 11:52:41PM +0100, Andrew Lunn wrote:
quoted
On Thu, Mar 11, 2021 at 06:53:40PM +0100, Kurt Kanzenbach wrote:
quoted
Report the META data descriptor usage via devlink.
Jakubs question is also relevant here. Please could you give a bit
more background about what the meta data is?
Not having seen any documentation for this device, my guess is that
metadata descriptors are frame references, and the RAM page count is
for packet memory buffers. Nonetheless, I would still like to hear it
from Kurt.
Yes, exactly.
There is still a lot unknown even if I am correct. For example, if
the frame references or buffers can be partitioned, or if watermarks for
things like congestion/flow control can be set, then maybe devlink-sb is
a better choice (as that has an occupancy facility as well)?
Fully understand that it is not as trivial as exposing a devlink
resource, but on Ocelot/Felix I quite appreciate having the feature
(drivers/net/ethernet/mscc/ocelot_devlink.c). And knowing that this is a
TSN switch, I expect that sooner or later, the need to have control over
resource partitioning per traffic class will arise anyway.
True. The switch can actually distinguish between critical and
background traffic. Multiple limits can be configured: Maximum memory,
reserved memory for critical traffic, background traffic rates and queue
depths. I'll take a look at devlink-sb for that.
Thanks,
Kurt