Skip to content

Commit f5396b8

Browse files
gnitkaanguy11
authored andcommitted
ice: switchdev slow path
Slow path means allowing packet to go from uplink to representor and from representor to correct VF on Rx site and from VF to representor and to uplink on Tx site. To accomplish this driver, has to set correct Tx descriptor. When packet is sent from representor to VF, destination should be set to VF VSI. When packet is sent from uplink port destination should be uplink to bypass switch infrastructure and send packet outside. On Rx site driver should check source VSI field from Rx descriptor and based on that forward packed to correct netdev. To allow this there is a target netdevs table in control plane VSI struct. Co-developed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent b3be918 commit f5396b8

File tree

6 files changed

+156
-1
lines changed

6 files changed

+156
-1
lines changed

drivers/net/ethernet/intel/ice/ice_eswitch.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,58 @@ void ice_eswitch_update_repr(struct ice_vsi *vsi)
258258
}
259259
}
260260

261+
/**
262+
* ice_eswitch_port_start_xmit - callback for packets transmit
263+
* @skb: send buffer
264+
* @netdev: network interface device structure
265+
*
266+
* Returns NETDEV_TX_OK if sent, else an error code
267+
*/
268+
netdev_tx_t
269+
ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)
270+
{
271+
struct ice_netdev_priv *np;
272+
struct ice_repr *repr;
273+
struct ice_vsi *vsi;
274+
275+
np = netdev_priv(netdev);
276+
vsi = np->vsi;
277+
278+
if (ice_is_reset_in_progress(vsi->back->state))
279+
return NETDEV_TX_BUSY;
280+
281+
repr = ice_netdev_to_repr(netdev);
282+
skb_dst_drop(skb);
283+
dst_hold((struct dst_entry *)repr->dst);
284+
skb_dst_set(skb, (struct dst_entry *)repr->dst);
285+
skb->queue_mapping = repr->vf->vf_id;
286+
287+
return ice_start_xmit(skb, netdev);
288+
}
289+
290+
/**
291+
* ice_eswitch_set_target_vsi - set switchdev context in Tx context descriptor
292+
* @skb: pointer to send buffer
293+
* @off: pointer to offload struct
294+
*/
295+
void
296+
ice_eswitch_set_target_vsi(struct sk_buff *skb,
297+
struct ice_tx_offload_params *off)
298+
{
299+
struct metadata_dst *dst = skb_metadata_dst(skb);
300+
u64 cd_cmd, dst_vsi;
301+
302+
if (!dst) {
303+
cd_cmd = ICE_TX_CTX_DESC_SWTCH_UPLINK << ICE_TXD_CTX_QW1_CMD_S;
304+
off->cd_qw1 |= (cd_cmd | ICE_TX_DESC_DTYPE_CTX);
305+
} else {
306+
cd_cmd = ICE_TX_CTX_DESC_SWTCH_VSI << ICE_TXD_CTX_QW1_CMD_S;
307+
dst_vsi = ((u64)dst->u.port_info.port_id <<
308+
ICE_TXD_CTX_QW1_VSI_S) & ICE_TXD_CTX_QW1_VSI_M;
309+
off->cd_qw1 = cd_cmd | dst_vsi | ICE_TX_DESC_DTYPE_CTX;
310+
}
311+
}
312+
261313
/**
262314
* ice_eswitch_release_env - clear switchdev HW filters
263315
* @pf: pointer to PF struct
@@ -448,6 +500,34 @@ ice_eswitch_mode_set(struct devlink *devlink, u16 mode,
448500
return 0;
449501
}
450502

503+
/**
504+
* ice_eswitch_get_target_netdev - return port representor netdev
505+
* @rx_ring: pointer to Rx ring
506+
* @rx_desc: pointer to Rx descriptor
507+
*
508+
* When working in switchdev mode context (when control VSI is used), this
509+
* function returns netdev of appropriate port representor. For non-switchdev
510+
* context, regular netdev associated with Rx ring is returned.
511+
*/
512+
struct net_device *
513+
ice_eswitch_get_target_netdev(struct ice_ring *rx_ring,
514+
union ice_32b_rx_flex_desc *rx_desc)
515+
{
516+
struct ice_32b_rx_flex_desc_nic_2 *desc;
517+
struct ice_vsi *vsi = rx_ring->vsi;
518+
struct ice_vsi *control_vsi;
519+
u16 target_vsi_id;
520+
521+
control_vsi = vsi->back->switchdev.control_vsi;
522+
if (vsi != control_vsi)
523+
return rx_ring->netdev;
524+
525+
desc = (struct ice_32b_rx_flex_desc_nic_2 *)rx_desc;
526+
target_vsi_id = le16_to_cpu(desc->src_vsi);
527+
528+
return vsi->target_netdevs[target_vsi_id];
529+
}
530+
451531
/**
452532
* ice_eswitch_mode_get - get current eswitch mode
453533
* @devlink: pointer to devlink structure

drivers/net/ethernet/intel/ice/ice_eswitch.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,24 @@ bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf);
2020
void ice_eswitch_update_repr(struct ice_vsi *vsi);
2121

2222
void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf);
23+
24+
struct net_device *
25+
ice_eswitch_get_target_netdev(struct ice_ring *rx_ring,
26+
union ice_32b_rx_flex_desc *rx_desc);
27+
28+
void ice_eswitch_set_target_vsi(struct sk_buff *skb,
29+
struct ice_tx_offload_params *off);
30+
netdev_tx_t
31+
ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev);
2332
#else /* CONFIG_ICE_SWITCHDEV */
2433
static inline void ice_eswitch_release(struct ice_pf *pf) { }
2534

