Skip to content

Commit f136315

Browse files
Edward Creekuba-moo
authored andcommitted
sfc: MAE functions to create/update/delete encap headers
Besides the raw header data, also pass the tunnel type, so that the hardware knows it needs to update the IP Total Length and UDP Length fields (and corresponding checksums) for each packet. Also, populate the ENCAP_HEADER_ID field in efx_mae_alloc_action_set() with the fw_id returned from efx_mae_allocate_encap_md(). Reviewed-by: Pieter Jansen van Vuuren <[email protected]> Signed-off-by: Edward Cree <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 69819d3 commit f136315

File tree

2 files changed

+95
-2
lines changed

2 files changed

+95
-2
lines changed

drivers/net/ethernet/sfc/mae.c

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "mcdi.h"
1616
#include "mcdi_pcol.h"
1717
#include "mcdi_pcol_mae.h"
18+
#include "tc_encap_actions.h"
1819

1920
int efx_mae_allocate_mport(struct efx_nic *efx, u32 *id, u32 *label)
2021
{
@@ -610,6 +611,87 @@ static int efx_mae_encap_type_to_mae_type(enum efx_encap_type type)
610611
}
611612
}
612613

614+
int efx_mae_allocate_encap_md(struct efx_nic *efx,
615+
struct efx_tc_encap_action *encap)
616+
{
617+
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAE_ENCAP_HEADER_ALLOC_IN_LEN(EFX_TC_MAX_ENCAP_HDR));
618+
MCDI_DECLARE_BUF(outbuf, MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_LEN);
619+
size_t inlen, outlen;
620+
int rc;
621+
622+
rc = efx_mae_encap_type_to_mae_type(encap->type);
623+
if (rc < 0)
624+
return rc;
625+
MCDI_SET_DWORD(inbuf, MAE_ENCAP_HEADER_ALLOC_IN_ENCAP_TYPE, rc);
626+
inlen = MC_CMD_MAE_ENCAP_HEADER_ALLOC_IN_LEN(encap->encap_hdr_len);
627+
if (WARN_ON(inlen > sizeof(inbuf))) /* can't happen */
628+
return -EINVAL;
629+
memcpy(MCDI_PTR(inbuf, MAE_ENCAP_HEADER_ALLOC_IN_HDR_DATA),
630+
encap->encap_hdr,
631+
encap->encap_hdr_len);
632+
rc = efx_mcdi_rpc(efx, MC_CMD_MAE_ENCAP_HEADER_ALLOC, inbuf,
633+
inlen, outbuf, sizeof(outbuf), &outlen);
634+
if (rc)
635+
return rc;
636+
if (outlen < sizeof(outbuf))
637+
return -EIO;
638+
encap->fw_id = MCDI_DWORD(outbuf, MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID);
639+
return 0;
640+
}
641+
642+
int efx_mae_update_encap_md(struct efx_nic *efx,
643+
struct efx_tc_encap_action *encap)
644+
{
645+
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_LEN(EFX_TC_MAX_ENCAP_HDR));
646+
size_t inlen;
647+
int rc;
648+
649+
rc = efx_mae_encap_type_to_mae_type(encap->type);
650+
if (rc < 0)
651+
return rc;
652+
MCDI_SET_DWORD(inbuf, MAE_ENCAP_HEADER_UPDATE_IN_ENCAP_TYPE, rc);
653+
MCDI_SET_DWORD(inbuf, MAE_ENCAP_HEADER_UPDATE_IN_EH_ID,
654+
encap->fw_id);
655+
inlen = MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_LEN(encap->encap_hdr_len);
656+
if (WARN_ON(inlen > sizeof(inbuf))) /* can't happen */
657+
return -EINVAL;
658+
memcpy(MCDI_PTR(inbuf, MAE_ENCAP_HEADER_UPDATE_IN_HDR_DATA),
659+
encap->encap_hdr,
660+
encap->encap_hdr_len);
661+
662+
BUILD_BUG_ON(MC_CMD_MAE_ENCAP_HEADER_UPDATE_OUT_LEN != 0);
663+
return efx_mcdi_rpc(efx, MC_CMD_MAE_ENCAP_HEADER_UPDATE, inbuf,
664+
inlen, NULL, 0, NULL);
665+
}
666+
667+
int efx_mae_free_encap_md(struct efx_nic *efx,
668+
struct efx_tc_encap_action *encap)
669+
{
670+
MCDI_DECLARE_BUF(outbuf, MC_CMD_MAE_ENCAP_HEADER_FREE_OUT_LEN(1));
671+
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAE_ENCAP_HEADER_FREE_IN_LEN(1));
672+
size_t outlen;
673+
int rc;
674+
675+
MCDI_SET_DWORD(inbuf, MAE_ENCAP_HEADER_FREE_IN_EH_ID, encap->fw_id);
676+
rc = efx_mcdi_rpc(efx, MC_CMD_MAE_ENCAP_HEADER_FREE, inbuf,
677+
sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
678+
if (rc)
679+
return rc;
680+
if (outlen < sizeof(outbuf))
681+
return -EIO;
682+
/* FW freed a different ID than we asked for, should also never happen.
683+
* Warn because it means we've now got a different idea to the FW of
684+
* what encap_mds exist, which could cause mayhem later.
685+
*/
686+
if (WARN_ON(MCDI_DWORD(outbuf, MAE_ENCAP_HEADER_FREE_OUT_FREED_EH_ID) != encap->fw_id))
687+
return -EIO;
688+
/* We're probably about to free @encap, but let's just make sure its
689+
* fw_id is blatted so that it won't look valid if it leaks out.
690+
*/
691+
encap->fw_id = MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL;
692+
return 0;
693+
}
694+
613695
int efx_mae_lookup_mport(struct efx_nic *efx, u32 vf_idx, u32 *id)
614696
{
615697
struct ef100_nic_data *nic_data = efx->nic_data;
@@ -833,8 +915,12 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)
833915
MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_PROTO_BE,
834916
act->vlan_proto[1]);
835917
}
836-
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID,
837-
MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL);
918+
if (act->encap_md)
919+
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID,
920+
act->encap_md->fw_id);
921+
else
922+
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID,
923+
MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL);
838924
if (act->deliver)
839925
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_DELIVER,
840926
act->dest_mport);

drivers/net/ethernet/sfc/mae.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ int efx_mae_check_encap_type_supported(struct efx_nic *efx,
9090
int efx_mae_allocate_counter(struct efx_nic *efx, struct efx_tc_counter *cnt);
9191
int efx_mae_free_counter(struct efx_nic *efx, struct efx_tc_counter *cnt);
9292

93+
int efx_mae_allocate_encap_md(struct efx_nic *efx,
94+
struct efx_tc_encap_action *encap);
95+
int efx_mae_update_encap_md(struct efx_nic *efx,
96+
struct efx_tc_encap_action *encap);
97+
int efx_mae_free_encap_md(struct efx_nic *efx,
98+
struct efx_tc_encap_action *encap);
99+
93100
int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act);
94101
int efx_mae_free_action_set(struct efx_nic *efx, u32 fw_id);
95102

0 commit comments

Comments
 (0)