Skip to content

Commit 31fa8d1

Browse files
committed
tgupdate: merge t/upstream base into t/upstream
2 parents d7354f3 + 172a933 commit 31fa8d1

File tree

14 files changed

+217
-118
lines changed

14 files changed

+217
-118
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,7 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
15311531
if (TPA_START_IS_IPV6(tpa_start1))
15321532
tpa_info->gso_type = SKB_GSO_TCPV6;
15331533
/* RSS profiles 1 and 3 with extract code 0 for inner 4-tuple */
1534-
else if (cmp_type == CMP_TYPE_RX_L2_TPA_START_CMP &&
1534+
else if (!BNXT_CHIP_P4_PLUS(bp) &&
15351535
TPA_START_HASH_TYPE(tpa_start) == 3)
15361536
tpa_info->gso_type = SKB_GSO_TCPV6;
15371537
tpa_info->rss_hash =
@@ -2226,15 +2226,13 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
22262226
if (cmp_type == CMP_TYPE_RX_L2_V3_CMP) {
22272227
type = bnxt_rss_ext_op(bp, rxcmp);
22282228
} else {
2229-
u32 hash_type = RX_CMP_HASH_TYPE(rxcmp);
2229+
u32 itypes = RX_CMP_ITYPES(rxcmp);
22302230

2231-
/* RSS profiles 1 and 3 with extract code 0 for inner
2232-
* 4-tuple
2233-
*/
2234-
if (hash_type != 1 && hash_type != 3)
2235-
type = PKT_HASH_TYPE_L3;
2236-
else
2231+
if (itypes == RX_CMP_FLAGS_ITYPE_TCP ||
2232+
itypes == RX_CMP_FLAGS_ITYPE_UDP)
22372233
type = PKT_HASH_TYPE_L4;
2234+
else
2235+
type = PKT_HASH_TYPE_L3;
22382236
}
22392237
skb_set_hash(skb, le32_to_cpu(rxcmp->rx_cmp_rss_hash), type);
22402238
}
@@ -8367,7 +8365,7 @@ static int bnxt_alloc_all_ctx_pg_info(struct bnxt *bp, int ctx_max)
83678365
struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
83688366
int n = 1;
83698367

8370-
if (!ctxm->max_entries)
8368+
if (!ctxm->max_entries || ctxm->pg_info)
83718369
continue;
83728370

83738371
if (ctxm->instance_bmap)
@@ -8971,8 +8969,8 @@ static int bnxt_backing_store_cfg_v2(struct bnxt *bp, u32 ena)
89718969
continue;
89728970
}
89738971
bnxt_bs_trace_init(bp, ctxm);
8974-
last_type = type;
89758972
}
8973+
last_type = type;
89768974
}
89778975

