Message ID | 20240221152421.112324-10-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: > Some parts of the logic differ only slightly between Silicon Revisions. > In these cases add the bits that differ to a common function that > executes those bits conditionally based on the Silicon Revision. > > Based on the work of Roger Quadros, Vignesh Raghavendra and > Grygorii Strashko 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> > --- > drivers/net/ethernet/ti/icssg/icssg_common.c | 46 +++++++++++++++----- > drivers/net/ethernet/ti/icssg/icssg_prueth.c | 4 +- > drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 +- > 3 files changed, 38 insertions(+), 14 deletions(-) > > diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c > index 99f27ecc9352..d4488cf5d7da 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_common.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c > @@ -152,6 +152,13 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn, > desc_dma); > swdata = cppi5_hdesc_get_swdata(desc_tx); > > + /* was this command's TX complete? */ > + if (emac->is_sr1 && *(swdata) == emac->cmd_data) { > + prueth_xmit_free(tx_chn, desc_tx); > + budget++; /* not a data packet */ > + continue; > + } > + > skb = *(swdata); > prueth_xmit_free(tx_chn, desc_tx); > > @@ -327,6 +334,7 @@ int prueth_init_rx_chns(struct prueth_emac *emac, > struct net_device *ndev = emac->ndev; > u32 fdqring_id, hdesc_size; > int i, ret = 0, slice; > + int flow_id_base; > > slice = prueth_emac_slice(emac); > if (slice < 0) > @@ -367,8 +375,14 @@ int prueth_init_rx_chns(struct prueth_emac *emac, > goto fail; > } > > - emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); > - netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base); > + flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); > + if (!strcmp(name, "rxmgm")) { if (emac->is_sr1 && !strcmp(name, "rxmgm")) ? > + emac->rx_mgm_flow_id_base = flow_id_base; > + netdev_dbg(ndev, "mgm flow id base = %d\n", flow_id_base); > + } else { > + emac->rx_flow_id_base = flow_id_base; > + netdev_dbg(ndev, "flow id base = %d\n", flow_id_base); > + } > > fdqring_id = K3_RINGACC_RING_ID_ANY; > for (i = 0; i < rx_cfg.flow_id_num; i++) { > @@ -477,10 +491,14 @@ void emac_rx_timestamp(struct prueth_emac *emac, > struct skb_shared_hwtstamps *ssh; > u64 ns; > > - u32 hi_sw = readl(emac->prueth->shram.va + > - TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); > - ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], > - IEP_DEFAULT_CYCLE_TIME_NS); > + if (emac->is_sr1) { > + ns = (u64)psdata[1] << 32 | psdata[0]; > + } else { > + u32 hi_sw = readl(emac->prueth->shram.va + > + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); > + ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], > + IEP_DEFAULT_CYCLE_TIME_NS); > + } > > ssh = skb_hwtstamps(skb); > memset(ssh, 0, sizeof(*ssh)); > @@ -809,7 +827,8 @@ void prueth_emac_stop(struct prueth_emac *emac) > } > > emac->fw_running = 0; > - rproc_shutdown(prueth->txpru[slice]); > + if (!emac->is_sr1) > + rproc_shutdown(prueth->txpru[slice]); > rproc_shutdown(prueth->rtu[slice]); > rproc_shutdown(prueth->pru[slice]); > } > @@ -829,8 +848,10 @@ void prueth_cleanup_tx_ts(struct prueth_emac *emac) > int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) > { > struct prueth_emac *emac = prueth_napi_to_emac(napi_rx); > - int rx_flow = PRUETH_RX_FLOW_DATA; > - int flow = PRUETH_MAX_RX_FLOWS; > + int rx_flow = emac->is_sr1 ? > + PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA; > + int flow = emac->is_sr1 ? > + PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS; > int num_rx = 0; > int cur_budget; > int ret; > @@ -1082,7 +1103,7 @@ void prueth_netdev_exit(struct prueth *prueth, > prueth->emac[mac] = NULL; > } > > -int prueth_get_cores(struct prueth *prueth, int slice) > +int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1) > { > struct device *dev = prueth->dev; > enum pruss_pru_id pruss_id; > @@ -1096,7 +1117,7 @@ int prueth_get_cores(struct prueth *prueth, int slice) > idx = 0; > break; > case ICSS_SLICE1: > - idx = 3; > + idx = is_sr1 ? 2 : 3; > break; > default: > return -EINVAL; > @@ -1118,6 +1139,9 @@ int prueth_get_cores(struct prueth *prueth, int slice) > return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice); > } > > + if (is_sr1) > + return 0; > + > idx++; > prueth->txpru[slice] = pru_rproc_get(np, idx, NULL); > if (IS_ERR(prueth->txpru[slice])) { > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > index 7d9db9683e18..5eab0657494c 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > @@ -907,13 +907,13 @@ static int prueth_probe(struct platform_device *pdev) > } > > if (eth0_node) { > - ret = prueth_get_cores(prueth, ICSS_SLICE0); > + ret = prueth_get_cores(prueth, ICSS_SLICE0, true); Isn't this SR2.0 device driver? so is_sr1 parameter should be false? > if (ret) > goto put_cores; > } > > if (eth1_node) { > - ret = prueth_get_cores(prueth, ICSS_SLICE1); > + ret = prueth_get_cores(prueth, ICSS_SLICE1, true); here too? > if (ret) > goto put_cores; > } > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > index faefd9351c39..d706460f2ca3 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h > @@ -354,7 +354,7 @@ int prueth_node_port(struct device_node *eth_node); > int prueth_node_mac(struct device_node *eth_node); > void prueth_netdev_exit(struct prueth *prueth, > struct device_node *eth_node); > -int prueth_get_cores(struct prueth *prueth, int slice); > +int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1); > void prueth_put_cores(struct prueth *prueth, int slice); > > /* Revision specific helper */
On 2/26/24 17:33, Roger Quadros wrote: > > > On 21/02/2024 17:24, Diogo Ivo wrote: >> Some parts of the logic differ only slightly between Silicon Revisions. >> In these cases add the bits that differ to a common function that >> executes those bits conditionally based on the Silicon Revision. >> >> Based on the work of Roger Quadros, Vignesh Raghavendra and >> Grygorii Strashko 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%7C44253ecc112a4f939f5e08dc36f11754%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638445656302550240%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=kXkC6HubTh0yeftDSzmIy47tJmlnISQjMbWoOqvEAx0%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> >> --- >> drivers/net/ethernet/ti/icssg/icssg_common.c | 46 +++++++++++++++----- >> drivers/net/ethernet/ti/icssg/icssg_prueth.c | 4 +- >> drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 +- >> 3 files changed, 38 insertions(+), 14 deletions(-) >> >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c ... >> - emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); >> - netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base); >> + flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); >> + if (!strcmp(name, "rxmgm")) { > > if (emac->is_sr1 && !strcmp(name, "rxmgm")) ? Since technically the DT should only contain "rxmgm" for SR1.0 I did not add the emac->is_sr1 check but it can't hurt to be safer so I'll add it. ... >> if (eth0_node) { >> - ret = prueth_get_cores(prueth, ICSS_SLICE0); >> + ret = prueth_get_cores(prueth, ICSS_SLICE0, true); > > Isn't this SR2.0 device driver? so is_sr1 parameter should be false? > >> if (ret) >> goto put_cores; >> } >> >> if (eth1_node) { >> - ret = prueth_get_cores(prueth, ICSS_SLICE1); >> + ret = prueth_get_cores(prueth, ICSS_SLICE1, true); > > here too? Yes, you are correct, thank you for catching that. Best regards, Diogo
diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c index 99f27ecc9352..d4488cf5d7da 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_common.c +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c @@ -152,6 +152,13 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn, desc_dma); swdata = cppi5_hdesc_get_swdata(desc_tx); + /* was this command's TX complete? */ + if (emac->is_sr1 && *(swdata) == emac->cmd_data) { + prueth_xmit_free(tx_chn, desc_tx); + budget++; /* not a data packet */ + continue; + } + skb = *(swdata); prueth_xmit_free(tx_chn, desc_tx); @@ -327,6 +334,7 @@ int prueth_init_rx_chns(struct prueth_emac *emac, struct net_device *ndev = emac->ndev; u32 fdqring_id, hdesc_size; int i, ret = 0, slice; + int flow_id_base; slice = prueth_emac_slice(emac); if (slice < 0) @@ -367,8 +375,14 @@ int prueth_init_rx_chns(struct prueth_emac *emac, goto fail; } - emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); - netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base); + flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); + if (!strcmp(name, "rxmgm")) { + emac->rx_mgm_flow_id_base = flow_id_base; + netdev_dbg(ndev, "mgm flow id base = %d\n", flow_id_base); + } else { + emac->rx_flow_id_base = flow_id_base; + netdev_dbg(ndev, "flow id base = %d\n", flow_id_base); + } fdqring_id = K3_RINGACC_RING_ID_ANY; for (i = 0; i < rx_cfg.flow_id_num; i++) { @@ -477,10 +491,14 @@ void emac_rx_timestamp(struct prueth_emac *emac, struct skb_shared_hwtstamps *ssh; u64 ns; - u32 hi_sw = readl(emac->prueth->shram.va + - TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); - ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], - IEP_DEFAULT_CYCLE_TIME_NS); + if (emac->is_sr1) { + ns = (u64)psdata[1] << 32 | psdata[0]; + } else { + u32 hi_sw = readl(emac->prueth->shram.va + + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); + ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], + IEP_DEFAULT_CYCLE_TIME_NS); + } ssh = skb_hwtstamps(skb); memset(ssh, 0, sizeof(*ssh)); @@ -809,7 +827,8 @@ void prueth_emac_stop(struct prueth_emac *emac) } emac->fw_running = 0; - rproc_shutdown(prueth->txpru[slice]); + if (!emac->is_sr1) + rproc_shutdown(prueth->txpru[slice]); rproc_shutdown(prueth->rtu[slice]); rproc_shutdown(prueth->pru[slice]); } @@ -829,8 +848,10 @@ void prueth_cleanup_tx_ts(struct prueth_emac *emac) int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) { struct prueth_emac *emac = prueth_napi_to_emac(napi_rx); - int rx_flow = PRUETH_RX_FLOW_DATA; - int flow = PRUETH_MAX_RX_FLOWS; + int rx_flow = emac->is_sr1 ? + PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA; + int flow = emac->is_sr1 ? + PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS; int num_rx = 0; int cur_budget; int ret; @@ -1082,7 +1103,7 @@ void prueth_netdev_exit(struct prueth *prueth, prueth->emac[mac] = NULL; } -int prueth_get_cores(struct prueth *prueth, int slice) +int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1) { struct device *dev = prueth->dev; enum pruss_pru_id pruss_id; @@ -1096,7 +1117,7 @@ int prueth_get_cores(struct prueth *prueth, int slice) idx = 0; break; case ICSS_SLICE1: - idx = 3; + idx = is_sr1 ? 2 : 3; break; default: return -EINVAL; @@ -1118,6 +1139,9 @@ int prueth_get_cores(struct prueth *prueth, int slice) return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice); } + if (is_sr1) + return 0; + idx++; prueth->txpru[slice] = pru_rproc_get(np, idx, NULL); if (IS_ERR(prueth->txpru[slice])) { diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 7d9db9683e18..5eab0657494c 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -907,13 +907,13 @@ static int prueth_probe(struct platform_device *pdev) } if (eth0_node) { - ret = prueth_get_cores(prueth, ICSS_SLICE0); + ret = prueth_get_cores(prueth, ICSS_SLICE0, true); if (ret) goto put_cores; } if (eth1_node) { - ret = prueth_get_cores(prueth, ICSS_SLICE1); + ret = prueth_get_cores(prueth, ICSS_SLICE1, true); if (ret) goto put_cores; } diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h index faefd9351c39..d706460f2ca3 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -354,7 +354,7 @@ int prueth_node_port(struct device_node *eth_node); int prueth_node_mac(struct device_node *eth_node); void prueth_netdev_exit(struct prueth *prueth, struct device_node *eth_node); -int prueth_get_cores(struct prueth *prueth, int slice); +int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1); void prueth_put_cores(struct prueth *prueth, int slice); /* Revision specific helper */