Skip to content

Commit 6ce1aac

Browse files
Amit Cohenkuba-moo
Amit Cohen
authored andcommitted
mlxsw: Move Tx header handling to PCI driver
Tx header should be added to all packets transmitted from the CPU to Spectrum ASICs. Historically, handling this header was added as a driver function, as Tx header is different between Spectrum and Switch-X. See SwitchX implementation in commit 31557f0 ("mlxsw: Introduce Mellanox SwitchX-2 ASIC support"). From May 2021, there is no support for SwitchX-2 ASIC, and all the relevant code was removed. For now, there is no justification to handle Tx header as part of spectrum.c, we can handle this as part of PCI, in skb_transmit(). A future patch set will add support for XDP in mlxsw driver, to support XDP_TX and XDP_REDIRECT actions, Tx header should be added before transmitting the packet. As preparation for this, move Tx header handling to PCI driver, so then XDP code will not have to call API from spectrum.c. This also improves the code as now Tx header is pushed just before transmitting, so it is not done from many flows which might miss something. Note that for PTP, we should configure Tx header differently, use the fields from mlxsw_txhdr_info to configure the packets correctly in PCI driver. Handle VLAN tagging in switch driver, verify that packet which should be transmitted as data is tagged, otherwise, tag it. Remove the calls for thxdr_construct() functions, as now this is done as part of skb_transmit(). Signed-off-by: Amit Cohen <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Signed-off-by: Petr Machata <[email protected]> Reviewed-by: Przemek Kitszel <[email protected]> Link: https://patch.msgid.link/293a81e6f7d59a8ec9f9592edb7745536649ff11.1737044384.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c89d9c3 commit 6ce1aac

File tree

7 files changed

+65
-180
lines changed

7 files changed

+65
-180
lines changed

drivers/net/ethernet/mellanox/mlxsw/core.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -737,9 +737,8 @@ static int mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core,
737737
if (!skb)
738738
return -ENOMEM;
739739

740-
trace_devlink_hwmsg(priv_to_devlink(mlxsw_core), false, 0,
741-
skb->data + mlxsw_core->driver->txhdr_len,
742-
skb->len - mlxsw_core->driver->txhdr_len);
740+
trace_devlink_hwmsg(priv_to_devlink(mlxsw_core), false, 0, skb->data,
741+
skb->len);
743742

