Skip to content

Commit 1b02a2b

Browse files
Murali KaricheriNipaLocal
authored andcommitted
net: ti: prueth: Adds support for RX interrupt coalescing/pacing
Changes for supporting RX interrupt pacing feature using eCAP peripheral available in PRU-ICSS. Instead of interrupting the CPU for every packet received, the firmware running on the PRU-ICSS will interrupt the CPU based on the configured time period, if interrupt pacing is enabled. The time period can be configured using ethtool. RX pacing/coalescing is implemented Using eCAP timer events to give CPU breathing space from ISR to perform other critical tasks. The changes include new eCAP driver module which will initialization and configures the ICSS eCAP HW. Makefile and Kernel config has been updated to compile the eCAP driver and to insert the module. Signed-off-by: Murali Karicheri <[email protected]> Signed-off-by: Basharath Hussain Khaja <[email protected]> Signed-off-by: Parvathi Pudi <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent a5b78b6 commit 1b02a2b

File tree

8 files changed

+461
-1
lines changed

8 files changed

+461
-1
lines changed

drivers/net/ethernet/ti/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@ config TI_ICSS_IEP
229229
To compile this driver as a module, choose M here. The module
230230
will be called icss_iep.
231231

232+
config TI_PRUETH_ECAP
233+
tristate "TI PRUETH ECAP driver"
234+
depends on TI_PRUSS
235+
default TI_PRUSS
236+
help
237+
This enables support for the PRU-ICSS Enhanced Capture (eCAP) driver
238+
used for rx interrupt pacing support in PRU Driver/firmwares
239+
(Dual EMAC, HSR, PRP).
240+
241+
To compile this driver as a module, choose M here. The module
242+
will be called prueth_ecap.
243+
232244
config TI_PRUETH
233245
tristate "TI PRU Ethernet EMAC driver"
234246
depends on PRU_REMOTEPROC

drivers/net/ethernet/ti/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,5 @@ icssg-y := icssg/icssg_common.o \
4949
icssg/icssg_ethtool.o
5050

5151
obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o
52+
53+
obj-$(CONFIG_TI_PRUETH_ECAP) += icssm/icssm_prueth_ecap.o

drivers/net/ethernet/ti/icssm/icssm_ethtool.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/if_bridge.h>
99
#include <linux/if_vlan.h>
1010
#include "icssm_prueth.h"
11+
#include "icssm_prueth_ecap.h"
1112
#include "icssm_vlan_mcast_filter_mmap.h"
1213
#include "../icssg/icss_iep.h"
1314

@@ -281,6 +282,40 @@ static int icssm_emac_get_ts_info(struct net_device *ndev,
281282
return 0;
282283
}
283284