2635
static inline void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf) { }
2736

37+
static inline void
38+
ice_eswitch_set_target_vsi(struct sk_buff *skb,
39+
struct ice_tx_offload_params *off) { }
40+
2841
static inline void ice_eswitch_update_repr(struct ice_vsi *vsi) { }
2942

3043
static inline int ice_eswitch_configure(struct ice_pf *pf)
@@ -53,5 +66,18 @@ static inline bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf)
5366
{
5467
return false;
5568
}
69+
70+
static inline struct net_device *
71+
ice_eswitch_get_target_netdev(struct ice_ring *rx_ring,
72+
union ice_32b_rx_flex_desc *rx_desc)
73+
{
74+
return rx_ring->netdev;
75+
}
76+
77+
static inline netdev_tx_t
78+
ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)
79+
{
80+
return NETDEV_TX_BUSY;
81+
}
5682
#endif /* CONFIG_ICE_SWITCHDEV */
5783
#endif /* _ICE_ESWITCH_H_ */

drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,46 @@ struct ice_32b_rx_flex_desc_nic {
301301
} flex_ts;
302302
};
303303

304+
/* Rx Flex Descriptor NIC Profile
305+
* RxDID Profile ID 6
306+
* Flex-field 0: RSS hash lower 16-bits
307+
* Flex-field 1: RSS hash upper 16-bits
308+
* Flex-field 2: Flow ID lower 16-bits
309+
* Flex-field 3: Source VSI
310+
* Flex-field 4: reserved, VLAN ID taken from L2Tag
311+
*/
312+
struct ice_32b_rx_flex_desc_nic_2 {
313+
/* Qword 0 */
314+
u8 rxdid;
315+
u8 mir_id_umb_cast;
316+
__le16 ptype_flexi_flags0;
317+
__le16 pkt_len;
318+
__le16 hdr_len_sph_flex_flags1;
319+
320+
/* Qword 1 */
321+
__le16 status_error0;
322+
__le16 l2tag1;
323+
__le32 rss_hash;
324+
325+
/* Qword 2 */
326+
__le16 status_error1;
327+
u8 flexi_flags2;
328+
u8 ts_low;
329+
__le16 l2tag2_1st;
330+
__le16 l2tag2_2nd;
331+
332+
/* Qword 3 */
333+
__le16 flow_id;
334+
__le16 src_vsi;
335+
union {
336+
struct {
337+
__le16 rsvd;
338+
__le16 flow_id_ipv6;
339+
} flex;
340+
__le32 ts_high;
341+
} flex_ts;
342+
};
343+
304344
/* Receive Flex Descriptor profile IDs: There are a total
305345
* of 64 profiles where profile IDs 0/1 are for legacy; and
306346
* profiles 2-63 are flex profiles that can be programmed
@@ -529,6 +569,9 @@ struct ice_tx_ctx_desc {
529569

530570
#define ICE_TXD_CTX_QW1_MSS_S 50
531571

572+
#define ICE_TXD_CTX_QW1_VSI_S 50
573+
#define ICE_TXD_CTX_QW1_VSI_M (0x3FFULL << ICE_TXD_CTX_QW1_VSI_S)
574+
532575
enum ice_tx_ctx_desc_cmd_bits {
533576
ICE_TX_CTX_DESC_TSO = 0x01,
534577
ICE_TX_CTX_DESC_TSYN = 0x02,

drivers/net/ethernet/intel/ice/ice_repr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static const struct net_device_ops ice_repr_netdev_ops = {
114114
.ndo_get_phys_port_name = ice_repr_get_phys_port_name,
115115
.ndo_open = ice_repr_open,
116116
.ndo_stop = ice_repr_stop,
117+
.ndo_start_xmit = ice_eswitch_port_start_xmit,
117118
.ndo_get_devlink_port = ice_repr_get_devlink_port,
118119
};
119120

drivers/net/ethernet/intel/ice/ice_txrx.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "ice_trace.h"
1515
#include "ice_dcb_lib.h"
1616
#include "ice_xsk.h"
17+
#include "ice_eswitch.h"
1718

1819
#define ICE_RX_HDR_SIZE 256
1920

@@ -2246,6 +2247,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring)
22462247
ICE_TXD_CTX_QW1_CMD_S);
22472248

22482249
ice_tstamp(tx_ring, skb, first, &offload);
2250+
if (ice_is_switchdev_running(vsi->back))
2251+
ice_eswitch_set_target_vsi(skb, &offload);
22492252

22502253
if (offload.cd_qw1 & ICE_TX_DESC_DTYPE_CTX) {
22512254
struct ice_tx_ctx_desc *cdesc;

drivers/net/ethernet/intel/ice/ice_txrx_lib.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright (c) 2019, Intel Corporation. */
33

44
#include "ice_txrx_lib.h"
5+
#include "ice_eswitch.h"
56

67
/**
78
* ice_release_rx_desc - Store the new tail and head values
@@ -185,7 +186,8 @@ ice_process_skb_fields(struct ice_ring *rx_ring,
185186
ice_rx_hash(rx_ring, rx_desc, skb, ptype);
186187

187188
/* modifies the skb - consumes the enet header */
188-
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
189+
skb->protocol = eth_type_trans(skb, ice_eswitch_get_target_netdev
190+
(rx_ring, rx_desc));
189191

190192
ice_rx_csum(rx_ring, skb, rx_desc, ptype);
191193

0 commit comments

Comments
 (0)