Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2013 - 2018 Intel Corporation. */
0003 
0004 #include "iavf_type.h"
0005 #include "iavf_adminq.h"
0006 #include "iavf_prototype.h"
0007 #include <linux/avf/virtchnl.h>
0008 
0009 /**
0010  * iavf_set_mac_type - Sets MAC type
0011  * @hw: pointer to the HW structure
0012  *
0013  * This function sets the mac type of the adapter based on the
0014  * vendor ID and device ID stored in the hw structure.
0015  **/
0016 enum iavf_status iavf_set_mac_type(struct iavf_hw *hw)
0017 {
0018     enum iavf_status status = 0;
0019 
0020     if (hw->vendor_id == PCI_VENDOR_ID_INTEL) {
0021         switch (hw->device_id) {
0022         case IAVF_DEV_ID_X722_VF:
0023             hw->mac.type = IAVF_MAC_X722_VF;
0024             break;
0025         case IAVF_DEV_ID_VF:
0026         case IAVF_DEV_ID_VF_HV:
0027         case IAVF_DEV_ID_ADAPTIVE_VF:
0028             hw->mac.type = IAVF_MAC_VF;
0029             break;
0030         default:
0031             hw->mac.type = IAVF_MAC_GENERIC;
0032             break;
0033         }
0034     } else {
0035         status = IAVF_ERR_DEVICE_NOT_SUPPORTED;
0036     }
0037 
0038     hw_dbg(hw, "found mac: %d, returns: %d\n", hw->mac.type, status);
0039     return status;
0040 }
0041 
0042 /**
0043  * iavf_aq_str - convert AQ err code to a string
0044  * @hw: pointer to the HW structure
0045  * @aq_err: the AQ error code to convert
0046  **/
0047 const char *iavf_aq_str(struct iavf_hw *hw, enum iavf_admin_queue_err aq_err)
0048 {
0049     switch (aq_err) {
0050     case IAVF_AQ_RC_OK:
0051         return "OK";
0052     case IAVF_AQ_RC_EPERM:
0053         return "IAVF_AQ_RC_EPERM";
0054     case IAVF_AQ_RC_ENOENT:
0055         return "IAVF_AQ_RC_ENOENT";
0056     case IAVF_AQ_RC_ESRCH:
0057         return "IAVF_AQ_RC_ESRCH";
0058     case IAVF_AQ_RC_EINTR:
0059         return "IAVF_AQ_RC_EINTR";
0060     case IAVF_AQ_RC_EIO:
0061         return "IAVF_AQ_RC_EIO";
0062     case IAVF_AQ_RC_ENXIO:
0063         return "IAVF_AQ_RC_ENXIO";
0064     case IAVF_AQ_RC_E2BIG:
0065         return "IAVF_AQ_RC_E2BIG";
0066     case IAVF_AQ_RC_EAGAIN:
0067         return "IAVF_AQ_RC_EAGAIN";
0068     case IAVF_AQ_RC_ENOMEM:
0069         return "IAVF_AQ_RC_ENOMEM";
0070     case IAVF_AQ_RC_EACCES:
0071         return "IAVF_AQ_RC_EACCES";
0072     case IAVF_AQ_RC_EFAULT:
0073         return "IAVF_AQ_RC_EFAULT";
0074     case IAVF_AQ_RC_EBUSY:
0075         return "IAVF_AQ_RC_EBUSY";
0076     case IAVF_AQ_RC_EEXIST:
0077         return "IAVF_AQ_RC_EEXIST";
0078     case IAVF_AQ_RC_EINVAL:
0079         return "IAVF_AQ_RC_EINVAL";
0080     case IAVF_AQ_RC_ENOTTY:
0081         return "IAVF_AQ_RC_ENOTTY";
0082     case IAVF_AQ_RC_ENOSPC:
0083         return "IAVF_AQ_RC_ENOSPC";
0084     case IAVF_AQ_RC_ENOSYS:
0085         return "IAVF_AQ_RC_ENOSYS";
0086     case IAVF_AQ_RC_ERANGE:
0087         return "IAVF_AQ_RC_ERANGE";
0088     case IAVF_AQ_RC_EFLUSHED:
0089         return "IAVF_AQ_RC_EFLUSHED";
0090     case IAVF_AQ_RC_BAD_ADDR:
0091         return "IAVF_AQ_RC_BAD_ADDR";
0092     case IAVF_AQ_RC_EMODE:
0093         return "IAVF_AQ_RC_EMODE";
0094     case IAVF_AQ_RC_EFBIG:
0095         return "IAVF_AQ_RC_EFBIG";
0096     }
0097 
0098     snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
0099     return hw->err_str;
0100 }
0101 
0102 /**
0103  * iavf_stat_str - convert status err code to a string
0104  * @hw: pointer to the HW structure
0105  * @stat_err: the status error code to convert
0106  **/
0107 const char *iavf_stat_str(struct iavf_hw *hw, enum iavf_status stat_err)
0108 {
0109     switch (stat_err) {
0110     case 0:
0111         return "OK";
0112     case IAVF_ERR_NVM:
0113         return "IAVF_ERR_NVM";
0114     case IAVF_ERR_NVM_CHECKSUM:
0115         return "IAVF_ERR_NVM_CHECKSUM";
0116     case IAVF_ERR_PHY:
0117         return "IAVF_ERR_PHY";
0118     case IAVF_ERR_CONFIG:
0119         return "IAVF_ERR_CONFIG";
0120     case IAVF_ERR_PARAM:
0121         return "IAVF_ERR_PARAM";
0122     case IAVF_ERR_MAC_TYPE:
0123         return "IAVF_ERR_MAC_TYPE";
0124     case IAVF_ERR_UNKNOWN_PHY:
0125         return "IAVF_ERR_UNKNOWN_PHY";
0126     case IAVF_ERR_LINK_SETUP:
0127         return "IAVF_ERR_LINK_SETUP";
0128     case IAVF_ERR_ADAPTER_STOPPED:
0129         return "IAVF_ERR_ADAPTER_STOPPED";
0130     case IAVF_ERR_INVALID_MAC_ADDR:
0131         return "IAVF_ERR_INVALID_MAC_ADDR";
0132     case IAVF_ERR_DEVICE_NOT_SUPPORTED:
0133         return "IAVF_ERR_DEVICE_NOT_SUPPORTED";
0134     case IAVF_ERR_PRIMARY_REQUESTS_PENDING:
0135         return "IAVF_ERR_PRIMARY_REQUESTS_PENDING";
0136     case IAVF_ERR_INVALID_LINK_SETTINGS:
0137         return "IAVF_ERR_INVALID_LINK_SETTINGS";
0138     case IAVF_ERR_AUTONEG_NOT_COMPLETE:
0139         return "IAVF_ERR_AUTONEG_NOT_COMPLETE";
0140     case IAVF_ERR_RESET_FAILED:
0141         return "IAVF_ERR_RESET_FAILED";
0142     case IAVF_ERR_SWFW_SYNC:
0143         return "IAVF_ERR_SWFW_SYNC";
0144     case IAVF_ERR_NO_AVAILABLE_VSI:
0145         return "IAVF_ERR_NO_AVAILABLE_VSI";
0146     case IAVF_ERR_NO_MEMORY:
0147         return "IAVF_ERR_NO_MEMORY";
0148     case IAVF_ERR_BAD_PTR:
0149         return "IAVF_ERR_BAD_PTR";
0150     case IAVF_ERR_RING_FULL:
0151         return "IAVF_ERR_RING_FULL";
0152     case IAVF_ERR_INVALID_PD_ID:
0153         return "IAVF_ERR_INVALID_PD_ID";
0154     case IAVF_ERR_INVALID_QP_ID:
0155         return "IAVF_ERR_INVALID_QP_ID";
0156     case IAVF_ERR_INVALID_CQ_ID:
0157         return "IAVF_ERR_INVALID_CQ_ID";
0158     case IAVF_ERR_INVALID_CEQ_ID:
0159         return "IAVF_ERR_INVALID_CEQ_ID";
0160     case IAVF_ERR_INVALID_AEQ_ID:
0161         return "IAVF_ERR_INVALID_AEQ_ID";
0162     case IAVF_ERR_INVALID_SIZE:
0163         return "IAVF_ERR_INVALID_SIZE";
0164     case IAVF_ERR_INVALID_ARP_INDEX:
0165         return "IAVF_ERR_INVALID_ARP_INDEX";
0166     case IAVF_ERR_INVALID_FPM_FUNC_ID:
0167         return "IAVF_ERR_INVALID_FPM_FUNC_ID";
0168     case IAVF_ERR_QP_INVALID_MSG_SIZE:
0169         return "IAVF_ERR_QP_INVALID_MSG_SIZE";
0170     case IAVF_ERR_QP_TOOMANY_WRS_POSTED:
0171         return "IAVF_ERR_QP_TOOMANY_WRS_POSTED";
0172     case IAVF_ERR_INVALID_FRAG_COUNT:
0173         return "IAVF_ERR_INVALID_FRAG_COUNT";
0174     case IAVF_ERR_QUEUE_EMPTY:
0175         return "IAVF_ERR_QUEUE_EMPTY";
0176     case IAVF_ERR_INVALID_ALIGNMENT:
0177         return "IAVF_ERR_INVALID_ALIGNMENT";
0178     case IAVF_ERR_FLUSHED_QUEUE:
0179         return "IAVF_ERR_FLUSHED_QUEUE";
0180     case IAVF_ERR_INVALID_PUSH_PAGE_INDEX:
0181         return "IAVF_ERR_INVALID_PUSH_PAGE_INDEX";
0182     case IAVF_ERR_INVALID_IMM_DATA_SIZE:
0183         return "IAVF_ERR_INVALID_IMM_DATA_SIZE";
0184     case IAVF_ERR_TIMEOUT:
0185         return "IAVF_ERR_TIMEOUT";
0186     case IAVF_ERR_OPCODE_MISMATCH:
0187         return "IAVF_ERR_OPCODE_MISMATCH";
0188     case IAVF_ERR_CQP_COMPL_ERROR:
0189         return "IAVF_ERR_CQP_COMPL_ERROR";
0190     case IAVF_ERR_INVALID_VF_ID:
0191         return "IAVF_ERR_INVALID_VF_ID";
0192     case IAVF_ERR_INVALID_HMCFN_ID:
0193         return "IAVF_ERR_INVALID_HMCFN_ID";
0194     case IAVF_ERR_BACKING_PAGE_ERROR:
0195         return "IAVF_ERR_BACKING_PAGE_ERROR";
0196     case IAVF_ERR_NO_PBLCHUNKS_AVAILABLE:
0197         return "IAVF_ERR_NO_PBLCHUNKS_AVAILABLE";
0198     case IAVF_ERR_INVALID_PBLE_INDEX:
0199         return "IAVF_ERR_INVALID_PBLE_INDEX";
0200     case IAVF_ERR_INVALID_SD_INDEX:
0201         return "IAVF_ERR_INVALID_SD_INDEX";
0202     case IAVF_ERR_INVALID_PAGE_DESC_INDEX:
0203         return "IAVF_ERR_INVALID_PAGE_DESC_INDEX";
0204     case IAVF_ERR_INVALID_SD_TYPE:
0205         return "IAVF_ERR_INVALID_SD_TYPE";
0206     case IAVF_ERR_MEMCPY_FAILED:
0207         return "IAVF_ERR_MEMCPY_FAILED";
0208     case IAVF_ERR_INVALID_HMC_OBJ_INDEX:
0209         return "IAVF_ERR_INVALID_HMC_OBJ_INDEX";
0210     case IAVF_ERR_INVALID_HMC_OBJ_COUNT:
0211         return "IAVF_ERR_INVALID_HMC_OBJ_COUNT";
0212     case IAVF_ERR_INVALID_SRQ_ARM_LIMIT:
0213         return "IAVF_ERR_INVALID_SRQ_ARM_LIMIT";
0214     case IAVF_ERR_SRQ_ENABLED:
0215         return "IAVF_ERR_SRQ_ENABLED";
0216     case IAVF_ERR_ADMIN_QUEUE_ERROR:
0217         return "IAVF_ERR_ADMIN_QUEUE_ERROR";
0218     case IAVF_ERR_ADMIN_QUEUE_TIMEOUT:
0219         return "IAVF_ERR_ADMIN_QUEUE_TIMEOUT";
0220     case IAVF_ERR_BUF_TOO_SHORT:
0221         return "IAVF_ERR_BUF_TOO_SHORT";
0222     case IAVF_ERR_ADMIN_QUEUE_FULL:
0223         return "IAVF_ERR_ADMIN_QUEUE_FULL";
0224     case IAVF_ERR_ADMIN_QUEUE_NO_WORK:
0225         return "IAVF_ERR_ADMIN_QUEUE_NO_WORK";
0226     case IAVF_ERR_BAD_IWARP_CQE:
0227         return "IAVF_ERR_BAD_IWARP_CQE";
0228     case IAVF_ERR_NVM_BLANK_MODE:
0229         return "IAVF_ERR_NVM_BLANK_MODE";
0230     case IAVF_ERR_NOT_IMPLEMENTED:
0231         return "IAVF_ERR_NOT_IMPLEMENTED";
0232     case IAVF_ERR_PE_DOORBELL_NOT_ENABLED:
0233         return "IAVF_ERR_PE_DOORBELL_NOT_ENABLED";
0234     case IAVF_ERR_DIAG_TEST_FAILED:
0235         return "IAVF_ERR_DIAG_TEST_FAILED";
0236     case IAVF_ERR_NOT_READY:
0237         return "IAVF_ERR_NOT_READY";
0238     case IAVF_NOT_SUPPORTED:
0239         return "IAVF_NOT_SUPPORTED";
0240     case IAVF_ERR_FIRMWARE_API_VERSION:
0241         return "IAVF_ERR_FIRMWARE_API_VERSION";
0242     case IAVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
0243         return "IAVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
0244     }
0245 
0246     snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
0247     return hw->err_str;
0248 }
0249 
0250 /**
0251  * iavf_debug_aq
0252  * @hw: debug mask related to admin queue
0253  * @mask: debug mask
0254  * @desc: pointer to admin queue descriptor
0255  * @buffer: pointer to command buffer
0256  * @buf_len: max length of buffer
0257  *
0258  * Dumps debug log about adminq command with descriptor contents.
0259  **/
0260 void iavf_debug_aq(struct iavf_hw *hw, enum iavf_debug_mask mask, void *desc,
0261            void *buffer, u16 buf_len)
0262 {
0263     struct iavf_aq_desc *aq_desc = (struct iavf_aq_desc *)desc;
0264     u8 *buf = (u8 *)buffer;
0265 
0266     if ((!(mask & hw->debug_mask)) || !desc)
0267         return;
0268 
0269     iavf_debug(hw, mask,
0270            "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
0271            le16_to_cpu(aq_desc->opcode),
0272            le16_to_cpu(aq_desc->flags),
0273            le16_to_cpu(aq_desc->datalen),
0274            le16_to_cpu(aq_desc->retval));
0275     iavf_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
0276            le32_to_cpu(aq_desc->cookie_high),
0277            le32_to_cpu(aq_desc->cookie_low));
0278     iavf_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n",
0279            le32_to_cpu(aq_desc->params.internal.param0),
0280            le32_to_cpu(aq_desc->params.internal.param1));
0281     iavf_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n",
0282            le32_to_cpu(aq_desc->params.external.addr_high),
0283            le32_to_cpu(aq_desc->params.external.addr_low));
0284 
0285     if (buffer && aq_desc->datalen) {
0286         u16 len = le16_to_cpu(aq_desc->datalen);
0287 
0288         iavf_debug(hw, mask, "AQ CMD Buffer:\n");
0289         if (buf_len < len)
0290             len = buf_len;
0291         /* write the full 16-byte chunks */
0292         if (hw->debug_mask & mask) {
0293             char prefix[27];
0294 
0295             snprintf(prefix, sizeof(prefix),
0296                  "iavf %02x:%02x.%x: \t0x",
0297                  hw->bus.bus_id,
0298                  hw->bus.device,
0299                  hw->bus.func);
0300 
0301             print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET,
0302                        16, 1, buf, len, false);
0303         }
0304     }
0305 }
0306 
0307 /**
0308  * iavf_check_asq_alive
0309  * @hw: pointer to the hw struct
0310  *
0311  * Returns true if Queue is enabled else false.
0312  **/
0313 bool iavf_check_asq_alive(struct iavf_hw *hw)
0314 {
0315     if (hw->aq.asq.len)
0316         return !!(rd32(hw, hw->aq.asq.len) &
0317               IAVF_VF_ATQLEN1_ATQENABLE_MASK);
0318     else
0319         return false;
0320 }
0321 
0322 /**
0323  * iavf_aq_queue_shutdown
0324  * @hw: pointer to the hw struct
0325  * @unloading: is the driver unloading itself
0326  *
0327  * Tell the Firmware that we're shutting down the AdminQ and whether
0328  * or not the driver is unloading as well.
0329  **/
0330 enum iavf_status iavf_aq_queue_shutdown(struct iavf_hw *hw, bool unloading)
0331 {
0332     struct iavf_aq_desc desc;
0333     struct iavf_aqc_queue_shutdown *cmd =
0334         (struct iavf_aqc_queue_shutdown *)&desc.params.raw;
0335     enum iavf_status status;
0336 
0337     iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_queue_shutdown);
0338 
0339     if (unloading)
0340         cmd->driver_unloading = cpu_to_le32(IAVF_AQ_DRIVER_UNLOADING);
0341     status = iavf_asq_send_command(hw, &desc, NULL, 0, NULL);
0342 
0343     return status;
0344 }
0345 
0346 /**
0347  * iavf_aq_get_set_rss_lut
0348  * @hw: pointer to the hardware structure
0349  * @vsi_id: vsi fw index
0350  * @pf_lut: for PF table set true, for VSI table set false
0351  * @lut: pointer to the lut buffer provided by the caller
0352  * @lut_size: size of the lut buffer
0353  * @set: set true to set the table, false to get the table
0354  *
0355  * Internal function to get or set RSS look up table
0356  **/
0357 static enum iavf_status iavf_aq_get_set_rss_lut(struct iavf_hw *hw,
0358                         u16 vsi_id, bool pf_lut,
0359                         u8 *lut, u16 lut_size,
0360                         bool set)
0361 {
0362     enum iavf_status status;
0363     struct iavf_aq_desc desc;
0364     struct iavf_aqc_get_set_rss_lut *cmd_resp =
0365            (struct iavf_aqc_get_set_rss_lut *)&desc.params.raw;
0366 
0367     if (set)
0368         iavf_fill_default_direct_cmd_desc(&desc,
0369                           iavf_aqc_opc_set_rss_lut);
0370     else
0371         iavf_fill_default_direct_cmd_desc(&desc,
0372                           iavf_aqc_opc_get_rss_lut);
0373 
0374     /* Indirect command */
0375     desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_BUF);
0376     desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_RD);
0377 
0378     cmd_resp->vsi_id =
0379             cpu_to_le16((u16)((vsi_id <<
0380                       IAVF_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
0381                       IAVF_AQC_SET_RSS_LUT_VSI_ID_MASK));
0382     cmd_resp->vsi_id |= cpu_to_le16((u16)IAVF_AQC_SET_RSS_LUT_VSI_VALID);
0383 
0384     if (pf_lut)
0385         cmd_resp->flags |= cpu_to_le16((u16)
0386                     ((IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
0387                     IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
0388                     IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
0389     else
0390         cmd_resp->flags |= cpu_to_le16((u16)
0391                     ((IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
0392                     IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
0393                     IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
0394 
0395     status = iavf_asq_send_command(hw, &desc, lut, lut_size, NULL);
0396 
0397     return status;
0398 }
0399 
0400 /**
0401  * iavf_aq_get_rss_lut
0402  * @hw: pointer to the hardware structure
0403  * @vsi_id: vsi fw index
0404  * @pf_lut: for PF table set true, for VSI table set false
0405  * @lut: pointer to the lut buffer provided by the caller
0406  * @lut_size: size of the lut buffer
0407  *
0408  * get the RSS lookup table, PF or VSI type
0409  **/
0410 enum iavf_status iavf_aq_get_rss_lut(struct iavf_hw *hw, u16 vsi_id,
0411                      bool pf_lut, u8 *lut, u16 lut_size)
0412 {
0413     return iavf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
0414                        false);
0415 }
0416 
0417 /**
0418  * iavf_aq_set_rss_lut
0419  * @hw: pointer to the hardware structure
0420  * @vsi_id: vsi fw index
0421  * @pf_lut: for PF table set true, for VSI table set false
0422  * @lut: pointer to the lut buffer provided by the caller
0423  * @lut_size: size of the lut buffer
0424  *
0425  * set the RSS lookup table, PF or VSI type
0426  **/
0427 enum iavf_status iavf_aq_set_rss_lut(struct iavf_hw *hw, u16 vsi_id,
0428                      bool pf_lut, u8 *lut, u16 lut_size)
0429 {
0430     return iavf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
0431 }
0432 
0433 /**
0434  * iavf_aq_get_set_rss_key
0435  * @hw: pointer to the hw struct
0436  * @vsi_id: vsi fw index
0437  * @key: pointer to key info struct
0438  * @set: set true to set the key, false to get the key
0439  *
0440  * get the RSS key per VSI
0441  **/
0442 static enum
0443 iavf_status iavf_aq_get_set_rss_key(struct iavf_hw *hw, u16 vsi_id,
0444                     struct iavf_aqc_get_set_rss_key_data *key,
0445                     bool set)
0446 {
0447     enum iavf_status status;
0448     struct iavf_aq_desc desc;
0449     struct iavf_aqc_get_set_rss_key *cmd_resp =
0450             (struct iavf_aqc_get_set_rss_key *)&desc.params.raw;
0451     u16 key_size = sizeof(struct iavf_aqc_get_set_rss_key_data);
0452 
0453     if (set)
0454         iavf_fill_default_direct_cmd_desc(&desc,
0455                           iavf_aqc_opc_set_rss_key);
0456     else
0457         iavf_fill_default_direct_cmd_desc(&desc,
0458                           iavf_aqc_opc_get_rss_key);
0459 
0460     /* Indirect command */
0461     desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_BUF);
0462     desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_RD);
0463 
0464     cmd_resp->vsi_id =
0465             cpu_to_le16((u16)((vsi_id <<
0466                       IAVF_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
0467                       IAVF_AQC_SET_RSS_KEY_VSI_ID_MASK));
0468     cmd_resp->vsi_id |= cpu_to_le16((u16)IAVF_AQC_SET_RSS_KEY_VSI_VALID);
0469 
0470     status = iavf_asq_send_command(hw, &desc, key, key_size, NULL);
0471 
0472     return status;
0473 }
0474 
0475 /**
0476  * iavf_aq_get_rss_key
0477  * @hw: pointer to the hw struct
0478  * @vsi_id: vsi fw index
0479  * @key: pointer to key info struct
0480  *
0481  **/
0482 enum iavf_status iavf_aq_get_rss_key(struct iavf_hw *hw, u16 vsi_id,
0483                      struct iavf_aqc_get_set_rss_key_data *key)
0484 {
0485     return iavf_aq_get_set_rss_key(hw, vsi_id, key, false);
0486 }
0487 
0488 /**
0489  * iavf_aq_set_rss_key
0490  * @hw: pointer to the hw struct
0491  * @vsi_id: vsi fw index
0492  * @key: pointer to key info struct
0493  *
0494  * set the RSS key per VSI
0495  **/
0496 enum iavf_status iavf_aq_set_rss_key(struct iavf_hw *hw, u16 vsi_id,
0497                      struct iavf_aqc_get_set_rss_key_data *key)
0498 {
0499     return iavf_aq_get_set_rss_key(hw, vsi_id, key, true);
0500 }
0501 
0502 /* The iavf_ptype_lookup table is used to convert from the 8-bit ptype in the
0503  * hardware to a bit-field that can be used by SW to more easily determine the
0504  * packet type.
0505  *
0506  * Macros are used to shorten the table lines and make this table human
0507  * readable.
0508  *
0509  * We store the PTYPE in the top byte of the bit field - this is just so that
0510  * we can check that the table doesn't have a row missing, as the index into
0511  * the table should be the PTYPE.
0512  *
0513  * Typical work flow:
0514  *
0515  * IF NOT iavf_ptype_lookup[ptype].known
0516  * THEN
0517  *      Packet is unknown
0518  * ELSE IF iavf_ptype_lookup[ptype].outer_ip == IAVF_RX_PTYPE_OUTER_IP
0519  *      Use the rest of the fields to look at the tunnels, inner protocols, etc
0520  * ELSE
0521  *      Use the enum iavf_rx_l2_ptype to decode the packet type
0522  * ENDIF
0523  */
0524 
0525 /* macro to make the table lines short, use explicit indexing with [PTYPE] */
0526 #define IAVF_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
0527     [PTYPE] = { \
0528         1, \
0529         IAVF_RX_PTYPE_OUTER_##OUTER_IP, \
0530         IAVF_RX_PTYPE_OUTER_##OUTER_IP_VER, \
0531         IAVF_RX_PTYPE_##OUTER_FRAG, \
0532         IAVF_RX_PTYPE_TUNNEL_##T, \
0533         IAVF_RX_PTYPE_TUNNEL_END_##TE, \
0534         IAVF_RX_PTYPE_##TEF, \
0535         IAVF_RX_PTYPE_INNER_PROT_##I, \
0536         IAVF_RX_PTYPE_PAYLOAD_LAYER_##PL }
0537 
0538 #define IAVF_PTT_UNUSED_ENTRY(PTYPE) [PTYPE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
0539 
0540 /* shorter macros makes the table fit but are terse */
0541 #define IAVF_RX_PTYPE_NOF       IAVF_RX_PTYPE_NOT_FRAG
0542 #define IAVF_RX_PTYPE_FRG       IAVF_RX_PTYPE_FRAG
0543 #define IAVF_RX_PTYPE_INNER_PROT_TS IAVF_RX_PTYPE_INNER_PROT_TIMESYNC
0544 
0545 /* Lookup table mapping the 8-bit HW PTYPE to the bit field for decoding */
0546 struct iavf_rx_ptype_decoded iavf_ptype_lookup[BIT(8)] = {
0547     /* L2 Packet types */
0548     IAVF_PTT_UNUSED_ENTRY(0),
0549     IAVF_PTT(1,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
0550     IAVF_PTT(2,  L2, NONE, NOF, NONE, NONE, NOF, TS,   PAY2),
0551     IAVF_PTT(3,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
0552     IAVF_PTT_UNUSED_ENTRY(4),
0553     IAVF_PTT_UNUSED_ENTRY(5),
0554     IAVF_PTT(6,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
0555     IAVF_PTT(7,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
0556     IAVF_PTT_UNUSED_ENTRY(8),
0557     IAVF_PTT_UNUSED_ENTRY(9),
0558     IAVF_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
0559     IAVF_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
0560     IAVF_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0561     IAVF_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0562     IAVF_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0563     IAVF_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0564     IAVF_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0565     IAVF_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0566     IAVF_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0567     IAVF_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0568     IAVF_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0569     IAVF_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
0570 
0571     /* Non Tunneled IPv4 */
0572     IAVF_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
0573     IAVF_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
0574     IAVF_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP,  PAY4),
0575     IAVF_PTT_UNUSED_ENTRY(25),
0576     IAVF_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP,  PAY4),
0577     IAVF_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
0578     IAVF_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
0579 
0580     /* IPv4 --> IPv4 */
0581     IAVF_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
0582     IAVF_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
0583     IAVF_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
0584     IAVF_PTT_UNUSED_ENTRY(32),
0585     IAVF_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
0586     IAVF_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
0587     IAVF_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
0588 
0589     /* IPv4 --> IPv6 */
0590     IAVF_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
0591     IAVF_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
0592     IAVF_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
0593     IAVF_PTT_UNUSED_ENTRY(39),
0594     IAVF_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
0595     IAVF_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
0596     IAVF_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
0597 
0598     /* IPv4 --> GRE/NAT */
0599     IAVF_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
0600 
0601     /* IPv4 --> GRE/NAT --> IPv4 */
0602     IAVF_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
0603     IAVF_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
0604     IAVF_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
0605     IAVF_PTT_UNUSED_ENTRY(47),
0606     IAVF_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
0607     IAVF_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
0608     IAVF_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
0609 
0610     /* IPv4 --> GRE/NAT --> IPv6 */
0611     IAVF_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
0612     IAVF_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
0613     IAVF_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
0614     IAVF_PTT_UNUSED_ENTRY(54),
0615     IAVF_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
0616     IAVF_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
0617     IAVF_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
0618 
0619     /* IPv4 --> GRE/NAT --> MAC */
0620     IAVF_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
0621 
0622     /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
0623     IAVF_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
0624     IAVF_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
0625     IAVF_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
0626     IAVF_PTT_UNUSED_ENTRY(62),
0627     IAVF_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
0628     IAVF_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
0629     IAVF_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
0630 
0631     /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
0632     IAVF_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
0633     IAVF_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
0634     IAVF_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
0635     IAVF_PTT_UNUSED_ENTRY(69),
0636     IAVF_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
0637     IAVF_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
0638     IAVF_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
0639 
0640     /* IPv4 --> GRE/NAT --> MAC/VLAN */
0641     IAVF_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
0642 
0643     /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
0644     IAVF_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
0645     IAVF_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
0646     IAVF_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
0647     IAVF_PTT_UNUSED_ENTRY(77),
0648     IAVF_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
0649     IAVF_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
0650     IAVF_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
0651 
0652     /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
0653     IAVF_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
0654     IAVF_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
0655     IAVF_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
0656     IAVF_PTT_UNUSED_ENTRY(84),
0657     IAVF_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
0658     IAVF_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
0659     IAVF_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
0660 
0661     /* Non Tunneled IPv6 */
0662     IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
0663     IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
0664     IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3),
0665     IAVF_PTT_UNUSED_ENTRY(91),
0666     IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
0667     IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
0668     IAVF_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
0669 
0670     /* IPv6 --> IPv4 */
0671     IAVF_PTT(95,  IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
0672     IAVF_PTT(96,  IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
0673     IAVF_PTT(97,  IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
0674     IAVF_PTT_UNUSED_ENTRY(98),
0675     IAVF_PTT(99,  IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
0676     IAVF_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
0677     IAVF_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
0678 
0679     /* IPv6 --> IPv6 */
0680     IAVF_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
0681     IAVF_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
0682     IAVF_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
0683     IAVF_PTT_UNUSED_ENTRY(105),
0684     IAVF_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
0685     IAVF_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
0686     IAVF_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
0687 
0688     /* IPv6 --> GRE/NAT */
0689     IAVF_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
0690 
0691     /* IPv6 --> GRE/NAT -> IPv4 */
0692     IAVF_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
0693     IAVF_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
0694     IAVF_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
0695     IAVF_PTT_UNUSED_ENTRY(113),
0696     IAVF_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
0697     IAVF_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
0698     IAVF_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
0699 
0700     /* IPv6 --> GRE/NAT -> IPv6 */
0701     IAVF_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
0702     IAVF_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
0703     IAVF_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
0704     IAVF_PTT_UNUSED_ENTRY(120),
0705     IAVF_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
0706     IAVF_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
0707     IAVF_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
0708 
0709     /* IPv6 --> GRE/NAT -> MAC */
0710     IAVF_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
0711 
0712     /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
0713     IAVF_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
0714     IAVF_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
0715     IAVF_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
0716     IAVF_PTT_UNUSED_ENTRY(128),
0717     IAVF_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
0718     IAVF_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
0719     IAVF_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
0720 
0721     /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
0722     IAVF_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
0723     IAVF_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
0724     IAVF_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
0725     IAVF_PTT_UNUSED_ENTRY(135),
0726     IAVF_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
0727     IAVF_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
0728     IAVF_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
0729 
0730     /* IPv6 --> GRE/NAT -> MAC/VLAN */
0731     IAVF_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
0732 
0733     /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
0734     IAVF_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
0735     IAVF_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
0736     IAVF_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
0737     IAVF_PTT_UNUSED_ENTRY(143),
0738     IAVF_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
0739     IAVF_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
0740     IAVF_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
0741 
0742     /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
0743     IAVF_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
0744     IAVF_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
0745     IAVF_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
0746     IAVF_PTT_UNUSED_ENTRY(150),
0747     IAVF_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
0748     IAVF_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
0749     IAVF_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
0750 
0751     /* unused entries */
0752     [154 ... 255] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
0753 };
0754 
0755 /**
0756  * iavf_aq_send_msg_to_pf
0757  * @hw: pointer to the hardware structure
0758  * @v_opcode: opcodes for VF-PF communication
0759  * @v_retval: return error code
0760  * @msg: pointer to the msg buffer
0761  * @msglen: msg length
0762  * @cmd_details: pointer to command details
0763  *
0764  * Send message to PF driver using admin queue. By default, this message
0765  * is sent asynchronously, i.e. iavf_asq_send_command() does not wait for
0766  * completion before returning.
0767  **/
0768 enum iavf_status iavf_aq_send_msg_to_pf(struct iavf_hw *hw,
0769                     enum virtchnl_ops v_opcode,
0770                     enum iavf_status v_retval,
0771                     u8 *msg, u16 msglen,
0772                     struct iavf_asq_cmd_details *cmd_details)
0773 {
0774     struct iavf_asq_cmd_details details;
0775     struct iavf_aq_desc desc;
0776     enum iavf_status status;
0777 
0778     iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_send_msg_to_pf);
0779     desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_SI);
0780     desc.cookie_high = cpu_to_le32(v_opcode);
0781     desc.cookie_low = cpu_to_le32(v_retval);
0782     if (msglen) {
0783         desc.flags |= cpu_to_le16((u16)(IAVF_AQ_FLAG_BUF
0784                         | IAVF_AQ_FLAG_RD));
0785         if (msglen > IAVF_AQ_LARGE_BUF)
0786             desc.flags |= cpu_to_le16((u16)IAVF_AQ_FLAG_LB);
0787         desc.datalen = cpu_to_le16(msglen);
0788     }
0789     if (!cmd_details) {
0790         memset(&details, 0, sizeof(details));
0791         details.async = true;
0792         cmd_details = &details;
0793     }
0794     status = iavf_asq_send_command(hw, &desc, msg, msglen, cmd_details);
0795     return status;
0796 }
0797 
0798 /**
0799  * iavf_vf_parse_hw_config
0800  * @hw: pointer to the hardware structure
0801  * @msg: pointer to the virtual channel VF resource structure
0802  *
0803  * Given a VF resource message from the PF, populate the hw struct
0804  * with appropriate information.
0805  **/
0806 void iavf_vf_parse_hw_config(struct iavf_hw *hw,
0807                  struct virtchnl_vf_resource *msg)
0808 {
0809     struct virtchnl_vsi_resource *vsi_res;
0810     int i;
0811 
0812     vsi_res = &msg->vsi_res[0];
0813 
0814     hw->dev_caps.num_vsis = msg->num_vsis;
0815     hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
0816     hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
0817     hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
0818     hw->dev_caps.dcb = msg->vf_cap_flags &
0819                VIRTCHNL_VF_OFFLOAD_L2;
0820     hw->dev_caps.fcoe = 0;
0821     for (i = 0; i < msg->num_vsis; i++) {
0822         if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
0823             ether_addr_copy(hw->mac.perm_addr,
0824                     vsi_res->default_mac_addr);
0825             ether_addr_copy(hw->mac.addr,
0826                     vsi_res->default_mac_addr);
0827         }
0828         vsi_res++;
0829     }
0830 }
0831 
0832 /**
0833  * iavf_vf_reset
0834  * @hw: pointer to the hardware structure
0835  *
0836  * Send a VF_RESET message to the PF. Does not wait for response from PF
0837  * as none will be forthcoming. Immediately after calling this function,
0838  * the admin queue should be shut down and (optionally) reinitialized.
0839  **/
0840 enum iavf_status iavf_vf_reset(struct iavf_hw *hw)
0841 {
0842     return iavf_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
0843                       0, NULL, 0, NULL);
0844 }