285+
static int icssm_emac_get_coalesce(struct net_device *ndev,
286+
struct ethtool_coalesce *coal,
287+
struct kernel_ethtool_coalesce *kernel_coal,
288+
struct netlink_ext_ack *extack)
289+
{
290+
struct prueth_emac *emac = netdev_priv(ndev);
291+
struct prueth *prueth = emac->prueth;
292+
struct prueth_ecap *ecap;
293+
294+
ecap = prueth->ecap;
295+
if (IS_ERR(ecap))
296+
return -EOPNOTSUPP;
297+
298+
return ecap->get_coalesce(emac, &coal->use_adaptive_rx_coalesce,
299+
&coal->rx_coalesce_usecs);
300+
}
301+
302+
static int icssm_emac_set_coalesce(struct net_device *ndev,
303+
struct ethtool_coalesce *coal,
304+
struct kernel_ethtool_coalesce *kernel_coal,
305+
struct netlink_ext_ack *extack)
306+
{
307+
struct prueth_emac *emac = netdev_priv(ndev);
308+
struct prueth *prueth = emac->prueth;
309+
struct prueth_ecap *ecap;
310+
311+
ecap = prueth->ecap;
312+
if (IS_ERR(ecap))
313+
return -EOPNOTSUPP;
314+
315+
return ecap->set_coalesce(emac, coal->use_adaptive_rx_coalesce,
316+
coal->rx_coalesce_usecs);
317+
}
318+
284319
/* Ethtool support for EMAC adapter */
285320
const struct ethtool_ops emac_ethtool_ops = {
286321
.get_drvinfo = icssm_emac_get_drvinfo,
@@ -295,5 +330,8 @@ const struct ethtool_ops emac_ethtool_ops = {
295330
.get_rmon_stats = icssm_emac_get_rmon_stats,
296331
.get_eth_mac_stats = icssm_emac_get_eth_mac_stats,
297332
.get_ts_info = icssm_emac_get_ts_info,
333+
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
334+
.get_coalesce = icssm_emac_get_coalesce,
335+
.set_coalesce = icssm_emac_set_coalesce,
298336
};
299337
EXPORT_SYMBOL_GPL(emac_ethtool_ops);

drivers/net/ethernet/ti/icssm/icssm_prueth.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "icssm_prueth.h"
3232
#include "icssm_vlan_mcast_filter_mmap.h"
33+
#include "icssm_prueth_ecap.h"
3334
#include "../icssg/icssg_mii_rt.h"
3435
#include "../icssg/icss_iep.h"
3536

@@ -1222,8 +1223,10 @@ static int icssm_emac_ndo_open(struct net_device *ndev)
12221223
{
12231224
struct prueth_emac *emac = netdev_priv(ndev);
12241225
struct prueth *prueth = emac->prueth;
1226+
struct prueth_ecap *ecap;
12251227
int ret;
12261228

1229+
ecap = prueth->ecap;
12271230
/* set h/w MAC as user might have re-configured */
12281231
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
12291232

@@ -1233,6 +1236,9 @@ static int icssm_emac_ndo_open(struct net_device *ndev)
12331236
icssm_prueth_emac_config(emac);
12341237

12351238
icssm_emac_set_stats(emac, &emac->stats);
1239+
/* initialize ecap for interrupt pacing */
1240+
if (!IS_ERR(ecap))
1241+
ecap->init(emac);
12361242

12371243
if (!prueth->emac_configured) {
12381244
icssm_iptp_dram_init(emac);
@@ -2179,12 +2185,25 @@ static int icssm_prueth_probe(struct platform_device *pdev)
21792185
goto netdev_exit;
21802186
}
21812187

2188+
/* Make rx interrupt pacing optional so that users can use ECAP for
2189+
* other use cases if needed
2190+
*/
2191+
prueth->ecap = icssm_prueth_ecap_get(np);
2192+
if (IS_ERR(prueth->ecap)) {
2193+
ret = PTR_ERR(prueth->ecap);
2194+
if (ret != -EPROBE_DEFER)
2195+
dev_info(dev,
2196+
"No ECAP. Rx interrupt pacing disabled\n");
2197+
else
2198+
goto iep_put;
2199+
}
2200+
21822201
/* register the network devices */
21832202
if (eth0_node) {
21842203
ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
21852204
if (ret) {
21862205
dev_err(dev, "can't register netdev for port MII0");
2187-
goto iep_put;
2206+
goto ecap_put;
21882207
}
21892208

21902209
prueth->registered_netdevs[PRUETH_MAC0] =
@@ -2220,6 +2239,10 @@ static int icssm_prueth_probe(struct platform_device *pdev)
22202239
unregister_netdev(prueth->registered_netdevs[i]);
22212240
}
22222241

2242+
ecap_put:
2243+
if (!IS_ERR(prueth->ecap))
2244+
icssm_prueth_ecap_put(prueth->ecap);
2245+
22232246
iep_put:
22242247
icss_iep_put(prueth->iep);
22252248

drivers/net/ethernet/ti/icssm/icssm_prueth.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/types.h>
1313
#include <linux/pruss_driver.h>
1414
#include <linux/remoteproc/pruss.h>
15+
#include <linux/netdevice.h>
1516

1617
#include "icssm_switch.h"
1718
#include "icssm_prueth_ptp.h"
@@ -403,6 +404,7 @@ struct prueth {
403404
struct regmap *mii_rt;
404405
struct icss_iep *iep;
405406

407+
struct prueth_ecap *ecap;
406408
const struct prueth_private_data *fw_data;
407409
struct prueth_fw_offsets *fw_offsets;
408410

@@ -412,6 +414,7 @@ struct prueth {
412414

413415
unsigned int eth_type;
414416
size_t ocmc_ram_size;
417+
struct mutex mlock; /* serialize access */
415418
u8 emac_configured;
416419
u8 base_mac[ETH_ALEN];
417420
};

0 commit comments

Comments
 (0)