Skip to content

Commit d4671cb

Browse files
committed
Merge branch 'lan966x-tx-rx-improve'
Horatiu Vultur says: ==================== net: lan966x: Improve TX/RX of frames from/to CPU The first patch of this series improves the RX side. As it seems to be an expensive operation to read the RX timestamp for every frame, then read it only if it is required. This will give an improvement of ~70mbit on the RX side. The second patch stops using the packing library. This improves mostly the TX side as this library is used to set diffent bits in the IFH. If this library is replaced with a more simple/shorter implementation, this gives an improvement of more than 100mbit on TX side. All the measurements were done using iperf3. v1->v2: - update lan966x_ifh_set to set the bytes and not each bit individually ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 105a201 + fd76278 commit d4671cb

File tree

5 files changed

+65
-39
lines changed

5 files changed

+65
-39
lines changed

drivers/net/ethernet/microchip/lan966x/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ config LAN966X_SWITCH
66
depends on NET_SWITCHDEV
77
depends on BRIDGE || BRIDGE=n
88
select PHYLINK
9-
select PACKING
109
select PAGE_POOL
1110
select VCAP
1211
help

drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
517517
if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
518518
skb_trim(skb, skb->len - ETH_FCS_LEN);
519519

520-
lan966x_ptp_rxtstamp(lan966x, skb, timestamp);
520+
lan966x_ptp_rxtstamp(lan966x, skb, src_port, timestamp);
521521
skb->protocol = eth_type_trans(skb, skb->dev);
522522

523523
if (lan966x->bridge_mask & BIT(src_port)) {

drivers/net/ethernet/microchip/lan966x/lan966x_main.c

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <linux/ip.h>
88
#include <linux/of_platform.h>
99
#include <linux/of_net.h>
10-
#include <linux/packing.h>
1110
#include <linux/phy/phy.h>
1211
#include <linux/reset.h>
1312
#include <net/addrconf.h>
@@ -305,46 +304,57 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
305304
return NETDEV_TX_BUSY;
306305
}
307306

307+
static void lan966x_ifh_set(u8 *ifh, size_t val, size_t pos, size_t length)
308+
{
309+
int i = 0;
310+
311+
do {
312+
u8 p = IFH_LEN_BYTES - (pos + i) / 8 - 1;
313+
u8 v = val >> i & 0xff;
314+
315+
/* There is no need to check for limits of the array, as these
316+
* will never be written
317+
*/
318+
ifh[p] |= v << ((pos + i) % 8);
319+
ifh[p - 1] |= v >> (8 - (pos + i) % 8);
320+
321+
i += 8;
322+
} while (i < length);
323+
}
324+
308325
void lan966x_ifh_set_bypass(void *ifh, u64 bypass)
309326
{
310-
packing(ifh, &bypass, IFH_POS_BYPASS + IFH_WID_BYPASS - 1,
311-
IFH_POS_BYPASS, IFH_LEN * 4, PACK, 0);
327+
lan966x_ifh_set(ifh, bypass, IFH_POS_BYPASS, IFH_WID_BYPASS);
312328
}
313329

314-
void lan966x_ifh_set_port(void *ifh, u64 bypass)
330+
void lan966x_ifh_set_port(void *ifh, u64 port)
315331
{
316-
packing(ifh, &bypass, IFH_POS_DSTS + IFH_WID_DSTS - 1,
317-
IFH_POS_DSTS, IFH_LEN * 4, PACK, 0);
332+
lan966x_ifh_set(ifh, port, IFH_POS_DSTS, IFH_WID_DSTS);
318333
}
319334

320-
static void lan966x_ifh_set_qos_class(void *ifh, u64 bypass)
335+
static void lan966x_ifh_set_qos_class(void *ifh, u64 qos)
321336
{
322-
packing(ifh, &bypass, IFH_POS_QOS_CLASS + IFH_WID_QOS_CLASS - 1,
323-
IFH_POS_QOS_CLASS, IFH_LEN * 4, PACK, 0);
337+
lan966x_ifh_set(ifh, qos, IFH_POS_QOS_CLASS, IFH_WID_QOS_CLASS);
324338
}
325339