744743
atomic_set(&trans->active, 1);
745744
err = mlxsw_core_skb_transmit(mlxsw_core, skb, &trans->txhdr_info);
@@ -995,7 +994,6 @@ static int mlxsw_emad_reg_access(struct mlxsw_core *mlxsw_core,
995994
trans->type = type;
996995

997996
mlxsw_emad_construct(mlxsw_core, skb, reg, payload, type, trans->tid);
998-
mlxsw_core->driver->txhdr_construct(skb, &trans->txhdr_info.tx_info);
999997

1000998
spin_lock_bh(&mlxsw_core->emad.trans_list_lock);
1001999
list_add_tail_rcu(&trans->list, &mlxsw_core->emad.trans_list);

drivers/net/ethernet/mellanox/mlxsw/core.h

-2
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,6 @@ struct mlxsw_driver {
432432
int (*trap_policer_counter_get)(struct mlxsw_core *mlxsw_core,
433433
const struct devlink_trap_policer *policer,
434434
u64 *p_drops);
435-
void (*txhdr_construct)(struct sk_buff *skb,
436-
const struct mlxsw_tx_info *tx_info);
437435
int (*resources_register)(struct mlxsw_core *mlxsw_core);
438436
int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
439437
const struct mlxsw_config_profile *profile,

drivers/net/ethernet/mellanox/mlxsw/pci.c

+38
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "cmd.h"
2222
#include "port.h"
2323
#include "resources.h"
24+
#include "txheader.h"
2425

2526
#define mlxsw_pci_write32(mlxsw_pci, reg, val) \
2627
iowrite32be(val, (mlxsw_pci)->hw_addr + (MLXSW_PCI_ ## reg))
@@ -2095,6 +2096,39 @@ static void mlxsw_pci_fini(void *bus_priv)
20952096
mlxsw_pci_free_irq_vectors(mlxsw_pci);
20962097
}
20972098

2099+
static int mlxsw_pci_txhdr_construct(struct sk_buff *skb,
2100+
const struct mlxsw_txhdr_info *txhdr_info)
2101+
{
2102+
const struct mlxsw_tx_info tx_info = txhdr_info->tx_info;
2103+
char *txhdr;
2104+
2105+
if (skb_cow_head(skb, MLXSW_TXHDR_LEN))
2106+
return -ENOMEM;
2107+
2108+
txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
2109+
memset(txhdr, 0, MLXSW_TXHDR_LEN);
2110+
2111+
mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
2112+
mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
2113+
mlxsw_tx_hdr_swid_set(txhdr, 0);
2114+
2115+
if (unlikely(txhdr_info->data)) {
2116+
u16 fid = txhdr_info->max_fid + tx_info.local_port - 1;
2117+
2118+
mlxsw_tx_hdr_rx_is_router_set(txhdr, true);
2119+
mlxsw_tx_hdr_fid_valid_set(txhdr, true);
2120+
mlxsw_tx_hdr_fid_set(txhdr, fid);
2121+
mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_DATA);
2122+
} else {
2123+
mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
2124+
mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
2125+
mlxsw_tx_hdr_port_mid_set(txhdr, tx_info.local_port);
2126+
mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
2127+
}
2128+
2129+
return 0;
2130+
}
2131+
20982132
static struct mlxsw_pci_queue *
20992133
mlxsw_pci_sdq_pick(struct mlxsw_pci *mlxsw_pci,
21002134
const struct mlxsw_tx_info *tx_info)
@@ -2131,6 +2165,10 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
21312165
int i;
21322166
int err;
21332167

2168+
err = mlxsw_pci_txhdr_construct(skb, txhdr_info);
2169+
if (err)
2170+
return err;
2171+
21342172
if (skb_shinfo(skb)->nr_frags > MLXSW_PCI_WQE_SG_ENTRIES - 1) {
21352173
err = skb_linearize(skb);
21362174
if (err)

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

+25-96
Original file line numberDiff line numberDiff line change
@@ -165,61 +165,6 @@ void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
165165
counter_index);
166166
}
167167

168-
void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
169-
const struct mlxsw_tx_info *tx_info)
170-
{
171-
char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
172-
173-
memset(txhdr, 0, MLXSW_TXHDR_LEN);
174-
175-
mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
176-
mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
177-
mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
178-
mlxsw_tx_hdr_swid_set(txhdr, 0);
179-
mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
180-
mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port);
181-
mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
182-
}
183-
184-
int
185-
mlxsw_sp_txhdr_ptp_data_construct(struct mlxsw_core *mlxsw_core,
186-
struct mlxsw_sp_port *mlxsw_sp_port,
187-
struct sk_buff *skb,
188-
const struct mlxsw_tx_info *tx_info)
189-
{
190-
char *txhdr;
191-
u16 max_fid;
192-
int err;
193-
194-
if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
195-
err = -ENOMEM;
196-
goto err_skb_cow_head;
197-
}
198-
199-
if (!MLXSW_CORE_RES_VALID(mlxsw_core, FID)) {
200-
err = -EIO;
201-
goto err_res_valid;
202-
}
203-
max_fid = MLXSW_CORE_RES_GET(mlxsw_core, FID);
204-
205-
txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
206-
memset(txhdr, 0, MLXSW_TXHDR_LEN);
207-
208-
mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
209-
mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
210-
mlxsw_tx_hdr_rx_is_router_set(txhdr, true);
211-
mlxsw_tx_hdr_fid_valid_set(txhdr, true);
212-
mlxsw_tx_hdr_fid_set(txhdr, max_fid + tx_info->local_port - 1);
213-
mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_DATA);
214-
return 0;
215-
216-
err_res_valid:
217-
err_skb_cow_head:
218-
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
219-
dev_kfree_skb_any(skb);
220-
return err;
221-
}
222-
223168
static bool mlxsw_sp_skb_requires_ts(struct sk_buff *skb)
224169
{
225170
unsigned int type;
@@ -242,46 +187,38 @@ static void mlxsw_sp_txhdr_info_data_init(struct mlxsw_core *mlxsw_core,
242187
txhdr_info->max_fid = max_fid;
243188
}
244189

245-
static void
190+
static struct sk_buff *
191+
mlxsw_sp_vlan_tag_push(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb)
192+
{
193+
/* In some Spectrum ASICs, in order for PTP event packets to have their
194+
* correction field correctly set on the egress port they must be
195+
* transmitted as data packets. Such packets ingress the ASIC via the
196+
* CPU port and must have a VLAN tag, as the CPU port is not configured
197+
* with a PVID. Push the default VLAN (4095), which is configured as
198+
* egress untagged on all the ports.
199+
*/
200+
if (skb_vlan_tagged(skb))
201+
return skb;
202+
203+
return vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q),
204+
MLXSW_SP_DEFAULT_VID);
205+
}
206+
207+
static struct sk_buff *
246208
mlxsw_sp_txhdr_preparations(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
247209
struct mlxsw_txhdr_info *txhdr_info)
248210
{
249211
if (likely(!mlxsw_sp_skb_requires_ts(skb)))
250-
return;
212+
return skb;
251213

252214
if (!mlxsw_sp->ptp_ops->tx_as_data)
253-
return;
215+
return skb;
254216

255217
/* Special handling for PTP events that require a time stamp and cannot
256218
* be transmitted as regular control packets.
257219
*/
258220
mlxsw_sp_txhdr_info_data_init(mlxsw_sp->core, skb, txhdr_info);
259-
}
260-
261-
static int mlxsw_sp_txhdr_handle(struct mlxsw_core *mlxsw_core,
262-
struct mlxsw_sp_port *mlxsw_sp_port,
263-
struct sk_buff *skb,
264-
const struct mlxsw_tx_info *tx_info)
265-
{
266-
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
267-
268-
/* In Spectrum-2 and Spectrum-3, PTP events that require a time stamp
269-
* need special handling and cannot be transmitted as regular control
270-
* packets.
271-
*/
272-
if (unlikely(mlxsw_sp_skb_requires_ts(skb)))
273-
return mlxsw_sp->ptp_ops->txhdr_construct(mlxsw_core,
274-
mlxsw_sp_port, skb,
275-
tx_info);
276-
277-
if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
278-
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
279-
dev_kfree_skb_any(skb);
280-
return -ENOMEM;
281-
}
282-
283-
mlxsw_sp_txhdr_construct(skb, tx_info);
284-
return 0;
221+
return mlxsw_sp_vlan_tag_push(mlxsw_sp, skb);
285222
}
286223