89788976
if (last_type == BNXT_CTX_INV) {

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ struct rx_cmp {
267267
(((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
268268
RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
269269

270+
#define RX_CMP_ITYPES(rxcmp) \
271+
(le32_to_cpu((rxcmp)->rx_cmp_len_flags_type) & RX_CMP_FLAGS_ITYPES_MASK)
272+
270273
#define RX_CMP_V3_HASH_TYPE_LEGACY(rxcmp) \
271274
((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_V3_RSS_EXT_OP_LEGACY) >>\
272275
RX_CMP_V3_RSS_EXT_OP_LEGACY_SHIFT)

drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
297297
if (ret) {
298298
mlx5dr_dbg(dmn, "Couldn't insert new vport into xarray (%d)\n", ret);
299299
kvfree(vport_caps);
300-
return ERR_PTR(ret);
300+
if (ret == -EBUSY)
301+
return ERR_PTR(-EBUSY);
302+
return NULL;
301303
}
302304

303305
return vport_caps;

drivers/net/ethernet/mscc/ocelot_ptp.c

Lines changed: 129 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <soc/mscc/ocelot.h>
1515
#include "ocelot.h"
1616

17+
#define OCELOT_PTP_TX_TSTAMP_TIMEOUT (5 * HZ)
18+
1719
int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
1820
{
1921
struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
@@ -495,6 +497,28 @@ static int ocelot_traps_to_ptp_rx_filter(unsigned int proto)
495497
return HWTSTAMP_FILTER_NONE;
496498
}
497499

500+
static int ocelot_ptp_tx_type_to_cmd(int tx_type, int *ptp_cmd)
501+
{
502+
switch (tx_type) {
503+
case HWTSTAMP_TX_ON:
504+
*ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
505+
break;
506+
case HWTSTAMP_TX_ONESTEP_SYNC:
507+
/* IFH_REW_OP_ONE_STEP_PTP updates the correctionField,
508+
* what we need to update is the originTimestamp.
509+
*/
510+
*ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
511+
break;
512+
case HWTSTAMP_TX_OFF:
513+
*ptp_cmd = 0;
514+
break;
515+
default:
516+
return -ERANGE;
517+
}
518+
519+
return 0;
520+
}
521+
498522
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
499523
{
500524
struct ocelot_port *ocelot_port = ocelot->ports[port];
@@ -521,30 +545,19 @@ EXPORT_SYMBOL(ocelot_hwstamp_get);
521545
int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
522546
{
523547
struct ocelot_port *ocelot_port = ocelot->ports[port];
548+
int ptp_cmd, old_ptp_cmd = ocelot_port->ptp_cmd;
524549
bool l2 = false, l4 = false;
525550
struct hwtstamp_config cfg;
551+
bool old_l2, old_l4;
526552
int err;
527553

528554
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
529555
return -EFAULT;
530556

531557
/* Tx type sanity check */
532-
switch (cfg.tx_type) {
533-
case HWTSTAMP_TX_ON:
534-
ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
535-
break;
536-
case HWTSTAMP_TX_ONESTEP_SYNC:
537-
/* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we
538-
* need to update the origin time.
539-
*/
540-
ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
541-
break;
542-
case HWTSTAMP_TX_OFF:
543-
ocelot_port->ptp_cmd = 0;
544-
break;
545-
default:
546-
return -ERANGE;
547-
}
558+
err = ocelot_ptp_tx_type_to_cmd(cfg.tx_type, &ptp_cmd);
559+
if (err)
560+
return err;
548561

549562
switch (cfg.rx_filter) {
550563
case HWTSTAMP_FILTER_NONE:
@@ -569,13 +582,27 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
569582
return -ERANGE;
570583
}
571584

585+
old_l2 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L2;
586+
old_l4 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L4;
587+
572588
err = ocelot_setup_ptp_traps(ocelot, port, l2, l4);
573589
if (err)
574590
return err;
575591

592+
ocelot_port->ptp_cmd = ptp_cmd;
593+
576594
cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);
577595

578-
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
596+
if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) {
597+
err = -EFAULT;
598+
goto out_restore_ptp_traps;
599+
}
600+
601+
return 0;
602+
out_restore_ptp_traps:
603+
ocelot_setup_ptp_traps(ocelot, port, old_l2, old_l4);
604+
ocelot_port->ptp_cmd = old_ptp_cmd;
605+
return err;
579606
}
580607
EXPORT_SYMBOL(ocelot_hwstamp_set);
581608

@@ -603,34 +630,87 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port,
603630
}
604631
EXPORT_SYMBOL(ocelot_get_ts_info);
605632

606-
static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
607-
struct sk_buff *clone)
633+
static struct sk_buff *ocelot_port_dequeue_ptp_tx_skb(struct ocelot *ocelot,
634+
int port, u8 ts_id,
635+
u32 seqid)
608636
{
609637
struct ocelot_port *ocelot_port = ocelot->ports[port];
610-
unsigned long flags;
638+
struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
639+
struct ptp_header *hdr;
611640

612-
spin_lock_irqsave(&ocelot->ts_id_lock, flags);
641+
spin_lock(&ocelot->ts_id_lock);
613642

614-
if (ocelot_port->ptp_skbs_in_flight == OCELOT_MAX_PTP_ID ||
615-
ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) {
616-
spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
617-
return -EBUSY;
643+
skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) {
644+
if (OCELOT_SKB_CB(skb)->ts_id != ts_id)
645+
continue;
646+
647+
/* Check that the timestamp ID is for the expected PTP
648+
* sequenceId. We don't have to test ptp_parse_header() against
649+
* NULL, because we've pre-validated the packet's ptp_class.
650+
*/
651+
hdr = ptp_parse_header(skb, OCELOT_SKB_CB(skb)->ptp_class);
652+
if (seqid != ntohs(hdr->sequence_id))
653+
continue;
654+
655+
__skb_unlink(skb, &ocelot_port->tx_skbs);
656+
ocelot->ptp_skbs_in_flight--;
657+
skb_match = skb;
658+
break;
618659
}
619660

620-
skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
621-
/* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */
622-
OCELOT_SKB_CB(clone)->ts_id = ocelot_port->ts_id;
661+
spin_unlock(&ocelot->ts_id_lock);
623662

624-
ocelot_port->ts_id++;
625-
if (ocelot_port->ts_id == OCELOT_MAX_PTP_ID)
626-
ocelot_port->ts_id = 0;
663+
return skb_match;
664+
}
665+
666+
static int ocelot_port_queue_ptp_tx_skb(struct ocelot *ocelot, int port,
667+
struct sk_buff *clone)
668+
{
669+
struct ocelot_port *ocelot_port = ocelot->ports[port];
670+
DECLARE_BITMAP(ts_id_in_flight, OCELOT_MAX_PTP_ID);
671+
struct sk_buff *skb, *skb_tmp;
672+
unsigned long n;
673+
674+
spin_lock(&ocelot->ts_id_lock);
675+
676+
/* To get a better chance of acquiring a timestamp ID, first flush the
677+
* stale packets still waiting in the TX timestamping queue. They are
678+
* probably lost.
679+
*/
680+
skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) {
681+
if (time_before(OCELOT_SKB_CB(skb)->ptp_tx_time +
682+
OCELOT_PTP_TX_TSTAMP_TIMEOUT, jiffies)) {
683+
dev_warn_ratelimited(ocelot->dev,
684+
"port %d invalidating stale timestamp ID %u which seems lost\n",
685+
port, OCELOT_SKB_CB(skb)->ts_id);
686+
__skb_unlink(skb, &ocelot_port->tx_skbs);
687+
kfree_skb(skb);
688+
ocelot->ptp_skbs_in_flight--;
689+
} else {
690+
__set_bit(OCELOT_SKB_CB(skb)->ts_id, ts_id_in_flight);
691+
}
692+
}
693+
694+
if (ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) {
695+
spin_unlock(&ocelot->ts_id_lock);
696+
return -EBUSY;
697+
}
698+
699+
n = find_first_zero_bit(ts_id_in_flight, OCELOT_MAX_PTP_ID);
700+
if (n == OCELOT_MAX_PTP_ID) {
701+
spin_unlock(&ocelot->ts_id_lock);
702+
return -EBUSY;
703+
}
627704

628-
ocelot_port->ptp_skbs_in_flight++;
705+
/* Found an available timestamp ID, use it */
706+
OCELOT_SKB_CB(clone)->ts_id = n;
707+
OCELOT_SKB_CB(clone)->ptp_tx_time = jiffies;
629708
ocelot->ptp_skbs_in_flight++;
709+
__skb_queue_tail(&ocelot_port->tx_skbs, clone);
630710

631-
skb_queue_tail(&ocelot_port->tx_skbs, clone);
711+
spin_unlock(&ocelot->ts_id_lock);
632712

633-
spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
713+
dev_dbg_ratelimited(ocelot->dev, "port %d timestamp id %lu\n", port, n);
634714

635715
return 0;
636716
}
@@ -687,10 +767,14 @@ int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
687767
if (!(*clone))
688768
return -ENOMEM;
689769

690-
err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
691-
if (err)
770+
/* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */
771+
err = ocelot_port_queue_ptp_tx_skb(ocelot, port, *clone);
772+
if (err) {
773+
kfree_skb(*clone);
692774
return err;
775+
}
693776

777+
skb_shinfo(*clone)->tx_flags |= SKBTX_IN_PROGRESS;
694778
OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
695779
OCELOT_SKB_CB(*clone)->ptp_class = ptp_class;
696780
}
@@ -726,28 +810,15 @@ static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
726810
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
727811
}
728812

