Message ID | 20240221152421.112324-9-diogo.ivo@siemens.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Support ICSSG-based Ethernet on AM65x SR1.0 devices | expand |
On 21/02/2024 17:24, Diogo Ivo wrote: > Add the functions to configure the SR1.0 packet classifier. > > Based on the work of Roger Quadros in TI's 5.10 SDK [1]. > > [1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y > > Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> > --- > Changes in v3: > - Replace local variables in icssg_class_add_mcast_sr1() > with eth_reserved_addr_base and eth_ipv4_mcast_addr_base > > .../net/ethernet/ti/icssg/icssg_classifier.c | 113 ++++++++++++++++-- > drivers/net/ethernet/ti/icssg/icssg_prueth.c | 2 +- > drivers/net/ethernet/ti/icssg/icssg_prueth.h | 6 +- > 3 files changed, 110 insertions(+), 11 deletions(-) > > diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c > index 6df53ab17fbc..71b2f89ccd8e 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_classifier.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c > @@ -274,6 +274,16 @@ static void rx_class_set_or(struct regmap *miig_rt, int slice, int n, > regmap_write(miig_rt, offset, data); > } > > +static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n) > +{ > + u32 offset, val; > + > + offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); > + regmap_read(miig_rt, offset, &val); > + > + return val; > +} > + > void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac) > { > regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 | > @@ -288,6 +298,26 @@ void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) > regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8)); > } > > +static void icssg_class_ft1_add_mcast(struct regmap *miig_rt, int slice, > + int slot, const u8 *addr, const u8 *mask) > +{ > + int i; > + u32 val; > + > + WARN(slot >= FT1_NUM_SLOTS, "invalid slot: %d\n", slot); > + > + rx_class_ft1_set_da(miig_rt, slice, slot, addr); > + rx_class_ft1_set_da_mask(miig_rt, slice, slot, mask); > + rx_class_ft1_cfg_set_type(miig_rt, slice, slot, FT1_CFG_TYPE_EQ); > + > + /* Enable the FT1 slot in OR enable for all classifiers */ > + for (i = 0; i < ICSSG_NUM_CLASSIFIERS_IN_USE; i++) { > + val = rx_class_get_or(miig_rt, slice, i); > + val |= RX_CLASS_FT_FT1_MATCH(slot); > + rx_class_set_or(miig_rt, slice, i, val); > + } > +} > + > /* disable all RX traffic */ > void icssg_class_disable(struct regmap *miig_rt, int slice) > { > @@ -331,30 +361,95 @@ void icssg_class_disable(struct regmap *miig_rt, int slice) > regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); > } > > -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti) > +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, > + bool is_sr1) > { > + int num_classifiers = is_sr1 ? ICSSG_NUM_CLASSIFIERS_IN_USE : 1; > u32 data; > + int n; > > /* defaults */ > icssg_class_disable(miig_rt, slice); > > /* Setup Classifier */ > - /* match on Broadcast or MAC_PRU address */ > - data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; > + for (n = 0; n < num_classifiers; n++) { > + /* match on Broadcast or MAC_PRU address */ > + data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; > > - /* multicast */ > - if (allmulti) > - data |= RX_CLASS_FT_MC; > + /* multicast */ > + if (allmulti) > + data |= RX_CLASS_FT_MC; > > - rx_class_set_or(miig_rt, slice, 0, data); > + rx_class_set_or(miig_rt, slice, n, data); > > - /* set CFG1 for OR_OR_AND for classifier */ > - rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND); > + /* set CFG1 for OR_OR_AND for classifier */ > + rx_class_sel_set_type(miig_rt, slice, n, > + RX_CLASS_SEL_TYPE_OR_OR_AND); > + } > > /* clear CFG2 */ > regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); > } > > +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice) > +{ > + u32 data, offset; > + int n; > + > + /* defaults */ > + icssg_class_disable(miig_rt, slice); > + > + /* Setup Classifier */ > + for (n = 0; n < ICSSG_NUM_CLASSIFIERS_IN_USE; n++) { > + /* set RAW_MASK to bypass filters */ > + offset = RX_CLASS_GATES_N_REG(slice, n); > + regmap_read(miig_rt, offset, &data); > + data |= RX_CLASS_GATES_RAW_MASK; > + regmap_write(miig_rt, offset, data); > + } > +} > + > +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, > + struct net_device *ndev) > +{ > + u8 mask_addr[6] = { 0, 0, 0, 0, 0, 0xff }; > + struct netdev_hw_addr *ha; > + int slot = 2; > + > + rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); > + /* reserve first 2 slots for > + * 1) 01-80-C2-00-00-XX Known Service Ethernet Multicast addresses > + * 2) 01-00-5e-00-00-XX Local Network Control Block > + * (224.0.0.0 - 224.0.0.255 (224.0.0/24)) > + */ > + icssg_class_ft1_add_mcast(miig_rt, slice, 0, > + eth_reserved_addr_base, mask_addr); > + icssg_class_ft1_add_mcast(miig_rt, slice, 1, > + eth_ipv4_mcast_addr_base, mask_addr); > + mask_addr[5] = 0; > + netdev_for_each_mc_addr(ha, ndev) { > + /* skip addresses matching reserved slots */ > + if (!memcmp(eth_reserved_addr_base, ha->addr, 5) || > + !memcmp(eth_ipv4_mcast_addr_base, ha->addr, 5)) { > + netdev_dbg(ndev, "mcast skip %pM\n", ha->addr); > + continue; > + } > + > + if (slot >= FT1_NUM_SLOTS) { > + netdev_dbg(ndev, > + "can't add more than %d MC addresses, enabling allmulti\n", > + FT1_NUM_SLOTS); > + icssg_class_default(miig_rt, slice, 1, true); > + break; > + } > + > + netdev_dbg(ndev, "mcast add %pM\n", ha->addr); > + icssg_class_ft1_add_mcast(miig_rt, slice, slot, > + ha->addr, mask_addr); > + slot++; > + } > +} > + > /* required for SAV check */ > void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) > { > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > index e6eac01f9f99..7d9db9683e18 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > @@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev) > icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); > icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); > > - icssg_class_default(prueth->miig_rt, slice, 0); > + icssg_class_default(prueth->miig_rt, slice, 0, false); Should you be passing emac->is_sr1 instead of false? > > /* Notify the stack of the actual queue counts. */ > ret = netif_set_real_num_tx_queues(ndev, num_data_chn); > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > index a8192e408941..faefd9351c39 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > @@ -283,7 +283,11 @@ extern const struct dev_pm_ops prueth_dev_pm_ops; > void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); > void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac); > void icssg_class_disable(struct regmap *miig_rt, int slice); > -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti); > +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, > + bool is_sr1); > +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice); > +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, > + struct net_device *ndev); > void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); > > /* config helpers */
On 21/02/2024 17:24, Diogo Ivo wrote: > Add the functions to configure the SR1.0 packet classifier. > > Based on the work of Roger Quadros in TI's 5.10 SDK [1]. > > [1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y > > Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> > --- > Changes in v3: > - Replace local variables in icssg_class_add_mcast_sr1() > with eth_reserved_addr_base and eth_ipv4_mcast_addr_base > > .../net/ethernet/ti/icssg/icssg_classifier.c | 113 ++++++++++++++++-- > drivers/net/ethernet/ti/icssg/icssg_prueth.c | 2 +- > drivers/net/ethernet/ti/icssg/icssg_prueth.h | 6 +- > 3 files changed, 110 insertions(+), 11 deletions(-) > > diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c > index 6df53ab17fbc..71b2f89ccd8e 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_classifier.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c > @@ -274,6 +274,16 @@ static void rx_class_set_or(struct regmap *miig_rt, int slice, int n, > regmap_write(miig_rt, offset, data); > } > > +static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n) > +{ > + u32 offset, val; > + > + offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); > + regmap_read(miig_rt, offset, &val); > + > + return val; > +} > + > void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac) > { > regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 | > @@ -288,6 +298,26 @@ void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) > regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8)); > } > > +static void icssg_class_ft1_add_mcast(struct regmap *miig_rt, int slice, > + int slot, const u8 *addr, const u8 *mask) > +{ > + int i; > + u32 val; > + > + WARN(slot >= FT1_NUM_SLOTS, "invalid slot: %d\n", slot); > + > + rx_class_ft1_set_da(miig_rt, slice, slot, addr); > + rx_class_ft1_set_da_mask(miig_rt, slice, slot, mask); > + rx_class_ft1_cfg_set_type(miig_rt, slice, slot, FT1_CFG_TYPE_EQ); > + > + /* Enable the FT1 slot in OR enable for all classifiers */ > + for (i = 0; i < ICSSG_NUM_CLASSIFIERS_IN_USE; i++) { > + val = rx_class_get_or(miig_rt, slice, i); > + val |= RX_CLASS_FT_FT1_MATCH(slot); > + rx_class_set_or(miig_rt, slice, i, val); > + } > +} > + > /* disable all RX traffic */ > void icssg_class_disable(struct regmap *miig_rt, int slice) > { > @@ -331,30 +361,95 @@ void icssg_class_disable(struct regmap *miig_rt, int slice) > regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); > } > > -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti) > +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, > + bool is_sr1) > { > + int num_classifiers = is_sr1 ? ICSSG_NUM_CLASSIFIERS_IN_USE : 1; > u32 data; > + int n; > > /* defaults */ > icssg_class_disable(miig_rt, slice); > > /* Setup Classifier */ > - /* match on Broadcast or MAC_PRU address */ > - data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; > + for (n = 0; n < num_classifiers; n++) { > + /* match on Broadcast or MAC_PRU address */ > + data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; > > - /* multicast */ > - if (allmulti) > - data |= RX_CLASS_FT_MC; > + /* multicast */ > + if (allmulti) > + data |= RX_CLASS_FT_MC; > > - rx_class_set_or(miig_rt, slice, 0, data); > + rx_class_set_or(miig_rt, slice, n, data); > > - /* set CFG1 for OR_OR_AND for classifier */ > - rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND); > + /* set CFG1 for OR_OR_AND for classifier */ > + rx_class_sel_set_type(miig_rt, slice, n, > + RX_CLASS_SEL_TYPE_OR_OR_AND); > + } > > /* clear CFG2 */ > regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); > } > > +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice) > +{ > + u32 data, offset; > + int n; > + > + /* defaults */ > + icssg_class_disable(miig_rt, slice); > + > + /* Setup Classifier */ > + for (n = 0; n < ICSSG_NUM_CLASSIFIERS_IN_USE; n++) { > + /* set RAW_MASK to bypass filters */ > + offset = RX_CLASS_GATES_N_REG(slice, n); > + regmap_read(miig_rt, offset, &data); > + data |= RX_CLASS_GATES_RAW_MASK; > + regmap_write(miig_rt, offset, data); > + } > +} > + > +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, > + struct net_device *ndev) > +{ > + u8 mask_addr[6] = { 0, 0, 0, 0, 0, 0xff }; > + struct netdev_hw_addr *ha; > + int slot = 2; > + > + rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); > + /* reserve first 2 slots for > + * 1) 01-80-C2-00-00-XX Known Service Ethernet Multicast addresses > + * 2) 01-00-5e-00-00-XX Local Network Control Block > + * (224.0.0.0 - 224.0.0.255 (224.0.0/24)) > + */ > + icssg_class_ft1_add_mcast(miig_rt, slice, 0, > + eth_reserved_addr_base, mask_addr); > + icssg_class_ft1_add_mcast(miig_rt, slice, 1, > + eth_ipv4_mcast_addr_base, mask_addr); Build fails with drivers/net/ethernet/ti/icssg/icssg_classifier.c:428:7: error: ‘eth_ipv4_mcast_addr_base’ undeclared (first use in this function) 428 | eth_ipv4_mcast_addr_base, mask_addr); | ^~~~~~~~~~~~~~~~~~~~~~~~ Is there a dependency patch? > + mask_addr[5] = 0; > + netdev_for_each_mc_addr(ha, ndev) { > + /* skip addresses matching reserved slots */ > + if (!memcmp(eth_reserved_addr_base, ha->addr, 5) || > + !memcmp(eth_ipv4_mcast_addr_base, ha->addr, 5)) { > + netdev_dbg(ndev, "mcast skip %pM\n", ha->addr); > + continue; > + } > + > + if (slot >= FT1_NUM_SLOTS) { > + netdev_dbg(ndev, > + "can't add more than %d MC addresses, enabling allmulti\n", > + FT1_NUM_SLOTS); > + icssg_class_default(miig_rt, slice, 1, true); > + break; > + } > + > + netdev_dbg(ndev, "mcast add %pM\n", ha->addr); > + icssg_class_ft1_add_mcast(miig_rt, slice, slot, > + ha->addr, mask_addr); > + slot++; > + } > +} > + > /* required for SAV check */ > void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) > { > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > index e6eac01f9f99..7d9db9683e18 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > @@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev) > icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); > icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); > > - icssg_class_default(prueth->miig_rt, slice, 0); > + icssg_class_default(prueth->miig_rt, slice, 0, false); > > /* Notify the stack of the actual queue counts. */ > ret = netif_set_real_num_tx_queues(ndev, num_data_chn); > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > index a8192e408941..faefd9351c39 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > @@ -283,7 +283,11 @@ extern const struct dev_pm_ops prueth_dev_pm_ops; > void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); > void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac); > void icssg_class_disable(struct regmap *miig_rt, int slice); > -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti); > +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, > + bool is_sr1); > +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice); > +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, > + struct net_device *ndev); > void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); > > /* config helpers */
On 2/26/24 17:26, Roger Quadros wrote: > > > On 21/02/2024 17:24, Diogo Ivo wrote: >> Add the functions to configure the SR1.0 packet classifier. >> >> Based on the work of Roger Quadros in TI's 5.10 SDK [1]. >> >> [1]: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.ti.com%2Fcgit%2Fti-linux-kernel%2Fti-linux-kernel%2Ftree%2F%3Fh%3Dti-linux-5.10.y&data=05%7C02%7Cdiogo.ivo%40siemens.com%7C5db0233cf1944b0b012808dc36f0214c%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638445652187413851%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=u4p0vZ6LCPScUuYuwCB2iJFm6uoz%2BDMesVWnTgwg1hs%3D&reserved=0 >> >> Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >> Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> >> --- >> Changes in v3: >> - Replace local variables in icssg_class_add_mcast_sr1() >> with eth_reserved_addr_base and eth_ipv4_mcast_addr_base >> ... >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c >> index e6eac01f9f99..7d9db9683e18 100644 >> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c >> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c >> @@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev) >> icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); >> icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); >> >> - icssg_class_default(prueth->miig_rt, slice, 0); >> + icssg_class_default(prueth->miig_rt, slice, 0, false); > > Should you be passing emac->is_sr1 instead of false? Given that this is the SR2.0 driver we know that bool is_sr1 will always be false, is there an advantage in passing emac->is_sr1 rather than false directly? Best regards, Diogo
On 2/26/24 18:41, Roger Quadros wrote: > > > On 21/02/2024 17:24, Diogo Ivo wrote: >> Add the functions to configure the SR1.0 packet classifier. >> >> Based on the work of Roger Quadros in TI's 5.10 SDK [1]. >> >> [1]: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.ti.com%2Fcgit%2Fti-linux-kernel%2Fti-linux-kernel%2Ftree%2F%3Fh%3Dti-linux-5.10.y&data=05%7C02%7Cdiogo.ivo%40siemens.com%7Ca43411e60ce048593e7408dc36fa7f73%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638445696707314198%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=v%2B%2FkgG1q31vJYa5a%2B5zYTbdxJbq5TKVOGT0Aavnk97Q%3D&reserved=0 >> >> Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >> Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> >> --- >> Changes in v3: >> - Replace local variables in icssg_class_add_mcast_sr1() >> with eth_reserved_addr_base and eth_ipv4_mcast_addr_base >> >> .../net/ethernet/ti/icssg/icssg_classifier.c | 113 ++++++++++++++++-- >> drivers/net/ethernet/ti/icssg/icssg_prueth.c | 2 +- >> drivers/net/ethernet/ti/icssg/icssg_prueth.h | 6 +- >> 3 files changed, 110 insertions(+), 11 deletions(-) ... > Build fails with > > drivers/net/ethernet/ti/icssg/icssg_classifier.c:428:7: error: ‘eth_ipv4_mcast_addr_base’ undeclared (first use in this function) > 428 | eth_ipv4_mcast_addr_base, mask_addr); > | ^~~~~~~~~~~~~~~~~~~~~~~~ > > Is there a dependency patch? Yes, this patch depends on patch 02/10 of the series, apologies for not mentioning it explicitly. Best regards, Diogo
On 27/02/2024 14:11, Diogo Ivo wrote: > On 2/26/24 17:26, Roger Quadros wrote: >> >> >> On 21/02/2024 17:24, Diogo Ivo wrote: >>> Add the functions to configure the SR1.0 packet classifier. >>> >>> Based on the work of Roger Quadros in TI's 5.10 SDK [1]. >>> >>> [1]: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.ti.com%2Fcgit%2Fti-linux-kernel%2Fti-linux-kernel%2Ftree%2F%3Fh%3Dti-linux-5.10.y&data=05%7C02%7Cdiogo.ivo%40siemens.com%7C5db0233cf1944b0b012808dc36f0214c%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638445652187413851%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=u4p0vZ6LCPScUuYuwCB2iJFm6uoz%2BDMesVWnTgwg1hs%3D&reserved=0 >>> >>> Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> >>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >>> Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> >>> --- >>> Changes in v3: >>> - Replace local variables in icssg_class_add_mcast_sr1() >>> with eth_reserved_addr_base and eth_ipv4_mcast_addr_base >>> > > ... > >>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c >>> index e6eac01f9f99..7d9db9683e18 100644 >>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c >>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c >>> @@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev) >>> icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); >>> icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); >>> - icssg_class_default(prueth->miig_rt, slice, 0); >>> + icssg_class_default(prueth->miig_rt, slice, 0, false); >> >> Should you be passing emac->is_sr1 instead of false? > > Given that this is the SR2.0 driver we know that bool is_sr1 will always > be false, is there an advantage in passing emac->is_sr1 rather than > false directly? Ah, no there isn't. You can leave it as it is.
On 27/02/2024 14:14, Diogo Ivo wrote: > On 2/26/24 18:41, Roger Quadros wrote: >> >> >> On 21/02/2024 17:24, Diogo Ivo wrote: >>> Add the functions to configure the SR1.0 packet classifier. >>> >>> Based on the work of Roger Quadros in TI's 5.10 SDK [1]. >>> >>> [1]: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.ti.com%2Fcgit%2Fti-linux-kernel%2Fti-linux-kernel%2Ftree%2F%3Fh%3Dti-linux-5.10.y&data=05%7C02%7Cdiogo.ivo%40siemens.com%7Ca43411e60ce048593e7408dc36fa7f73%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638445696707314198%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=v%2B%2FkgG1q31vJYa5a%2B5zYTbdxJbq5TKVOGT0Aavnk97Q%3D&reserved=0 >>> >>> Co-developed-by: Jan Kiszka <jan.kiszka@siemens.com> >>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >>> Signed-off-by: Diogo Ivo <diogo.ivo@siemens.com> >>> --- >>> Changes in v3: >>> - Replace local variables in icssg_class_add_mcast_sr1() >>> with eth_reserved_addr_base and eth_ipv4_mcast_addr_base >>> >>> .../net/ethernet/ti/icssg/icssg_classifier.c | 113 ++++++++++++++++-- >>> drivers/net/ethernet/ti/icssg/icssg_prueth.c | 2 +- >>> drivers/net/ethernet/ti/icssg/icssg_prueth.h | 6 +- >>> 3 files changed, 110 insertions(+), 11 deletions(-) > > ... > >> Build fails with >> >> drivers/net/ethernet/ti/icssg/icssg_classifier.c:428:7: error: ‘eth_ipv4_mcast_addr_base’ undeclared (first use in this function) >> 428 | eth_ipv4_mcast_addr_base, mask_addr); >> | ^~~~~~~~~~~~~~~~~~~~~~~~ >> >> Is there a dependency patch? > > Yes, this patch depends on patch 02/10 of the series, apologies for not > mentioning it explicitly. You don't have to mention it explicitly. Patc 2 didn't arrive at my inbox and I didn't notice it. It was my bad, sorry.
diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c index 6df53ab17fbc..71b2f89ccd8e 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_classifier.c +++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c @@ -274,6 +274,16 @@ static void rx_class_set_or(struct regmap *miig_rt, int slice, int n, regmap_write(miig_rt, offset, data); } +static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n) +{ + u32 offset, val; + + offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); + regmap_read(miig_rt, offset, &val); + + return val; +} + void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac) { regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 | @@ -288,6 +298,26 @@ void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8)); } +static void icssg_class_ft1_add_mcast(struct regmap *miig_rt, int slice, + int slot, const u8 *addr, const u8 *mask) +{ + int i; + u32 val; + + WARN(slot >= FT1_NUM_SLOTS, "invalid slot: %d\n", slot); + + rx_class_ft1_set_da(miig_rt, slice, slot, addr); + rx_class_ft1_set_da_mask(miig_rt, slice, slot, mask); + rx_class_ft1_cfg_set_type(miig_rt, slice, slot, FT1_CFG_TYPE_EQ); + + /* Enable the FT1 slot in OR enable for all classifiers */ + for (i = 0; i < ICSSG_NUM_CLASSIFIERS_IN_USE; i++) { + val = rx_class_get_or(miig_rt, slice, i); + val |= RX_CLASS_FT_FT1_MATCH(slot); + rx_class_set_or(miig_rt, slice, i, val); + } +} + /* disable all RX traffic */ void icssg_class_disable(struct regmap *miig_rt, int slice) { @@ -331,30 +361,95 @@ void icssg_class_disable(struct regmap *miig_rt, int slice) regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); } -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti) +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, + bool is_sr1) { + int num_classifiers = is_sr1 ? ICSSG_NUM_CLASSIFIERS_IN_USE : 1; u32 data; + int n; /* defaults */ icssg_class_disable(miig_rt, slice); /* Setup Classifier */ - /* match on Broadcast or MAC_PRU address */ - data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; + for (n = 0; n < num_classifiers; n++) { + /* match on Broadcast or MAC_PRU address */ + data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; - /* multicast */ - if (allmulti) - data |= RX_CLASS_FT_MC; + /* multicast */ + if (allmulti) + data |= RX_CLASS_FT_MC; - rx_class_set_or(miig_rt, slice, 0, data); + rx_class_set_or(miig_rt, slice, n, data); - /* set CFG1 for OR_OR_AND for classifier */ - rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND); + /* set CFG1 for OR_OR_AND for classifier */ + rx_class_sel_set_type(miig_rt, slice, n, + RX_CLASS_SEL_TYPE_OR_OR_AND); + } /* clear CFG2 */ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); } +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice) +{ + u32 data, offset; + int n; + + /* defaults */ + icssg_class_disable(miig_rt, slice); + + /* Setup Classifier */ + for (n = 0; n < ICSSG_NUM_CLASSIFIERS_IN_USE; n++) { + /* set RAW_MASK to bypass filters */ + offset = RX_CLASS_GATES_N_REG(slice, n); + regmap_read(miig_rt, offset, &data); + data |= RX_CLASS_GATES_RAW_MASK; + regmap_write(miig_rt, offset, data); + } +} + +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, + struct net_device *ndev) +{ + u8 mask_addr[6] = { 0, 0, 0, 0, 0, 0xff }; + struct netdev_hw_addr *ha; + int slot = 2; + + rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); + /* reserve first 2 slots for + * 1) 01-80-C2-00-00-XX Known Service Ethernet Multicast addresses + * 2) 01-00-5e-00-00-XX Local Network Control Block + * (224.0.0.0 - 224.0.0.255 (224.0.0/24)) + */ + icssg_class_ft1_add_mcast(miig_rt, slice, 0, + eth_reserved_addr_base, mask_addr); + icssg_class_ft1_add_mcast(miig_rt, slice, 1, + eth_ipv4_mcast_addr_base, mask_addr); + mask_addr[5] = 0; + netdev_for_each_mc_addr(ha, ndev) { + /* skip addresses matching reserved slots */ + if (!memcmp(eth_reserved_addr_base, ha->addr, 5) || + !memcmp(eth_ipv4_mcast_addr_base, ha->addr, 5)) { + netdev_dbg(ndev, "mcast skip %pM\n", ha->addr); + continue; + } + + if (slot >= FT1_NUM_SLOTS) { + netdev_dbg(ndev, + "can't add more than %d MC addresses, enabling allmulti\n", + FT1_NUM_SLOTS); + icssg_class_default(miig_rt, slice, 1, true); + break; + } + + netdev_dbg(ndev, "mcast add %pM\n", ha->addr); + icssg_class_ft1_add_mcast(miig_rt, slice, slot, + ha->addr, mask_addr); + slot++; + } +} + /* required for SAV check */ void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) { diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index e6eac01f9f99..7d9db9683e18 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev) icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); - icssg_class_default(prueth->miig_rt, slice, 0); + icssg_class_default(prueth->miig_rt, slice, 0, false); /* Notify the stack of the actual queue counts. */ ret = netif_set_real_num_tx_queues(ndev, num_data_chn); diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h index a8192e408941..faefd9351c39 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -283,7 +283,11 @@ extern const struct dev_pm_ops prueth_dev_pm_ops; void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac); void icssg_class_disable(struct regmap *miig_rt, int slice); -void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti); +void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, + bool is_sr1); +void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice); +void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, + struct net_device *ndev); void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); /* config helpers */