287224
enum mlxsw_reg_spms_state mlxsw_sp_stp_spms_state(u8 state)
@@ -697,12 +634,11 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
697634
return NETDEV_TX_OK;
698635
}
699636

700-
mlxsw_sp_txhdr_preparations(mlxsw_sp, skb, &txhdr_info);
701-
702-
err = mlxsw_sp_txhdr_handle(mlxsw_sp->core, mlxsw_sp_port, skb,
703-
&txhdr_info.tx_info);
704-
if (err)
637+
skb = mlxsw_sp_txhdr_preparations(mlxsw_sp, skb, &txhdr_info);
638+
if (!skb) {
639+
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
705640
return NETDEV_TX_OK;
641+
}
706642

707643
/* TX header is consumed by HW on the way so we shouldn't count its
708644
* bytes as being sent.
@@ -2753,7 +2689,6 @@ static const struct mlxsw_sp_ptp_ops mlxsw_sp1_ptp_ops = {
27532689
.get_stats_count = mlxsw_sp1_get_stats_count,
27542690
.get_stats_strings = mlxsw_sp1_get_stats_strings,
27552691
.get_stats = mlxsw_sp1_get_stats,
2756-
.txhdr_construct = mlxsw_sp_ptp_txhdr_construct,
27572692
};
27582693

27592694
static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
@@ -2772,7 +2707,6 @@ static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
27722707
.get_stats_count = mlxsw_sp2_get_stats_count,
27732708
.get_stats_strings = mlxsw_sp2_get_stats_strings,
27742709
.get_stats = mlxsw_sp2_get_stats,
2775-
.txhdr_construct = mlxsw_sp2_ptp_txhdr_construct,
27762710
.tx_as_data = true,
27772711
};
27782712

@@ -2792,7 +2726,6 @@ static const struct mlxsw_sp_ptp_ops mlxsw_sp4_ptp_ops = {
27922726
.get_stats_count = mlxsw_sp2_get_stats_count,
27932727
.get_stats_strings = mlxsw_sp2_get_stats_strings,
27942728
.get_stats = mlxsw_sp2_get_stats,
2795-
.txhdr_construct = mlxsw_sp_ptp_txhdr_construct,
27962729
};
27972730

27982731
struct mlxsw_sp_sample_trigger_node {
@@ -3954,7 +3887,6 @@ static struct mlxsw_driver mlxsw_sp1_driver = {
39543887
.trap_policer_fini = mlxsw_sp_trap_policer_fini,
39553888
.trap_policer_set = mlxsw_sp_trap_policer_set,
39563889
.trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3957-
.txhdr_construct = mlxsw_sp_txhdr_construct,
39583890
.resources_register = mlxsw_sp1_resources_register,
39593891
.kvd_sizes_get = mlxsw_sp_kvd_sizes_get,
39603892
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
@@ -3992,7 +3924,6 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
39923924
.trap_policer_fini = mlxsw_sp_trap_policer_fini,
39933925
.trap_policer_set = mlxsw_sp_trap_policer_set,
39943926
.trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3995-
.txhdr_construct = mlxsw_sp_txhdr_construct,
39963927
.resources_register = mlxsw_sp2_resources_register,
39973928
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
39983929
.txhdr_len = MLXSW_TXHDR_LEN,
@@ -4029,7 +3960,6 @@ static struct mlxsw_driver mlxsw_sp3_driver = {
40293960
.trap_policer_fini = mlxsw_sp_trap_policer_fini,
40303961
.trap_policer_set = mlxsw_sp_trap_policer_set,
40313962
.trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
4032-
.txhdr_construct = mlxsw_sp_txhdr_construct,
40333963
.resources_register = mlxsw_sp2_resources_register,
40343964
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
40353965
.txhdr_len = MLXSW_TXHDR_LEN,
@@ -4064,7 +3994,6 @@ static struct mlxsw_driver mlxsw_sp4_driver = {
40643994
.trap_policer_fini = mlxsw_sp_trap_policer_fini,
40653995
.trap_policer_set = mlxsw_sp_trap_policer_set,
40663996
.trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
4067-
.txhdr_construct = mlxsw_sp_txhdr_construct,
40683997
.resources_register = mlxsw_sp2_resources_register,
40693998
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
40703999
.txhdr_len = MLXSW_TXHDR_LEN,

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

-10
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,6 @@ struct mlxsw_sp_ptp_ops {
243243
void (*get_stats_strings)(u8 **p);
244244
void (*get_stats)(struct mlxsw_sp_port *mlxsw_sp_port,
245245
u64 *data, int data_index);
246-
int (*txhdr_construct)(struct mlxsw_core *mlxsw_core,
247-
struct mlxsw_sp_port *mlxsw_sp_port,
248-
struct sk_buff *skb,
249-
const struct mlxsw_tx_info *tx_info);
250246
bool tx_as_data;
251247
};
252248

@@ -712,12 +708,6 @@ int mlxsw_sp_flow_counter_alloc(struct mlxsw_sp *mlxsw_sp,
712708
unsigned int *p_counter_index);
713709
void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
714710
unsigned int counter_index);
715-
void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
716-
const struct mlxsw_tx_info *tx_info);
717-
int mlxsw_sp_txhdr_ptp_data_construct(struct mlxsw_core *mlxsw_core,
718-
struct mlxsw_sp_port *mlxsw_sp_port,
719-
struct sk_buff *skb,
720-
const struct mlxsw_tx_info *tx_info);
721711
bool mlxsw_sp_port_dev_check(const struct net_device *dev);
722712
struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev);
723713
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);

drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c

-40
Original file line numberDiff line numberDiff line change
@@ -1683,43 +1683,3 @@ int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
16831683

16841684
return 0;
16851685
}
1686-
1687-
int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
1688-
struct mlxsw_sp_port *mlxsw_sp_port,
1689-
struct sk_buff *skb,
1690-
const struct mlxsw_tx_info *tx_info)
1691-
{
1692-
if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
1693-
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
1694-
dev_kfree_skb_any(skb);
1695-
return -ENOMEM;
1696-
}
1697-
1698-
mlxsw_sp_txhdr_construct(skb, tx_info);
1699-
return 0;
1700-
}
1701-
1702-
int mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
1703-
struct mlxsw_sp_port *mlxsw_sp_port,
1704-
struct sk_buff *skb,
1705-
const struct mlxsw_tx_info *tx_info)
1706-
{
1707-
/* In Spectrum-2 and Spectrum-3, in order for PTP event packets to have
1708-
* their correction field correctly set on the egress port they must be
1709-
* transmitted as data packets. Such packets ingress the ASIC via the
1710-
* CPU port and must have a VLAN tag, as the CPU port is not configured
1711-
* with a PVID. Push the default VLAN (4095), which is configured as
1712-
* egress untagged on all the ports.
1713-
*/
1714-
if (!skb_vlan_tagged(skb)) {
1715-
skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q),
1716-
MLXSW_SP_DEFAULT_VID);
1717-
if (!skb) {
1718-
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
1719-
return -ENOMEM;
1720-
}
1721-
}
1722-
1723-
return mlxsw_sp_txhdr_ptp_data_construct(mlxsw_core, mlxsw_sp_port, skb,
1724-
tx_info);
1725-
}

0 commit comments

Comments
 (0)