|
15 | 15 | #include "mcdi.h" |
16 | 16 | #include "mcdi_pcol.h" |
17 | 17 | #include "mcdi_pcol_mae.h" |
| 18 | +#include "tc_encap_actions.h" |
18 | 19 |
|
19 | 20 | int efx_mae_allocate_mport(struct efx_nic *efx, u32 *id, u32 *label) |
20 | 21 | { |
@@ -610,6 +611,87 @@ static int efx_mae_encap_type_to_mae_type(enum efx_encap_type type) |
610 | 611 | } |
611 | 612 | } |
612 | 613 |
|
| 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 | + |
613 | 695 | int efx_mae_lookup_mport(struct efx_nic *efx, u32 vf_idx, u32 *id) |
614 | 696 | { |
615 | 697 | 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) |
833 | 915 | MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_PROTO_BE, |
834 | 916 | act->vlan_proto[1]); |
835 | 917 | } |
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); |
838 | 924 | if (act->deliver) |
839 | 925 | MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_DELIVER, |
840 | 926 | act->dest_mport); |
|
0 commit comments