326-
static void lan966x_ifh_set_ipv(void *ifh, u64 bypass)
340+
static void lan966x_ifh_set_ipv(void *ifh, u64 ipv)
327341
{
328-
packing(ifh, &bypass, IFH_POS_IPV + IFH_WID_IPV - 1,
329-
IFH_POS_IPV, IFH_LEN * 4, PACK, 0);
342+
lan966x_ifh_set(ifh, ipv, IFH_POS_IPV, IFH_WID_IPV);
330343
}
331344

332345
static void lan966x_ifh_set_vid(void *ifh, u64 vid)
333346
{
334-
packing(ifh, &vid, IFH_POS_TCI + IFH_WID_TCI - 1,
335-
IFH_POS_TCI, IFH_LEN * 4, PACK, 0);
347+
lan966x_ifh_set(ifh, vid, IFH_POS_TCI, IFH_WID_TCI);
336348
}
337349

338350
static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
339351
{
340-
packing(ifh, &rew_op, IFH_POS_REW_CMD + IFH_WID_REW_CMD - 1,
341-
IFH_POS_REW_CMD, IFH_LEN * 4, PACK, 0);
352+
lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD);
342353
}
343354

344355
static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
345356
{
346-
packing(ifh, &timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1,
347-
IFH_POS_TIMESTAMP, IFH_LEN * 4, PACK, 0);
357+
lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP);
348358
}
349359

350360
static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
@@ -582,22 +592,38 @@ static int lan966x_rx_frame_word(struct lan966x *lan966x, u8 grp, u32 *rval)
582592
}
583593
}
584594

595+
static u64 lan966x_ifh_get(u8 *ifh, size_t pos, size_t length)
596+
{
597+
u64 val = 0;
598+
u8 v;
599+
600+
for (int i = 0; i < length ; i++) {
601+
int j = pos + i;
602+
int k = j % 8;
603+
604+
if (i == 0 || k == 0)
605+
v = ifh[IFH_LEN_BYTES - (j / 8) - 1];
606+
607+
if (v & (1 << k))
608+
val |= (1 << i);
609+
}
610+
611+
return val;
612+
}
613+
585614
void lan966x_ifh_get_src_port(void *ifh, u64 *src_port)
586615
{
587-
packing(ifh, src_port, IFH_POS_SRCPORT + IFH_WID_SRCPORT - 1,
588-
IFH_POS_SRCPORT, IFH_LEN * 4, UNPACK, 0);
616+
*src_port = lan966x_ifh_get(ifh, IFH_POS_SRCPORT, IFH_WID_SRCPORT);
589617
}
590618

591619
static void lan966x_ifh_get_len(void *ifh, u64 *len)
592620
{
593-
packing(ifh, len, IFH_POS_LEN + IFH_WID_LEN - 1,
594-
IFH_POS_LEN, IFH_LEN * 4, UNPACK, 0);
621+
*len = lan966x_ifh_get(ifh, IFH_POS_LEN, IFH_WID_LEN);
595622
}
596623

597624
void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp)
598625
{
599-
packing(ifh, timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1,
600-
IFH_POS_TIMESTAMP, IFH_LEN * 4, UNPACK, 0);
626+
*timestamp = lan966x_ifh_get(ifh, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP);
601627
}
602628

603629
static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
@@ -668,7 +694,7 @@ static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
668694
*buf = val;
669695
}
670696

671-
lan966x_ptp_rxtstamp(lan966x, skb, timestamp);
697+
lan966x_ptp_rxtstamp(lan966x, skb, src_port, timestamp);
672698
skb->protocol = eth_type_trans(skb, dev);
673699