729-
static bool ocelot_validate_ptp_skb(struct sk_buff *clone, u16 seqid)
730-
{
731-
struct ptp_header *hdr;
732-
733-
hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class);
734-
if (WARN_ON(!hdr))
735-
return false;
736-
737-
return seqid == ntohs(hdr->sequence_id);
738-
}
739-
740813
void ocelot_get_txtstamp(struct ocelot *ocelot)
741814
{
742815
int budget = OCELOT_PTP_QUEUE_SZ;
743816

744817
while (budget--) {
745-
struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
746818
struct skb_shared_hwtstamps shhwtstamps;
747819
u32 val, id, seqid, txport;
748-
struct ocelot_port *port;
820+
struct sk_buff *skb_match;
749821
struct timespec64 ts;
750-
unsigned long flags;
751822

752823
val = ocelot_read(ocelot, SYS_PTP_STATUS);
753824

@@ -762,36 +833,14 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
762833
txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
763834
seqid = SYS_PTP_STATUS_PTP_MESS_SEQ_ID(val);
764835

765-
port = ocelot->ports[txport];
766-
767-
spin_lock(&ocelot->ts_id_lock);
768-
port->ptp_skbs_in_flight--;
769-
ocelot->ptp_skbs_in_flight--;
770-
spin_unlock(&ocelot->ts_id_lock);
771-
772836
/* Retrieve its associated skb */
773-
try_again:
774-
spin_lock_irqsave(&port->tx_skbs.lock, flags);
775-
776-
skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
777-
if (OCELOT_SKB_CB(skb)->ts_id != id)
778-
continue;
779-
__skb_unlink(skb, &port->tx_skbs);
780-
skb_match = skb;
781-
break;
782-
}
783-
784-
spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
785-
786-
if (WARN_ON(!skb_match))
787-
continue;
788-
789-
if (!ocelot_validate_ptp_skb(skb_match, seqid)) {
790-
dev_err_ratelimited(ocelot->dev,
791-
"port %d received stale TX timestamp for seqid %d, discarding\n",
792-
txport, seqid);
793-
dev_kfree_skb_any(skb);
794-
goto try_again;
837+
skb_match = ocelot_port_dequeue_ptp_tx_skb(ocelot, txport, id,
838+
seqid);
839+
if (!skb_match) {
840+
dev_warn_ratelimited(ocelot->dev,
841+
"port %d received TX timestamp (seqid %d, ts id %u) for packet previously declared stale\n",
842+
txport, seqid, id);
843+
goto next_ts;
795844
}
796845

797846
/* Get the h/w timestamp */
@@ -802,7 +851,7 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
802851
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
803852
skb_complete_tx_timestamp(skb_match, &shhwtstamps);
804853

805-
/* Next ts */
854+
next_ts:
806855
ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
807856
}
808857
}

0 commit comments

Comments
 (0)