674700
if (lan966x->bridge_mask & BIT(src_port)) {

drivers/net/ethernet/microchip/lan966x/lan966x_main.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ struct lan966x_port {
407407
struct phy *serdes;
408408
struct fwnode_handle *fwnode;
409409

410-
u8 ptp_cmd;
410+
u8 ptp_tx_cmd;
411+
bool ptp_rx_cmd;
411412
u16 ts_id;
412413
struct sk_buff_head tx_skbs;
413414

@@ -527,7 +528,7 @@ void lan966x_ptp_deinit(struct lan966x *lan966x);
527528
int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr);
528529
int lan966x_ptp_hwtstamp_get(struct lan966x_port *port, struct ifreq *ifr);
529530
void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
530-
u64 timestamp);
531+
u64 src_port, u64 timestamp);
531532
int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
532533
struct sk_buff *skb);
533534
void lan966x_ptp_txtstamp_release(struct lan966x_port *port,

drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,21 @@ int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr)
272272

273273
switch (cfg.tx_type) {
274274
case HWTSTAMP_TX_ON:
275-
port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
275+
port->ptp_tx_cmd = IFH_REW_OP_TWO_STEP_PTP;
276276
break;
277277
case HWTSTAMP_TX_ONESTEP_SYNC:
278-
port->ptp_cmd = IFH_REW_OP_ONE_STEP_PTP;
278+
port->ptp_tx_cmd = IFH_REW_OP_ONE_STEP_PTP;
279279
break;
280280
case HWTSTAMP_TX_OFF:
281-
port->ptp_cmd = IFH_REW_OP_NOOP;
281+
port->ptp_tx_cmd = IFH_REW_OP_NOOP;
282282
break;
283283
default:
284284
return -ERANGE;
285285
}
286286

287287
switch (cfg.rx_filter) {
288288
case HWTSTAMP_FILTER_NONE:
289+
port->ptp_rx_cmd = false;
289290
break;
290291
case HWTSTAMP_FILTER_ALL:
291292
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
@@ -301,6 +302,7 @@ int lan966x_ptp_hwtstamp_set(struct lan966x_port *port, struct ifreq *ifr)
301302
case HWTSTAMP_FILTER_PTP_V2_SYNC:
302303
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
303304
case HWTSTAMP_FILTER_NTP_ALL:
305+
port->ptp_rx_cmd = true;
304306
cfg.rx_filter = HWTSTAMP_FILTER_ALL;
305307
break;
306308
default:
@@ -332,7 +334,7 @@ static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
332334
u8 msgtype;
333335
int type;
334336

335-
if (port->ptp_cmd == IFH_REW_OP_NOOP)
337+
if (port->ptp_tx_cmd == IFH_REW_OP_NOOP)
336338
return IFH_REW_OP_NOOP;
337339

338340
type = ptp_classify_raw(skb);
@@ -343,7 +345,7 @@ static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
343345
if (!header)
344346
return IFH_REW_OP_NOOP;
345347

346-
if (port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
348+
if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP)
347349
return IFH_REW_OP_TWO_STEP_PTP;
348350

349351
/* If it is sync and run 1 step then set the correct operation,
@@ -1009,9 +1011,6 @@ static int lan966x_ptp_phc_init(struct lan966x *lan966x,
10091011
phc->index = index;
10101012
phc->lan966x = lan966x;
10111013

1012-
/* PTP Rx stamping is always enabled. */
1013-
phc->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
1014-
10151014
return 0;
10161015
}
10171016

@@ -1088,14 +1087,15 @@ void lan966x_ptp_deinit(struct lan966x *lan966x)
10881087
}
10891088

10901089
void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,
1091-
u64 timestamp)
1090+
u64 src_port, u64 timestamp)
10921091
{
10931092
struct skb_shared_hwtstamps *shhwtstamps;
10941093
struct lan966x_phc *phc;
10951094
struct timespec64 ts;
10961095
u64 full_ts_in_ns;
10971096

1098-
if (!lan966x->ptp)
1097+
if (!lan966x->ptp ||
1098+
!lan966x->ports[src_port]->ptp_rx_cmd)
10991099
return;
11001100

11011101
phc = &lan966x->phc[LAN966X_PHC_PORT];

0 commit comments

Comments
 (0)