17ec59eeaSAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0 27ec59eeaSAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */ 37ec59eeaSAnirudh Venkataramanan 47ec59eeaSAnirudh Venkataramanan #include "ice_common.h" 59c20346bSAnirudh Venkataramanan #include "ice_sched.h" 67ec59eeaSAnirudh Venkataramanan #include "ice_adminq_cmd.h" 77ec59eeaSAnirudh Venkataramanan 8f31e4b6fSAnirudh Venkataramanan #define ICE_PF_RESET_WAIT_COUNT 200 9f31e4b6fSAnirudh Venkataramanan 10cdedef59SAnirudh Venkataramanan #define ICE_NIC_FLX_ENTRY(hw, mdid, idx) \ 11cdedef59SAnirudh Venkataramanan wr32((hw), GLFLXP_RXDID_FLX_WRD_##idx(ICE_RXDID_FLEX_NIC), \ 12cdedef59SAnirudh Venkataramanan ((ICE_RX_OPC_MDID << \ 13cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLX_WRD_##idx##_RXDID_OPCODE_S) & \ 14cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLX_WRD_##idx##_RXDID_OPCODE_M) | \ 15cdedef59SAnirudh Venkataramanan (((mdid) << GLFLXP_RXDID_FLX_WRD_##idx##_PROT_MDID_S) & \ 16cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLX_WRD_##idx##_PROT_MDID_M)) 17cdedef59SAnirudh Venkataramanan 18cdedef59SAnirudh Venkataramanan #define ICE_NIC_FLX_FLG_ENTRY(hw, flg_0, flg_1, flg_2, flg_3, idx) \ 19cdedef59SAnirudh Venkataramanan wr32((hw), GLFLXP_RXDID_FLAGS(ICE_RXDID_FLEX_NIC, idx), \ 20cdedef59SAnirudh Venkataramanan (((flg_0) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S) & \ 21cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M) | \ 22cdedef59SAnirudh Venkataramanan (((flg_1) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_1_S) & \ 23cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_1_M) | \ 24cdedef59SAnirudh Venkataramanan (((flg_2) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_2_S) & \ 25cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_2_M) | \ 26cdedef59SAnirudh Venkataramanan (((flg_3) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_3_S) & \ 27cdedef59SAnirudh Venkataramanan GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_3_M)) 28cdedef59SAnirudh Venkataramanan 29f31e4b6fSAnirudh Venkataramanan /** 30f31e4b6fSAnirudh Venkataramanan * ice_set_mac_type - Sets MAC type 31f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 32f31e4b6fSAnirudh Venkataramanan * 33f31e4b6fSAnirudh Venkataramanan * This function sets the MAC type of the adapter based on the 34f31e4b6fSAnirudh Venkataramanan * vendor ID and device ID stored in the hw structure. 35f31e4b6fSAnirudh Venkataramanan */ 36f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_set_mac_type(struct ice_hw *hw) 37f31e4b6fSAnirudh Venkataramanan { 38f31e4b6fSAnirudh Venkataramanan if (hw->vendor_id != PCI_VENDOR_ID_INTEL) 39f31e4b6fSAnirudh Venkataramanan return ICE_ERR_DEVICE_NOT_SUPPORTED; 40f31e4b6fSAnirudh Venkataramanan 41f31e4b6fSAnirudh Venkataramanan hw->mac_type = ICE_MAC_GENERIC; 42f31e4b6fSAnirudh Venkataramanan return 0; 43f31e4b6fSAnirudh Venkataramanan } 44f31e4b6fSAnirudh Venkataramanan 45f31e4b6fSAnirudh Venkataramanan /** 46f31e4b6fSAnirudh Venkataramanan * ice_clear_pf_cfg - Clear PF configuration 47f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 48f31e4b6fSAnirudh Venkataramanan */ 49f31e4b6fSAnirudh Venkataramanan enum ice_status ice_clear_pf_cfg(struct ice_hw *hw) 50f31e4b6fSAnirudh Venkataramanan { 51f31e4b6fSAnirudh Venkataramanan struct ice_aq_desc desc; 52f31e4b6fSAnirudh Venkataramanan 53f31e4b6fSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pf_cfg); 54f31e4b6fSAnirudh Venkataramanan 55f31e4b6fSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 56f31e4b6fSAnirudh Venkataramanan } 57f31e4b6fSAnirudh Venkataramanan 58f31e4b6fSAnirudh Venkataramanan /** 59dc49c772SAnirudh Venkataramanan * ice_aq_manage_mac_read - manage MAC address read command 60dc49c772SAnirudh Venkataramanan * @hw: pointer to the hw struct 61dc49c772SAnirudh Venkataramanan * @buf: a virtual buffer to hold the manage MAC read response 62dc49c772SAnirudh Venkataramanan * @buf_size: Size of the virtual buffer 63dc49c772SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 64dc49c772SAnirudh Venkataramanan * 65dc49c772SAnirudh Venkataramanan * This function is used to return per PF station MAC address (0x0107). 66dc49c772SAnirudh Venkataramanan * NOTE: Upon successful completion of this command, MAC address information 67dc49c772SAnirudh Venkataramanan * is returned in user specified buffer. Please interpret user specified 68dc49c772SAnirudh Venkataramanan * buffer as "manage_mac_read" response. 69dc49c772SAnirudh Venkataramanan * Response such as various MAC addresses are stored in HW struct (port.mac) 70dc49c772SAnirudh Venkataramanan * ice_aq_discover_caps is expected to be called before this function is called. 71dc49c772SAnirudh Venkataramanan */ 72dc49c772SAnirudh Venkataramanan static enum ice_status 73dc49c772SAnirudh Venkataramanan ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size, 74dc49c772SAnirudh Venkataramanan struct ice_sq_cd *cd) 75dc49c772SAnirudh Venkataramanan { 76dc49c772SAnirudh Venkataramanan struct ice_aqc_manage_mac_read_resp *resp; 77dc49c772SAnirudh Venkataramanan struct ice_aqc_manage_mac_read *cmd; 78dc49c772SAnirudh Venkataramanan struct ice_aq_desc desc; 79dc49c772SAnirudh Venkataramanan enum ice_status status; 80dc49c772SAnirudh Venkataramanan u16 flags; 81dc49c772SAnirudh Venkataramanan 82dc49c772SAnirudh Venkataramanan cmd = &desc.params.mac_read; 83dc49c772SAnirudh Venkataramanan 84dc49c772SAnirudh Venkataramanan if (buf_size < sizeof(*resp)) 85dc49c772SAnirudh Venkataramanan return ICE_ERR_BUF_TOO_SHORT; 86dc49c772SAnirudh Venkataramanan 87dc49c772SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read); 88dc49c772SAnirudh Venkataramanan 89dc49c772SAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 90dc49c772SAnirudh Venkataramanan if (status) 91dc49c772SAnirudh Venkataramanan return status; 92dc49c772SAnirudh Venkataramanan 93dc49c772SAnirudh Venkataramanan resp = (struct ice_aqc_manage_mac_read_resp *)buf; 94dc49c772SAnirudh Venkataramanan flags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M; 95dc49c772SAnirudh Venkataramanan 96dc49c772SAnirudh Venkataramanan if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) { 97dc49c772SAnirudh Venkataramanan ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n"); 98dc49c772SAnirudh Venkataramanan return ICE_ERR_CFG; 99dc49c772SAnirudh Venkataramanan } 100dc49c772SAnirudh Venkataramanan 101dc49c772SAnirudh Venkataramanan ether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr); 102dc49c772SAnirudh Venkataramanan ether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr); 103dc49c772SAnirudh Venkataramanan return 0; 104dc49c772SAnirudh Venkataramanan } 105dc49c772SAnirudh Venkataramanan 106dc49c772SAnirudh Venkataramanan /** 107dc49c772SAnirudh Venkataramanan * ice_aq_get_phy_caps - returns PHY capabilities 108dc49c772SAnirudh Venkataramanan * @pi: port information structure 109dc49c772SAnirudh Venkataramanan * @qual_mods: report qualified modules 110dc49c772SAnirudh Venkataramanan * @report_mode: report mode capabilities 111dc49c772SAnirudh Venkataramanan * @pcaps: structure for PHY capabilities to be filled 112dc49c772SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 113dc49c772SAnirudh Venkataramanan * 114dc49c772SAnirudh Venkataramanan * Returns the various PHY capabilities supported on the Port (0x0600) 115dc49c772SAnirudh Venkataramanan */ 116dc49c772SAnirudh Venkataramanan static enum ice_status 117dc49c772SAnirudh Venkataramanan ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode, 118dc49c772SAnirudh Venkataramanan struct ice_aqc_get_phy_caps_data *pcaps, 119dc49c772SAnirudh Venkataramanan struct ice_sq_cd *cd) 120dc49c772SAnirudh Venkataramanan { 121dc49c772SAnirudh Venkataramanan struct ice_aqc_get_phy_caps *cmd; 122dc49c772SAnirudh Venkataramanan u16 pcaps_size = sizeof(*pcaps); 123dc49c772SAnirudh Venkataramanan struct ice_aq_desc desc; 124dc49c772SAnirudh Venkataramanan enum ice_status status; 125dc49c772SAnirudh Venkataramanan 126dc49c772SAnirudh Venkataramanan cmd = &desc.params.get_phy; 127dc49c772SAnirudh Venkataramanan 128dc49c772SAnirudh Venkataramanan if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi) 129dc49c772SAnirudh Venkataramanan return ICE_ERR_PARAM; 130dc49c772SAnirudh Venkataramanan 131dc49c772SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps); 132dc49c772SAnirudh Venkataramanan 133dc49c772SAnirudh Venkataramanan if (qual_mods) 134dc49c772SAnirudh Venkataramanan cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM); 135dc49c772SAnirudh Venkataramanan 136dc49c772SAnirudh Venkataramanan cmd->param0 |= cpu_to_le16(report_mode); 137dc49c772SAnirudh Venkataramanan status = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd); 138dc49c772SAnirudh Venkataramanan 139dc49c772SAnirudh Venkataramanan if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP) 140dc49c772SAnirudh Venkataramanan pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low); 141dc49c772SAnirudh Venkataramanan 142dc49c772SAnirudh Venkataramanan return status; 143dc49c772SAnirudh Venkataramanan } 144dc49c772SAnirudh Venkataramanan 145dc49c772SAnirudh Venkataramanan /** 146dc49c772SAnirudh Venkataramanan * ice_get_media_type - Gets media type 147dc49c772SAnirudh Venkataramanan * @pi: port information structure 148dc49c772SAnirudh Venkataramanan */ 149dc49c772SAnirudh Venkataramanan static enum ice_media_type ice_get_media_type(struct ice_port_info *pi) 150dc49c772SAnirudh Venkataramanan { 151dc49c772SAnirudh Venkataramanan struct ice_link_status *hw_link_info; 152dc49c772SAnirudh Venkataramanan 153dc49c772SAnirudh Venkataramanan if (!pi) 154dc49c772SAnirudh Venkataramanan return ICE_MEDIA_UNKNOWN; 155dc49c772SAnirudh Venkataramanan 156dc49c772SAnirudh Venkataramanan hw_link_info = &pi->phy.link_info; 157dc49c772SAnirudh Venkataramanan 158dc49c772SAnirudh Venkataramanan if (hw_link_info->phy_type_low) { 159dc49c772SAnirudh Venkataramanan switch (hw_link_info->phy_type_low) { 160dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_1000BASE_SX: 161dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_1000BASE_LX: 162dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10GBASE_SR: 163dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10GBASE_LR: 164dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10G_SFI_C2C: 165dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_SR: 166dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_LR: 167dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25G_AUI_C2C: 168dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_40GBASE_SR4: 169dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_40GBASE_LR4: 170dc49c772SAnirudh Venkataramanan return ICE_MEDIA_FIBER; 171dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_100BASE_TX: 172dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_1000BASE_T: 173dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_2500BASE_T: 174dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_5GBASE_T: 175dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10GBASE_T: 176dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_T: 177dc49c772SAnirudh Venkataramanan return ICE_MEDIA_BASET; 178dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10G_SFI_DA: 179dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_CR: 180dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_CR_S: 181dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_CR1: 182dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_40GBASE_CR4: 183dc49c772SAnirudh Venkataramanan return ICE_MEDIA_DA; 184dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_1000BASE_KX: 185dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_2500BASE_KX: 186dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_2500BASE_X: 187dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_5GBASE_KR: 188dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1: 189dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_KR: 190dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_KR1: 191dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_25GBASE_KR_S: 192dc49c772SAnirudh Venkataramanan case ICE_PHY_TYPE_LOW_40GBASE_KR4: 193dc49c772SAnirudh Venkataramanan return ICE_MEDIA_BACKPLANE; 194dc49c772SAnirudh Venkataramanan } 195dc49c772SAnirudh Venkataramanan } 196dc49c772SAnirudh Venkataramanan 197dc49c772SAnirudh Venkataramanan return ICE_MEDIA_UNKNOWN; 198dc49c772SAnirudh Venkataramanan } 199dc49c772SAnirudh Venkataramanan 200dc49c772SAnirudh Venkataramanan /** 201dc49c772SAnirudh Venkataramanan * ice_aq_get_link_info 202dc49c772SAnirudh Venkataramanan * @pi: port information structure 203dc49c772SAnirudh Venkataramanan * @ena_lse: enable/disable LinkStatusEvent reporting 204dc49c772SAnirudh Venkataramanan * @link: pointer to link status structure - optional 205dc49c772SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 206dc49c772SAnirudh Venkataramanan * 207dc49c772SAnirudh Venkataramanan * Get Link Status (0x607). Returns the link status of the adapter. 208dc49c772SAnirudh Venkataramanan */ 209dc49c772SAnirudh Venkataramanan enum ice_status 210dc49c772SAnirudh Venkataramanan ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse, 211dc49c772SAnirudh Venkataramanan struct ice_link_status *link, struct ice_sq_cd *cd) 212dc49c772SAnirudh Venkataramanan { 213dc49c772SAnirudh Venkataramanan struct ice_link_status *hw_link_info_old, *hw_link_info; 214dc49c772SAnirudh Venkataramanan struct ice_aqc_get_link_status_data link_data = { 0 }; 215dc49c772SAnirudh Venkataramanan struct ice_aqc_get_link_status *resp; 216dc49c772SAnirudh Venkataramanan enum ice_media_type *hw_media_type; 217dc49c772SAnirudh Venkataramanan struct ice_fc_info *hw_fc_info; 218dc49c772SAnirudh Venkataramanan bool tx_pause, rx_pause; 219dc49c772SAnirudh Venkataramanan struct ice_aq_desc desc; 220dc49c772SAnirudh Venkataramanan enum ice_status status; 221dc49c772SAnirudh Venkataramanan u16 cmd_flags; 222dc49c772SAnirudh Venkataramanan 223dc49c772SAnirudh Venkataramanan if (!pi) 224dc49c772SAnirudh Venkataramanan return ICE_ERR_PARAM; 225dc49c772SAnirudh Venkataramanan hw_link_info_old = &pi->phy.link_info_old; 226dc49c772SAnirudh Venkataramanan hw_media_type = &pi->phy.media_type; 227dc49c772SAnirudh Venkataramanan hw_link_info = &pi->phy.link_info; 228dc49c772SAnirudh Venkataramanan hw_fc_info = &pi->fc; 229dc49c772SAnirudh Venkataramanan 230dc49c772SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status); 231dc49c772SAnirudh Venkataramanan cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS; 232dc49c772SAnirudh Venkataramanan resp = &desc.params.get_link_status; 233dc49c772SAnirudh Venkataramanan resp->cmd_flags = cpu_to_le16(cmd_flags); 234dc49c772SAnirudh Venkataramanan resp->lport_num = pi->lport; 235dc49c772SAnirudh Venkataramanan 236dc49c772SAnirudh Venkataramanan status = ice_aq_send_cmd(pi->hw, &desc, &link_data, sizeof(link_data), 237dc49c772SAnirudh Venkataramanan cd); 238dc49c772SAnirudh Venkataramanan 239dc49c772SAnirudh Venkataramanan if (status) 240dc49c772SAnirudh Venkataramanan return status; 241dc49c772SAnirudh Venkataramanan 242dc49c772SAnirudh Venkataramanan /* save off old link status information */ 243dc49c772SAnirudh Venkataramanan *hw_link_info_old = *hw_link_info; 244dc49c772SAnirudh Venkataramanan 245dc49c772SAnirudh Venkataramanan /* update current link status information */ 246dc49c772SAnirudh Venkataramanan hw_link_info->link_speed = le16_to_cpu(link_data.link_speed); 247dc49c772SAnirudh Venkataramanan hw_link_info->phy_type_low = le64_to_cpu(link_data.phy_type_low); 248dc49c772SAnirudh Venkataramanan *hw_media_type = ice_get_media_type(pi); 249dc49c772SAnirudh Venkataramanan hw_link_info->link_info = link_data.link_info; 250dc49c772SAnirudh Venkataramanan hw_link_info->an_info = link_data.an_info; 251dc49c772SAnirudh Venkataramanan hw_link_info->ext_info = link_data.ext_info; 252dc49c772SAnirudh Venkataramanan hw_link_info->max_frame_size = le16_to_cpu(link_data.max_frame_size); 253dc49c772SAnirudh Venkataramanan hw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M; 254dc49c772SAnirudh Venkataramanan 255dc49c772SAnirudh Venkataramanan /* update fc info */ 256dc49c772SAnirudh Venkataramanan tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX); 257dc49c772SAnirudh Venkataramanan rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX); 258dc49c772SAnirudh Venkataramanan if (tx_pause && rx_pause) 259dc49c772SAnirudh Venkataramanan hw_fc_info->current_mode = ICE_FC_FULL; 260dc49c772SAnirudh Venkataramanan else if (tx_pause) 261dc49c772SAnirudh Venkataramanan hw_fc_info->current_mode = ICE_FC_TX_PAUSE; 262dc49c772SAnirudh Venkataramanan else if (rx_pause) 263dc49c772SAnirudh Venkataramanan hw_fc_info->current_mode = ICE_FC_RX_PAUSE; 264dc49c772SAnirudh Venkataramanan else 265dc49c772SAnirudh Venkataramanan hw_fc_info->current_mode = ICE_FC_NONE; 266dc49c772SAnirudh Venkataramanan 267dc49c772SAnirudh Venkataramanan hw_link_info->lse_ena = 268dc49c772SAnirudh Venkataramanan !!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED)); 269dc49c772SAnirudh Venkataramanan 270dc49c772SAnirudh Venkataramanan /* save link status information */ 271dc49c772SAnirudh Venkataramanan if (link) 272dc49c772SAnirudh Venkataramanan *link = *hw_link_info; 273dc49c772SAnirudh Venkataramanan 274dc49c772SAnirudh Venkataramanan /* flag cleared so calling functions don't call AQ again */ 275dc49c772SAnirudh Venkataramanan pi->phy.get_link_info = false; 276dc49c772SAnirudh Venkataramanan 277dc49c772SAnirudh Venkataramanan return status; 278dc49c772SAnirudh Venkataramanan } 279dc49c772SAnirudh Venkataramanan 280dc49c772SAnirudh Venkataramanan /** 281cdedef59SAnirudh Venkataramanan * ice_init_flex_parser - initialize rx flex parser 282cdedef59SAnirudh Venkataramanan * @hw: pointer to the hardware structure 283cdedef59SAnirudh Venkataramanan * 284cdedef59SAnirudh Venkataramanan * Function to initialize flex descriptors 285cdedef59SAnirudh Venkataramanan */ 286cdedef59SAnirudh Venkataramanan static void ice_init_flex_parser(struct ice_hw *hw) 287cdedef59SAnirudh Venkataramanan { 288cdedef59SAnirudh Venkataramanan u8 idx = 0; 289cdedef59SAnirudh Venkataramanan 290cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_ENTRY(hw, ICE_RX_MDID_HASH_LOW, 0); 291cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_ENTRY(hw, ICE_RX_MDID_HASH_HIGH, 1); 292cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_ENTRY(hw, ICE_RX_MDID_FLOW_ID_LOWER, 2); 293cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_ENTRY(hw, ICE_RX_MDID_FLOW_ID_HIGH, 3); 294cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_FLG_ENTRY(hw, ICE_RXFLG_PKT_FRG, ICE_RXFLG_UDP_GRE, 295cdedef59SAnirudh Venkataramanan ICE_RXFLG_PKT_DSI, ICE_RXFLG_FIN, idx++); 296cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_FLG_ENTRY(hw, ICE_RXFLG_SYN, ICE_RXFLG_RST, 297cdedef59SAnirudh Venkataramanan ICE_RXFLG_PKT_DSI, ICE_RXFLG_PKT_DSI, idx++); 298cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_FLG_ENTRY(hw, ICE_RXFLG_PKT_DSI, ICE_RXFLG_PKT_DSI, 299cdedef59SAnirudh Venkataramanan ICE_RXFLG_EVLAN_x8100, ICE_RXFLG_EVLAN_x9100, 300cdedef59SAnirudh Venkataramanan idx++); 301cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_FLG_ENTRY(hw, ICE_RXFLG_VLAN_x8100, ICE_RXFLG_TNL_VLAN, 302cdedef59SAnirudh Venkataramanan ICE_RXFLG_TNL_MAC, ICE_RXFLG_TNL0, idx++); 303cdedef59SAnirudh Venkataramanan ICE_NIC_FLX_FLG_ENTRY(hw, ICE_RXFLG_TNL1, ICE_RXFLG_TNL2, 304cdedef59SAnirudh Venkataramanan ICE_RXFLG_PKT_DSI, ICE_RXFLG_PKT_DSI, idx); 305cdedef59SAnirudh Venkataramanan } 306cdedef59SAnirudh Venkataramanan 307cdedef59SAnirudh Venkataramanan /** 3089daf8208SAnirudh Venkataramanan * ice_init_fltr_mgmt_struct - initializes filter management list and locks 3099daf8208SAnirudh Venkataramanan * @hw: pointer to the hw struct 3109daf8208SAnirudh Venkataramanan */ 3119daf8208SAnirudh Venkataramanan static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) 3129daf8208SAnirudh Venkataramanan { 3139daf8208SAnirudh Venkataramanan struct ice_switch_info *sw; 3149daf8208SAnirudh Venkataramanan 3159daf8208SAnirudh Venkataramanan hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw), 3169daf8208SAnirudh Venkataramanan sizeof(*hw->switch_info), GFP_KERNEL); 3179daf8208SAnirudh Venkataramanan sw = hw->switch_info; 3189daf8208SAnirudh Venkataramanan 3199daf8208SAnirudh Venkataramanan if (!sw) 3209daf8208SAnirudh Venkataramanan return ICE_ERR_NO_MEMORY; 3219daf8208SAnirudh Venkataramanan 3229daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->vsi_list_map_head); 3239daf8208SAnirudh Venkataramanan 3249daf8208SAnirudh Venkataramanan mutex_init(&sw->mac_list_lock); 3259daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->mac_list_head); 3269daf8208SAnirudh Venkataramanan 3279daf8208SAnirudh Venkataramanan mutex_init(&sw->vlan_list_lock); 3289daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->vlan_list_head); 3299daf8208SAnirudh Venkataramanan 3309daf8208SAnirudh Venkataramanan mutex_init(&sw->eth_m_list_lock); 3319daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->eth_m_list_head); 3329daf8208SAnirudh Venkataramanan 3339daf8208SAnirudh Venkataramanan mutex_init(&sw->promisc_list_lock); 3349daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->promisc_list_head); 3359daf8208SAnirudh Venkataramanan 3369daf8208SAnirudh Venkataramanan mutex_init(&sw->mac_vlan_list_lock); 3379daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&sw->mac_vlan_list_head); 3389daf8208SAnirudh Venkataramanan 3399daf8208SAnirudh Venkataramanan return 0; 3409daf8208SAnirudh Venkataramanan } 3419daf8208SAnirudh Venkataramanan 3429daf8208SAnirudh Venkataramanan /** 3439daf8208SAnirudh Venkataramanan * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks 3449daf8208SAnirudh Venkataramanan * @hw: pointer to the hw struct 3459daf8208SAnirudh Venkataramanan */ 3469daf8208SAnirudh Venkataramanan static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw) 3479daf8208SAnirudh Venkataramanan { 3489daf8208SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 3499daf8208SAnirudh Venkataramanan struct ice_vsi_list_map_info *v_pos_map; 3509daf8208SAnirudh Venkataramanan struct ice_vsi_list_map_info *v_tmp_map; 3519daf8208SAnirudh Venkataramanan 3529daf8208SAnirudh Venkataramanan list_for_each_entry_safe(v_pos_map, v_tmp_map, &sw->vsi_list_map_head, 3539daf8208SAnirudh Venkataramanan list_entry) { 3549daf8208SAnirudh Venkataramanan list_del(&v_pos_map->list_entry); 3559daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), v_pos_map); 3569daf8208SAnirudh Venkataramanan } 3579daf8208SAnirudh Venkataramanan 3589daf8208SAnirudh Venkataramanan mutex_destroy(&sw->mac_list_lock); 3599daf8208SAnirudh Venkataramanan mutex_destroy(&sw->vlan_list_lock); 3609daf8208SAnirudh Venkataramanan mutex_destroy(&sw->eth_m_list_lock); 3619daf8208SAnirudh Venkataramanan mutex_destroy(&sw->promisc_list_lock); 3629daf8208SAnirudh Venkataramanan mutex_destroy(&sw->mac_vlan_list_lock); 3639daf8208SAnirudh Venkataramanan 3649daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), sw); 3659daf8208SAnirudh Venkataramanan } 3669daf8208SAnirudh Venkataramanan 3679daf8208SAnirudh Venkataramanan /** 368f31e4b6fSAnirudh Venkataramanan * ice_init_hw - main hardware initialization routine 369f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 370f31e4b6fSAnirudh Venkataramanan */ 371f31e4b6fSAnirudh Venkataramanan enum ice_status ice_init_hw(struct ice_hw *hw) 372f31e4b6fSAnirudh Venkataramanan { 373dc49c772SAnirudh Venkataramanan struct ice_aqc_get_phy_caps_data *pcaps; 374f31e4b6fSAnirudh Venkataramanan enum ice_status status; 375dc49c772SAnirudh Venkataramanan u16 mac_buf_len; 376dc49c772SAnirudh Venkataramanan void *mac_buf; 377f31e4b6fSAnirudh Venkataramanan 378f31e4b6fSAnirudh Venkataramanan /* Set MAC type based on DeviceID */ 379f31e4b6fSAnirudh Venkataramanan status = ice_set_mac_type(hw); 380f31e4b6fSAnirudh Venkataramanan if (status) 381f31e4b6fSAnirudh Venkataramanan return status; 382f31e4b6fSAnirudh Venkataramanan 383f31e4b6fSAnirudh Venkataramanan hw->pf_id = (u8)(rd32(hw, PF_FUNC_RID) & 384f31e4b6fSAnirudh Venkataramanan PF_FUNC_RID_FUNC_NUM_M) >> 385f31e4b6fSAnirudh Venkataramanan PF_FUNC_RID_FUNC_NUM_S; 386f31e4b6fSAnirudh Venkataramanan 387f31e4b6fSAnirudh Venkataramanan status = ice_reset(hw, ICE_RESET_PFR); 388f31e4b6fSAnirudh Venkataramanan if (status) 389f31e4b6fSAnirudh Venkataramanan return status; 390f31e4b6fSAnirudh Venkataramanan 391940b61afSAnirudh Venkataramanan /* set these values to minimum allowed */ 392940b61afSAnirudh Venkataramanan hw->itr_gran_200 = ICE_ITR_GRAN_MIN_200; 393940b61afSAnirudh Venkataramanan hw->itr_gran_100 = ICE_ITR_GRAN_MIN_100; 394940b61afSAnirudh Venkataramanan hw->itr_gran_50 = ICE_ITR_GRAN_MIN_50; 395940b61afSAnirudh Venkataramanan hw->itr_gran_25 = ICE_ITR_GRAN_MIN_25; 396940b61afSAnirudh Venkataramanan 397f31e4b6fSAnirudh Venkataramanan status = ice_init_all_ctrlq(hw); 398f31e4b6fSAnirudh Venkataramanan if (status) 399f31e4b6fSAnirudh Venkataramanan goto err_unroll_cqinit; 400f31e4b6fSAnirudh Venkataramanan 401f31e4b6fSAnirudh Venkataramanan status = ice_clear_pf_cfg(hw); 402f31e4b6fSAnirudh Venkataramanan if (status) 403f31e4b6fSAnirudh Venkataramanan goto err_unroll_cqinit; 404f31e4b6fSAnirudh Venkataramanan 405f31e4b6fSAnirudh Venkataramanan ice_clear_pxe_mode(hw); 406f31e4b6fSAnirudh Venkataramanan 407f31e4b6fSAnirudh Venkataramanan status = ice_init_nvm(hw); 408f31e4b6fSAnirudh Venkataramanan if (status) 409f31e4b6fSAnirudh Venkataramanan goto err_unroll_cqinit; 410f31e4b6fSAnirudh Venkataramanan 4119c20346bSAnirudh Venkataramanan status = ice_get_caps(hw); 4129c20346bSAnirudh Venkataramanan if (status) 4139c20346bSAnirudh Venkataramanan goto err_unroll_cqinit; 4149c20346bSAnirudh Venkataramanan 4159c20346bSAnirudh Venkataramanan hw->port_info = devm_kzalloc(ice_hw_to_dev(hw), 4169c20346bSAnirudh Venkataramanan sizeof(*hw->port_info), GFP_KERNEL); 4179c20346bSAnirudh Venkataramanan if (!hw->port_info) { 4189c20346bSAnirudh Venkataramanan status = ICE_ERR_NO_MEMORY; 4199c20346bSAnirudh Venkataramanan goto err_unroll_cqinit; 4209c20346bSAnirudh Venkataramanan } 4219c20346bSAnirudh Venkataramanan 4229c20346bSAnirudh Venkataramanan /* set the back pointer to hw */ 4239c20346bSAnirudh Venkataramanan hw->port_info->hw = hw; 4249c20346bSAnirudh Venkataramanan 4259c20346bSAnirudh Venkataramanan /* Initialize port_info struct with switch configuration data */ 4269c20346bSAnirudh Venkataramanan status = ice_get_initial_sw_cfg(hw); 4279c20346bSAnirudh Venkataramanan if (status) 4289c20346bSAnirudh Venkataramanan goto err_unroll_alloc; 4299c20346bSAnirudh Venkataramanan 4309daf8208SAnirudh Venkataramanan hw->evb_veb = true; 4319daf8208SAnirudh Venkataramanan 4329c20346bSAnirudh Venkataramanan /* Query the allocated resources for tx scheduler */ 4339c20346bSAnirudh Venkataramanan status = ice_sched_query_res_alloc(hw); 4349c20346bSAnirudh Venkataramanan if (status) { 4359c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_SCHED, 4369c20346bSAnirudh Venkataramanan "Failed to get scheduler allocated resources\n"); 4379c20346bSAnirudh Venkataramanan goto err_unroll_alloc; 4389c20346bSAnirudh Venkataramanan } 4399c20346bSAnirudh Venkataramanan 440dc49c772SAnirudh Venkataramanan /* Initialize port_info struct with scheduler data */ 441dc49c772SAnirudh Venkataramanan status = ice_sched_init_port(hw->port_info); 442dc49c772SAnirudh Venkataramanan if (status) 443dc49c772SAnirudh Venkataramanan goto err_unroll_sched; 444dc49c772SAnirudh Venkataramanan 445dc49c772SAnirudh Venkataramanan pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL); 446dc49c772SAnirudh Venkataramanan if (!pcaps) { 447dc49c772SAnirudh Venkataramanan status = ICE_ERR_NO_MEMORY; 448dc49c772SAnirudh Venkataramanan goto err_unroll_sched; 449dc49c772SAnirudh Venkataramanan } 450dc49c772SAnirudh Venkataramanan 451dc49c772SAnirudh Venkataramanan /* Initialize port_info struct with PHY capabilities */ 452dc49c772SAnirudh Venkataramanan status = ice_aq_get_phy_caps(hw->port_info, false, 453dc49c772SAnirudh Venkataramanan ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL); 454dc49c772SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), pcaps); 455dc49c772SAnirudh Venkataramanan if (status) 456dc49c772SAnirudh Venkataramanan goto err_unroll_sched; 457dc49c772SAnirudh Venkataramanan 458dc49c772SAnirudh Venkataramanan /* Initialize port_info struct with link information */ 459dc49c772SAnirudh Venkataramanan status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL); 460dc49c772SAnirudh Venkataramanan if (status) 461dc49c772SAnirudh Venkataramanan goto err_unroll_sched; 462dc49c772SAnirudh Venkataramanan 4639daf8208SAnirudh Venkataramanan status = ice_init_fltr_mgmt_struct(hw); 4649daf8208SAnirudh Venkataramanan if (status) 4659daf8208SAnirudh Venkataramanan goto err_unroll_sched; 4669daf8208SAnirudh Venkataramanan 467dc49c772SAnirudh Venkataramanan /* Get port MAC information */ 468dc49c772SAnirudh Venkataramanan mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp); 469dc49c772SAnirudh Venkataramanan mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL); 470dc49c772SAnirudh Venkataramanan 471dc49c772SAnirudh Venkataramanan if (!mac_buf) 4729daf8208SAnirudh Venkataramanan goto err_unroll_fltr_mgmt_struct; 473dc49c772SAnirudh Venkataramanan 474dc49c772SAnirudh Venkataramanan status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL); 475dc49c772SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), mac_buf); 476dc49c772SAnirudh Venkataramanan 477dc49c772SAnirudh Venkataramanan if (status) 4789daf8208SAnirudh Venkataramanan goto err_unroll_fltr_mgmt_struct; 479dc49c772SAnirudh Venkataramanan 480cdedef59SAnirudh Venkataramanan ice_init_flex_parser(hw); 481cdedef59SAnirudh Venkataramanan 482f31e4b6fSAnirudh Venkataramanan return 0; 483f31e4b6fSAnirudh Venkataramanan 4849daf8208SAnirudh Venkataramanan err_unroll_fltr_mgmt_struct: 4859daf8208SAnirudh Venkataramanan ice_cleanup_fltr_mgmt_struct(hw); 486dc49c772SAnirudh Venkataramanan err_unroll_sched: 487dc49c772SAnirudh Venkataramanan ice_sched_cleanup_all(hw); 4889c20346bSAnirudh Venkataramanan err_unroll_alloc: 4899c20346bSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), hw->port_info); 490f31e4b6fSAnirudh Venkataramanan err_unroll_cqinit: 491f31e4b6fSAnirudh Venkataramanan ice_shutdown_all_ctrlq(hw); 492f31e4b6fSAnirudh Venkataramanan return status; 493f31e4b6fSAnirudh Venkataramanan } 494f31e4b6fSAnirudh Venkataramanan 495f31e4b6fSAnirudh Venkataramanan /** 496f31e4b6fSAnirudh Venkataramanan * ice_deinit_hw - unroll initialization operations done by ice_init_hw 497f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 498f31e4b6fSAnirudh Venkataramanan */ 499f31e4b6fSAnirudh Venkataramanan void ice_deinit_hw(struct ice_hw *hw) 500f31e4b6fSAnirudh Venkataramanan { 5019c20346bSAnirudh Venkataramanan ice_sched_cleanup_all(hw); 502f31e4b6fSAnirudh Venkataramanan ice_shutdown_all_ctrlq(hw); 503dc49c772SAnirudh Venkataramanan 5049c20346bSAnirudh Venkataramanan if (hw->port_info) { 5059c20346bSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), hw->port_info); 5069c20346bSAnirudh Venkataramanan hw->port_info = NULL; 5079c20346bSAnirudh Venkataramanan } 5089daf8208SAnirudh Venkataramanan 5099daf8208SAnirudh Venkataramanan ice_cleanup_fltr_mgmt_struct(hw); 510f31e4b6fSAnirudh Venkataramanan } 511f31e4b6fSAnirudh Venkataramanan 512f31e4b6fSAnirudh Venkataramanan /** 513f31e4b6fSAnirudh Venkataramanan * ice_check_reset - Check to see if a global reset is complete 514f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 515f31e4b6fSAnirudh Venkataramanan */ 516f31e4b6fSAnirudh Venkataramanan enum ice_status ice_check_reset(struct ice_hw *hw) 517f31e4b6fSAnirudh Venkataramanan { 518f31e4b6fSAnirudh Venkataramanan u32 cnt, reg = 0, grst_delay; 519f31e4b6fSAnirudh Venkataramanan 520f31e4b6fSAnirudh Venkataramanan /* Poll for Device Active state in case a recent CORER, GLOBR, 521f31e4b6fSAnirudh Venkataramanan * or EMPR has occurred. The grst delay value is in 100ms units. 522f31e4b6fSAnirudh Venkataramanan * Add 1sec for outstanding AQ commands that can take a long time. 523f31e4b6fSAnirudh Venkataramanan */ 524f31e4b6fSAnirudh Venkataramanan grst_delay = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >> 525f31e4b6fSAnirudh Venkataramanan GLGEN_RSTCTL_GRSTDEL_S) + 10; 526f31e4b6fSAnirudh Venkataramanan 527f31e4b6fSAnirudh Venkataramanan for (cnt = 0; cnt < grst_delay; cnt++) { 528f31e4b6fSAnirudh Venkataramanan mdelay(100); 529f31e4b6fSAnirudh Venkataramanan reg = rd32(hw, GLGEN_RSTAT); 530f31e4b6fSAnirudh Venkataramanan if (!(reg & GLGEN_RSTAT_DEVSTATE_M)) 531f31e4b6fSAnirudh Venkataramanan break; 532f31e4b6fSAnirudh Venkataramanan } 533f31e4b6fSAnirudh Venkataramanan 534f31e4b6fSAnirudh Venkataramanan if (cnt == grst_delay) { 535f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 536f31e4b6fSAnirudh Venkataramanan "Global reset polling failed to complete.\n"); 537f31e4b6fSAnirudh Venkataramanan return ICE_ERR_RESET_FAILED; 538f31e4b6fSAnirudh Venkataramanan } 539f31e4b6fSAnirudh Venkataramanan 540f31e4b6fSAnirudh Venkataramanan #define ICE_RESET_DONE_MASK (GLNVM_ULD_CORER_DONE_M | \ 541f31e4b6fSAnirudh Venkataramanan GLNVM_ULD_GLOBR_DONE_M) 542f31e4b6fSAnirudh Venkataramanan 543f31e4b6fSAnirudh Venkataramanan /* Device is Active; check Global Reset processes are done */ 544f31e4b6fSAnirudh Venkataramanan for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { 545f31e4b6fSAnirudh Venkataramanan reg = rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK; 546f31e4b6fSAnirudh Venkataramanan if (reg == ICE_RESET_DONE_MASK) { 547f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 548f31e4b6fSAnirudh Venkataramanan "Global reset processes done. %d\n", cnt); 549f31e4b6fSAnirudh Venkataramanan break; 550f31e4b6fSAnirudh Venkataramanan } 551f31e4b6fSAnirudh Venkataramanan mdelay(10); 552f31e4b6fSAnirudh Venkataramanan } 553f31e4b6fSAnirudh Venkataramanan 554f31e4b6fSAnirudh Venkataramanan if (cnt == ICE_PF_RESET_WAIT_COUNT) { 555f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 556f31e4b6fSAnirudh Venkataramanan "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n", 557f31e4b6fSAnirudh Venkataramanan reg); 558f31e4b6fSAnirudh Venkataramanan return ICE_ERR_RESET_FAILED; 559f31e4b6fSAnirudh Venkataramanan } 560f31e4b6fSAnirudh Venkataramanan 561f31e4b6fSAnirudh Venkataramanan return 0; 562f31e4b6fSAnirudh Venkataramanan } 563f31e4b6fSAnirudh Venkataramanan 564f31e4b6fSAnirudh Venkataramanan /** 565f31e4b6fSAnirudh Venkataramanan * ice_pf_reset - Reset the PF 566f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 567f31e4b6fSAnirudh Venkataramanan * 568f31e4b6fSAnirudh Venkataramanan * If a global reset has been triggered, this function checks 569f31e4b6fSAnirudh Venkataramanan * for its completion and then issues the PF reset 570f31e4b6fSAnirudh Venkataramanan */ 571f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_pf_reset(struct ice_hw *hw) 572f31e4b6fSAnirudh Venkataramanan { 573f31e4b6fSAnirudh Venkataramanan u32 cnt, reg; 574f31e4b6fSAnirudh Venkataramanan 575f31e4b6fSAnirudh Venkataramanan /* If at function entry a global reset was already in progress, i.e. 576f31e4b6fSAnirudh Venkataramanan * state is not 'device active' or any of the reset done bits are not 577f31e4b6fSAnirudh Venkataramanan * set in GLNVM_ULD, there is no need for a PF Reset; poll until the 578f31e4b6fSAnirudh Venkataramanan * global reset is done. 579f31e4b6fSAnirudh Venkataramanan */ 580f31e4b6fSAnirudh Venkataramanan if ((rd32(hw, GLGEN_RSTAT) & GLGEN_RSTAT_DEVSTATE_M) || 581f31e4b6fSAnirudh Venkataramanan (rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK) ^ ICE_RESET_DONE_MASK) { 582f31e4b6fSAnirudh Venkataramanan /* poll on global reset currently in progress until done */ 583f31e4b6fSAnirudh Venkataramanan if (ice_check_reset(hw)) 584f31e4b6fSAnirudh Venkataramanan return ICE_ERR_RESET_FAILED; 585f31e4b6fSAnirudh Venkataramanan 586f31e4b6fSAnirudh Venkataramanan return 0; 587f31e4b6fSAnirudh Venkataramanan } 588f31e4b6fSAnirudh Venkataramanan 589f31e4b6fSAnirudh Venkataramanan /* Reset the PF */ 590f31e4b6fSAnirudh Venkataramanan reg = rd32(hw, PFGEN_CTRL); 591f31e4b6fSAnirudh Venkataramanan 592f31e4b6fSAnirudh Venkataramanan wr32(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR_M)); 593f31e4b6fSAnirudh Venkataramanan 594f31e4b6fSAnirudh Venkataramanan for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { 595f31e4b6fSAnirudh Venkataramanan reg = rd32(hw, PFGEN_CTRL); 596f31e4b6fSAnirudh Venkataramanan if (!(reg & PFGEN_CTRL_PFSWR_M)) 597f31e4b6fSAnirudh Venkataramanan break; 598f31e4b6fSAnirudh Venkataramanan 599f31e4b6fSAnirudh Venkataramanan mdelay(1); 600f31e4b6fSAnirudh Venkataramanan } 601f31e4b6fSAnirudh Venkataramanan 602f31e4b6fSAnirudh Venkataramanan if (cnt == ICE_PF_RESET_WAIT_COUNT) { 603f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 604f31e4b6fSAnirudh Venkataramanan "PF reset polling failed to complete.\n"); 605f31e4b6fSAnirudh Venkataramanan return ICE_ERR_RESET_FAILED; 606f31e4b6fSAnirudh Venkataramanan } 607f31e4b6fSAnirudh Venkataramanan 608f31e4b6fSAnirudh Venkataramanan return 0; 609f31e4b6fSAnirudh Venkataramanan } 610f31e4b6fSAnirudh Venkataramanan 611f31e4b6fSAnirudh Venkataramanan /** 612f31e4b6fSAnirudh Venkataramanan * ice_reset - Perform different types of reset 613f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hardware structure 614f31e4b6fSAnirudh Venkataramanan * @req: reset request 615f31e4b6fSAnirudh Venkataramanan * 616f31e4b6fSAnirudh Venkataramanan * This function triggers a reset as specified by the req parameter. 617f31e4b6fSAnirudh Venkataramanan * 618f31e4b6fSAnirudh Venkataramanan * Note: 619f31e4b6fSAnirudh Venkataramanan * If anything other than a PF reset is triggered, PXE mode is restored. 620f31e4b6fSAnirudh Venkataramanan * This has to be cleared using ice_clear_pxe_mode again, once the AQ 621f31e4b6fSAnirudh Venkataramanan * interface has been restored in the rebuild flow. 622f31e4b6fSAnirudh Venkataramanan */ 623f31e4b6fSAnirudh Venkataramanan enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req) 624f31e4b6fSAnirudh Venkataramanan { 625f31e4b6fSAnirudh Venkataramanan u32 val = 0; 626f31e4b6fSAnirudh Venkataramanan 627f31e4b6fSAnirudh Venkataramanan switch (req) { 628f31e4b6fSAnirudh Venkataramanan case ICE_RESET_PFR: 629f31e4b6fSAnirudh Venkataramanan return ice_pf_reset(hw); 630f31e4b6fSAnirudh Venkataramanan case ICE_RESET_CORER: 631f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "CoreR requested\n"); 632f31e4b6fSAnirudh Venkataramanan val = GLGEN_RTRIG_CORER_M; 633f31e4b6fSAnirudh Venkataramanan break; 634f31e4b6fSAnirudh Venkataramanan case ICE_RESET_GLOBR: 635f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "GlobalR requested\n"); 636f31e4b6fSAnirudh Venkataramanan val = GLGEN_RTRIG_GLOBR_M; 637f31e4b6fSAnirudh Venkataramanan break; 638f31e4b6fSAnirudh Venkataramanan } 639f31e4b6fSAnirudh Venkataramanan 640f31e4b6fSAnirudh Venkataramanan val |= rd32(hw, GLGEN_RTRIG); 641f31e4b6fSAnirudh Venkataramanan wr32(hw, GLGEN_RTRIG, val); 642f31e4b6fSAnirudh Venkataramanan ice_flush(hw); 643f31e4b6fSAnirudh Venkataramanan 644f31e4b6fSAnirudh Venkataramanan /* wait for the FW to be ready */ 645f31e4b6fSAnirudh Venkataramanan return ice_check_reset(hw); 646f31e4b6fSAnirudh Venkataramanan } 647f31e4b6fSAnirudh Venkataramanan 6487ec59eeaSAnirudh Venkataramanan /** 649cdedef59SAnirudh Venkataramanan * ice_copy_rxq_ctx_to_hw 650cdedef59SAnirudh Venkataramanan * @hw: pointer to the hardware structure 651cdedef59SAnirudh Venkataramanan * @ice_rxq_ctx: pointer to the rxq context 652cdedef59SAnirudh Venkataramanan * @rxq_index: the index of the rx queue 653cdedef59SAnirudh Venkataramanan * 654cdedef59SAnirudh Venkataramanan * Copies rxq context from dense structure to hw register space 655cdedef59SAnirudh Venkataramanan */ 656cdedef59SAnirudh Venkataramanan static enum ice_status 657cdedef59SAnirudh Venkataramanan ice_copy_rxq_ctx_to_hw(struct ice_hw *hw, u8 *ice_rxq_ctx, u32 rxq_index) 658cdedef59SAnirudh Venkataramanan { 659cdedef59SAnirudh Venkataramanan u8 i; 660cdedef59SAnirudh Venkataramanan 661cdedef59SAnirudh Venkataramanan if (!ice_rxq_ctx) 662cdedef59SAnirudh Venkataramanan return ICE_ERR_BAD_PTR; 663cdedef59SAnirudh Venkataramanan 664cdedef59SAnirudh Venkataramanan if (rxq_index > QRX_CTRL_MAX_INDEX) 665cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 666cdedef59SAnirudh Venkataramanan 667cdedef59SAnirudh Venkataramanan /* Copy each dword separately to hw */ 668cdedef59SAnirudh Venkataramanan for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++) { 669cdedef59SAnirudh Venkataramanan wr32(hw, QRX_CONTEXT(i, rxq_index), 670cdedef59SAnirudh Venkataramanan *((u32 *)(ice_rxq_ctx + (i * sizeof(u32))))); 671cdedef59SAnirudh Venkataramanan 672cdedef59SAnirudh Venkataramanan ice_debug(hw, ICE_DBG_QCTX, "qrxdata[%d]: %08X\n", i, 673cdedef59SAnirudh Venkataramanan *((u32 *)(ice_rxq_ctx + (i * sizeof(u32))))); 674cdedef59SAnirudh Venkataramanan } 675cdedef59SAnirudh Venkataramanan 676cdedef59SAnirudh Venkataramanan return 0; 677cdedef59SAnirudh Venkataramanan } 678cdedef59SAnirudh Venkataramanan 679cdedef59SAnirudh Venkataramanan /* LAN Rx Queue Context */ 680cdedef59SAnirudh Venkataramanan static const struct ice_ctx_ele ice_rlan_ctx_info[] = { 681cdedef59SAnirudh Venkataramanan /* Field Width LSB */ 682cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, head, 13, 0), 683cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, cpuid, 8, 13), 684cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, base, 57, 32), 685cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, qlen, 13, 89), 686cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, dbuf, 7, 102), 687cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, hbuf, 5, 109), 688cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, dtype, 2, 114), 689cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, dsize, 1, 116), 690cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, crcstrip, 1, 117), 691cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, l2tsel, 1, 119), 692cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, hsplit_0, 4, 120), 693cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, hsplit_1, 2, 124), 694cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, showiv, 1, 127), 695cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, rxmax, 14, 174), 696cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, tphrdesc_ena, 1, 193), 697cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, tphwdesc_ena, 1, 194), 698cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, tphdata_ena, 1, 195), 699cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, tphhead_ena, 1, 196), 700cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_rlan_ctx, lrxqthresh, 3, 198), 701cdedef59SAnirudh Venkataramanan { 0 } 702cdedef59SAnirudh Venkataramanan }; 703cdedef59SAnirudh Venkataramanan 704cdedef59SAnirudh Venkataramanan /** 705cdedef59SAnirudh Venkataramanan * ice_write_rxq_ctx 706cdedef59SAnirudh Venkataramanan * @hw: pointer to the hardware structure 707cdedef59SAnirudh Venkataramanan * @rlan_ctx: pointer to the rxq context 708cdedef59SAnirudh Venkataramanan * @rxq_index: the index of the rx queue 709cdedef59SAnirudh Venkataramanan * 710cdedef59SAnirudh Venkataramanan * Converts rxq context from sparse to dense structure and then writes 711cdedef59SAnirudh Venkataramanan * it to hw register space 712cdedef59SAnirudh Venkataramanan */ 713cdedef59SAnirudh Venkataramanan enum ice_status 714cdedef59SAnirudh Venkataramanan ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, 715cdedef59SAnirudh Venkataramanan u32 rxq_index) 716cdedef59SAnirudh Venkataramanan { 717cdedef59SAnirudh Venkataramanan u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 }; 718cdedef59SAnirudh Venkataramanan 719cdedef59SAnirudh Venkataramanan ice_set_ctx((u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info); 720cdedef59SAnirudh Venkataramanan return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index); 721cdedef59SAnirudh Venkataramanan } 722cdedef59SAnirudh Venkataramanan 723cdedef59SAnirudh Venkataramanan /* LAN Tx Queue Context */ 724cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele ice_tlan_ctx_info[] = { 725cdedef59SAnirudh Venkataramanan /* Field Width LSB */ 726cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, base, 57, 0), 727cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, port_num, 3, 57), 728cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, cgd_num, 5, 60), 729cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, pf_num, 3, 65), 730cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, vmvf_num, 10, 68), 731cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, vmvf_type, 2, 78), 732cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, src_vsi, 10, 80), 733cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tsyn_ena, 1, 90), 734cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, alt_vlan, 1, 92), 735cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, cpuid, 8, 93), 736cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, wb_mode, 1, 101), 737cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tphrd_desc, 1, 102), 738cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tphrd, 1, 103), 739cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tphwr_desc, 1, 104), 740cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, cmpq_id, 9, 105), 741cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, qnum_in_func, 14, 114), 742cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, itr_notification_mode, 1, 128), 743cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, adjust_prof_id, 6, 129), 744cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, qlen, 13, 135), 745cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, quanta_prof_idx, 4, 148), 746cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tso_ena, 1, 152), 747cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, tso_qnum, 11, 153), 748cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, legacy_int, 1, 164), 749cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, drop_ena, 1, 165), 750cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, cache_prof_idx, 2, 166), 751cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, pkt_shaper_prof_idx, 3, 168), 752cdedef59SAnirudh Venkataramanan ICE_CTX_STORE(ice_tlan_ctx, int_q_state, 110, 171), 753cdedef59SAnirudh Venkataramanan { 0 } 754cdedef59SAnirudh Venkataramanan }; 755cdedef59SAnirudh Venkataramanan 756cdedef59SAnirudh Venkataramanan /** 7577ec59eeaSAnirudh Venkataramanan * ice_debug_cq 7587ec59eeaSAnirudh Venkataramanan * @hw: pointer to the hardware structure 7597ec59eeaSAnirudh Venkataramanan * @mask: debug mask 7607ec59eeaSAnirudh Venkataramanan * @desc: pointer to control queue descriptor 7617ec59eeaSAnirudh Venkataramanan * @buf: pointer to command buffer 7627ec59eeaSAnirudh Venkataramanan * @buf_len: max length of buf 7637ec59eeaSAnirudh Venkataramanan * 7647ec59eeaSAnirudh Venkataramanan * Dumps debug log about control command with descriptor contents. 7657ec59eeaSAnirudh Venkataramanan */ 7667ec59eeaSAnirudh Venkataramanan void ice_debug_cq(struct ice_hw *hw, u32 __maybe_unused mask, void *desc, 7677ec59eeaSAnirudh Venkataramanan void *buf, u16 buf_len) 7687ec59eeaSAnirudh Venkataramanan { 7697ec59eeaSAnirudh Venkataramanan struct ice_aq_desc *cq_desc = (struct ice_aq_desc *)desc; 7707ec59eeaSAnirudh Venkataramanan u16 len; 7717ec59eeaSAnirudh Venkataramanan 7727ec59eeaSAnirudh Venkataramanan #ifndef CONFIG_DYNAMIC_DEBUG 7737ec59eeaSAnirudh Venkataramanan if (!(mask & hw->debug_mask)) 7747ec59eeaSAnirudh Venkataramanan return; 7757ec59eeaSAnirudh Venkataramanan #endif 7767ec59eeaSAnirudh Venkataramanan 7777ec59eeaSAnirudh Venkataramanan if (!desc) 7787ec59eeaSAnirudh Venkataramanan return; 7797ec59eeaSAnirudh Venkataramanan 7807ec59eeaSAnirudh Venkataramanan len = le16_to_cpu(cq_desc->datalen); 7817ec59eeaSAnirudh Venkataramanan 7827ec59eeaSAnirudh Venkataramanan ice_debug(hw, mask, 7837ec59eeaSAnirudh Venkataramanan "CQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n", 7847ec59eeaSAnirudh Venkataramanan le16_to_cpu(cq_desc->opcode), 7857ec59eeaSAnirudh Venkataramanan le16_to_cpu(cq_desc->flags), 7867ec59eeaSAnirudh Venkataramanan le16_to_cpu(cq_desc->datalen), le16_to_cpu(cq_desc->retval)); 7877ec59eeaSAnirudh Venkataramanan ice_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n", 7887ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->cookie_high), 7897ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->cookie_low)); 7907ec59eeaSAnirudh Venkataramanan ice_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n", 7917ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->params.generic.param0), 7927ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->params.generic.param1)); 7937ec59eeaSAnirudh Venkataramanan ice_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n", 7947ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->params.generic.addr_high), 7957ec59eeaSAnirudh Venkataramanan le32_to_cpu(cq_desc->params.generic.addr_low)); 7967ec59eeaSAnirudh Venkataramanan if (buf && cq_desc->datalen != 0) { 7977ec59eeaSAnirudh Venkataramanan ice_debug(hw, mask, "Buffer:\n"); 7987ec59eeaSAnirudh Venkataramanan if (buf_len < len) 7997ec59eeaSAnirudh Venkataramanan len = buf_len; 8007ec59eeaSAnirudh Venkataramanan 8017ec59eeaSAnirudh Venkataramanan ice_debug_array(hw, mask, 16, 1, (u8 *)buf, len); 8027ec59eeaSAnirudh Venkataramanan } 8037ec59eeaSAnirudh Venkataramanan } 8047ec59eeaSAnirudh Venkataramanan 8057ec59eeaSAnirudh Venkataramanan /* FW Admin Queue command wrappers */ 8067ec59eeaSAnirudh Venkataramanan 8077ec59eeaSAnirudh Venkataramanan /** 8087ec59eeaSAnirudh Venkataramanan * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue 8097ec59eeaSAnirudh Venkataramanan * @hw: pointer to the hw struct 8107ec59eeaSAnirudh Venkataramanan * @desc: descriptor describing the command 8117ec59eeaSAnirudh Venkataramanan * @buf: buffer to use for indirect commands (NULL for direct commands) 8127ec59eeaSAnirudh Venkataramanan * @buf_size: size of buffer for indirect commands (0 for direct commands) 8137ec59eeaSAnirudh Venkataramanan * @cd: pointer to command details structure 8147ec59eeaSAnirudh Venkataramanan * 8157ec59eeaSAnirudh Venkataramanan * Helper function to send FW Admin Queue commands to the FW Admin Queue. 8167ec59eeaSAnirudh Venkataramanan */ 8177ec59eeaSAnirudh Venkataramanan enum ice_status 8187ec59eeaSAnirudh Venkataramanan ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf, 8197ec59eeaSAnirudh Venkataramanan u16 buf_size, struct ice_sq_cd *cd) 8207ec59eeaSAnirudh Venkataramanan { 8217ec59eeaSAnirudh Venkataramanan return ice_sq_send_cmd(hw, &hw->adminq, desc, buf, buf_size, cd); 8227ec59eeaSAnirudh Venkataramanan } 8237ec59eeaSAnirudh Venkataramanan 8247ec59eeaSAnirudh Venkataramanan /** 8257ec59eeaSAnirudh Venkataramanan * ice_aq_get_fw_ver 8267ec59eeaSAnirudh Venkataramanan * @hw: pointer to the hw struct 8277ec59eeaSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 8287ec59eeaSAnirudh Venkataramanan * 8297ec59eeaSAnirudh Venkataramanan * Get the firmware version (0x0001) from the admin queue commands 8307ec59eeaSAnirudh Venkataramanan */ 8317ec59eeaSAnirudh Venkataramanan enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd) 8327ec59eeaSAnirudh Venkataramanan { 8337ec59eeaSAnirudh Venkataramanan struct ice_aqc_get_ver *resp; 8347ec59eeaSAnirudh Venkataramanan struct ice_aq_desc desc; 8357ec59eeaSAnirudh Venkataramanan enum ice_status status; 8367ec59eeaSAnirudh Venkataramanan 8377ec59eeaSAnirudh Venkataramanan resp = &desc.params.get_ver; 8387ec59eeaSAnirudh Venkataramanan 8397ec59eeaSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_ver); 8407ec59eeaSAnirudh Venkataramanan 8417ec59eeaSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 8427ec59eeaSAnirudh Venkataramanan 8437ec59eeaSAnirudh Venkataramanan if (!status) { 8447ec59eeaSAnirudh Venkataramanan hw->fw_branch = resp->fw_branch; 8457ec59eeaSAnirudh Venkataramanan hw->fw_maj_ver = resp->fw_major; 8467ec59eeaSAnirudh Venkataramanan hw->fw_min_ver = resp->fw_minor; 8477ec59eeaSAnirudh Venkataramanan hw->fw_patch = resp->fw_patch; 8487ec59eeaSAnirudh Venkataramanan hw->fw_build = le32_to_cpu(resp->fw_build); 8497ec59eeaSAnirudh Venkataramanan hw->api_branch = resp->api_branch; 8507ec59eeaSAnirudh Venkataramanan hw->api_maj_ver = resp->api_major; 8517ec59eeaSAnirudh Venkataramanan hw->api_min_ver = resp->api_minor; 8527ec59eeaSAnirudh Venkataramanan hw->api_patch = resp->api_patch; 8537ec59eeaSAnirudh Venkataramanan } 8547ec59eeaSAnirudh Venkataramanan 8557ec59eeaSAnirudh Venkataramanan return status; 8567ec59eeaSAnirudh Venkataramanan } 8577ec59eeaSAnirudh Venkataramanan 8587ec59eeaSAnirudh Venkataramanan /** 8597ec59eeaSAnirudh Venkataramanan * ice_aq_q_shutdown 8607ec59eeaSAnirudh Venkataramanan * @hw: pointer to the hw struct 8617ec59eeaSAnirudh Venkataramanan * @unloading: is the driver unloading itself 8627ec59eeaSAnirudh Venkataramanan * 8637ec59eeaSAnirudh Venkataramanan * Tell the Firmware that we're shutting down the AdminQ and whether 8647ec59eeaSAnirudh Venkataramanan * or not the driver is unloading as well (0x0003). 8657ec59eeaSAnirudh Venkataramanan */ 8667ec59eeaSAnirudh Venkataramanan enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading) 8677ec59eeaSAnirudh Venkataramanan { 8687ec59eeaSAnirudh Venkataramanan struct ice_aqc_q_shutdown *cmd; 8697ec59eeaSAnirudh Venkataramanan struct ice_aq_desc desc; 8707ec59eeaSAnirudh Venkataramanan 8717ec59eeaSAnirudh Venkataramanan cmd = &desc.params.q_shutdown; 8727ec59eeaSAnirudh Venkataramanan 8737ec59eeaSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_q_shutdown); 8747ec59eeaSAnirudh Venkataramanan 8757ec59eeaSAnirudh Venkataramanan if (unloading) 8767ec59eeaSAnirudh Venkataramanan cmd->driver_unloading = cpu_to_le32(ICE_AQC_DRIVER_UNLOADING); 8777ec59eeaSAnirudh Venkataramanan 8787ec59eeaSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 8797ec59eeaSAnirudh Venkataramanan } 880f31e4b6fSAnirudh Venkataramanan 881f31e4b6fSAnirudh Venkataramanan /** 882f31e4b6fSAnirudh Venkataramanan * ice_aq_req_res 883f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hw struct 884f31e4b6fSAnirudh Venkataramanan * @res: resource id 885f31e4b6fSAnirudh Venkataramanan * @access: access type 886f31e4b6fSAnirudh Venkataramanan * @sdp_number: resource number 887f31e4b6fSAnirudh Venkataramanan * @timeout: the maximum time in ms that the driver may hold the resource 888f31e4b6fSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 889f31e4b6fSAnirudh Venkataramanan * 890f31e4b6fSAnirudh Venkataramanan * requests common resource using the admin queue commands (0x0008) 891f31e4b6fSAnirudh Venkataramanan */ 892f31e4b6fSAnirudh Venkataramanan static enum ice_status 893f31e4b6fSAnirudh Venkataramanan ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res, 894f31e4b6fSAnirudh Venkataramanan enum ice_aq_res_access_type access, u8 sdp_number, u32 *timeout, 895f31e4b6fSAnirudh Venkataramanan struct ice_sq_cd *cd) 896f31e4b6fSAnirudh Venkataramanan { 897f31e4b6fSAnirudh Venkataramanan struct ice_aqc_req_res *cmd_resp; 898f31e4b6fSAnirudh Venkataramanan struct ice_aq_desc desc; 899f31e4b6fSAnirudh Venkataramanan enum ice_status status; 900f31e4b6fSAnirudh Venkataramanan 901f31e4b6fSAnirudh Venkataramanan cmd_resp = &desc.params.res_owner; 902f31e4b6fSAnirudh Venkataramanan 903f31e4b6fSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_req_res); 904f31e4b6fSAnirudh Venkataramanan 905f31e4b6fSAnirudh Venkataramanan cmd_resp->res_id = cpu_to_le16(res); 906f31e4b6fSAnirudh Venkataramanan cmd_resp->access_type = cpu_to_le16(access); 907f31e4b6fSAnirudh Venkataramanan cmd_resp->res_number = cpu_to_le32(sdp_number); 908f31e4b6fSAnirudh Venkataramanan 909f31e4b6fSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 910f31e4b6fSAnirudh Venkataramanan /* The completion specifies the maximum time in ms that the driver 911f31e4b6fSAnirudh Venkataramanan * may hold the resource in the Timeout field. 912f31e4b6fSAnirudh Venkataramanan * If the resource is held by someone else, the command completes with 913f31e4b6fSAnirudh Venkataramanan * busy return value and the timeout field indicates the maximum time 914f31e4b6fSAnirudh Venkataramanan * the current owner of the resource has to free it. 915f31e4b6fSAnirudh Venkataramanan */ 916f31e4b6fSAnirudh Venkataramanan if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY) 917f31e4b6fSAnirudh Venkataramanan *timeout = le32_to_cpu(cmd_resp->timeout); 918f31e4b6fSAnirudh Venkataramanan 919f31e4b6fSAnirudh Venkataramanan return status; 920f31e4b6fSAnirudh Venkataramanan } 921f31e4b6fSAnirudh Venkataramanan 922f31e4b6fSAnirudh Venkataramanan /** 923f31e4b6fSAnirudh Venkataramanan * ice_aq_release_res 924f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hw struct 925f31e4b6fSAnirudh Venkataramanan * @res: resource id 926f31e4b6fSAnirudh Venkataramanan * @sdp_number: resource number 927f31e4b6fSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 928f31e4b6fSAnirudh Venkataramanan * 929f31e4b6fSAnirudh Venkataramanan * release common resource using the admin queue commands (0x0009) 930f31e4b6fSAnirudh Venkataramanan */ 931f31e4b6fSAnirudh Venkataramanan static enum ice_status 932f31e4b6fSAnirudh Venkataramanan ice_aq_release_res(struct ice_hw *hw, enum ice_aq_res_ids res, u8 sdp_number, 933f31e4b6fSAnirudh Venkataramanan struct ice_sq_cd *cd) 934f31e4b6fSAnirudh Venkataramanan { 935f31e4b6fSAnirudh Venkataramanan struct ice_aqc_req_res *cmd; 936f31e4b6fSAnirudh Venkataramanan struct ice_aq_desc desc; 937f31e4b6fSAnirudh Venkataramanan 938f31e4b6fSAnirudh Venkataramanan cmd = &desc.params.res_owner; 939f31e4b6fSAnirudh Venkataramanan 940f31e4b6fSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_release_res); 941f31e4b6fSAnirudh Venkataramanan 942f31e4b6fSAnirudh Venkataramanan cmd->res_id = cpu_to_le16(res); 943f31e4b6fSAnirudh Venkataramanan cmd->res_number = cpu_to_le32(sdp_number); 944f31e4b6fSAnirudh Venkataramanan 945f31e4b6fSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 946f31e4b6fSAnirudh Venkataramanan } 947f31e4b6fSAnirudh Venkataramanan 948f31e4b6fSAnirudh Venkataramanan /** 949f31e4b6fSAnirudh Venkataramanan * ice_acquire_res 950f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 951f31e4b6fSAnirudh Venkataramanan * @res: resource id 952f31e4b6fSAnirudh Venkataramanan * @access: access type (read or write) 953f31e4b6fSAnirudh Venkataramanan * 954f31e4b6fSAnirudh Venkataramanan * This function will attempt to acquire the ownership of a resource. 955f31e4b6fSAnirudh Venkataramanan */ 956f31e4b6fSAnirudh Venkataramanan enum ice_status 957f31e4b6fSAnirudh Venkataramanan ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, 958f31e4b6fSAnirudh Venkataramanan enum ice_aq_res_access_type access) 959f31e4b6fSAnirudh Venkataramanan { 960f31e4b6fSAnirudh Venkataramanan #define ICE_RES_POLLING_DELAY_MS 10 961f31e4b6fSAnirudh Venkataramanan u32 delay = ICE_RES_POLLING_DELAY_MS; 962f31e4b6fSAnirudh Venkataramanan enum ice_status status; 963f31e4b6fSAnirudh Venkataramanan u32 time_left = 0; 964f31e4b6fSAnirudh Venkataramanan u32 timeout; 965f31e4b6fSAnirudh Venkataramanan 966f31e4b6fSAnirudh Venkataramanan status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); 967f31e4b6fSAnirudh Venkataramanan 968f31e4b6fSAnirudh Venkataramanan /* An admin queue return code of ICE_AQ_RC_EEXIST means that another 969f31e4b6fSAnirudh Venkataramanan * driver has previously acquired the resource and performed any 970f31e4b6fSAnirudh Venkataramanan * necessary updates; in this case the caller does not obtain the 971f31e4b6fSAnirudh Venkataramanan * resource and has no further work to do. 972f31e4b6fSAnirudh Venkataramanan */ 973f31e4b6fSAnirudh Venkataramanan if (hw->adminq.sq_last_status == ICE_AQ_RC_EEXIST) { 974f31e4b6fSAnirudh Venkataramanan status = ICE_ERR_AQ_NO_WORK; 975f31e4b6fSAnirudh Venkataramanan goto ice_acquire_res_exit; 976f31e4b6fSAnirudh Venkataramanan } 977f31e4b6fSAnirudh Venkataramanan 978f31e4b6fSAnirudh Venkataramanan if (status) 979f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_RES, 980f31e4b6fSAnirudh Venkataramanan "resource %d acquire type %d failed.\n", res, access); 981f31e4b6fSAnirudh Venkataramanan 982f31e4b6fSAnirudh Venkataramanan /* If necessary, poll until the current lock owner timeouts */ 983f31e4b6fSAnirudh Venkataramanan timeout = time_left; 984f31e4b6fSAnirudh Venkataramanan while (status && timeout && time_left) { 985f31e4b6fSAnirudh Venkataramanan mdelay(delay); 986f31e4b6fSAnirudh Venkataramanan timeout = (timeout > delay) ? timeout - delay : 0; 987f31e4b6fSAnirudh Venkataramanan status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); 988f31e4b6fSAnirudh Venkataramanan 989f31e4b6fSAnirudh Venkataramanan if (hw->adminq.sq_last_status == ICE_AQ_RC_EEXIST) { 990f31e4b6fSAnirudh Venkataramanan /* lock free, but no work to do */ 991f31e4b6fSAnirudh Venkataramanan status = ICE_ERR_AQ_NO_WORK; 992f31e4b6fSAnirudh Venkataramanan break; 993f31e4b6fSAnirudh Venkataramanan } 994f31e4b6fSAnirudh Venkataramanan 995f31e4b6fSAnirudh Venkataramanan if (!status) 996f31e4b6fSAnirudh Venkataramanan /* lock acquired */ 997f31e4b6fSAnirudh Venkataramanan break; 998f31e4b6fSAnirudh Venkataramanan } 999f31e4b6fSAnirudh Venkataramanan if (status && status != ICE_ERR_AQ_NO_WORK) 1000f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_RES, "resource acquire timed out.\n"); 1001f31e4b6fSAnirudh Venkataramanan 1002f31e4b6fSAnirudh Venkataramanan ice_acquire_res_exit: 1003f31e4b6fSAnirudh Venkataramanan if (status == ICE_ERR_AQ_NO_WORK) { 1004f31e4b6fSAnirudh Venkataramanan if (access == ICE_RES_WRITE) 1005f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_RES, 1006f31e4b6fSAnirudh Venkataramanan "resource indicates no work to do.\n"); 1007f31e4b6fSAnirudh Venkataramanan else 1008f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_RES, 1009f31e4b6fSAnirudh Venkataramanan "Warning: ICE_ERR_AQ_NO_WORK not expected\n"); 1010f31e4b6fSAnirudh Venkataramanan } 1011f31e4b6fSAnirudh Venkataramanan return status; 1012f31e4b6fSAnirudh Venkataramanan } 1013f31e4b6fSAnirudh Venkataramanan 1014f31e4b6fSAnirudh Venkataramanan /** 1015f31e4b6fSAnirudh Venkataramanan * ice_release_res 1016f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 1017f31e4b6fSAnirudh Venkataramanan * @res: resource id 1018f31e4b6fSAnirudh Venkataramanan * 1019f31e4b6fSAnirudh Venkataramanan * This function will release a resource using the proper Admin Command. 1020f31e4b6fSAnirudh Venkataramanan */ 1021f31e4b6fSAnirudh Venkataramanan void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res) 1022f31e4b6fSAnirudh Venkataramanan { 1023f31e4b6fSAnirudh Venkataramanan enum ice_status status; 1024f31e4b6fSAnirudh Venkataramanan u32 total_delay = 0; 1025f31e4b6fSAnirudh Venkataramanan 1026f31e4b6fSAnirudh Venkataramanan status = ice_aq_release_res(hw, res, 0, NULL); 1027f31e4b6fSAnirudh Venkataramanan 1028f31e4b6fSAnirudh Venkataramanan /* there are some rare cases when trying to release the resource 1029f31e4b6fSAnirudh Venkataramanan * results in an admin Q timeout, so handle them correctly 1030f31e4b6fSAnirudh Venkataramanan */ 1031f31e4b6fSAnirudh Venkataramanan while ((status == ICE_ERR_AQ_TIMEOUT) && 1032f31e4b6fSAnirudh Venkataramanan (total_delay < hw->adminq.sq_cmd_timeout)) { 1033f31e4b6fSAnirudh Venkataramanan mdelay(1); 1034f31e4b6fSAnirudh Venkataramanan status = ice_aq_release_res(hw, res, 0, NULL); 1035f31e4b6fSAnirudh Venkataramanan total_delay++; 1036f31e4b6fSAnirudh Venkataramanan } 1037f31e4b6fSAnirudh Venkataramanan } 1038f31e4b6fSAnirudh Venkataramanan 1039f31e4b6fSAnirudh Venkataramanan /** 10409c20346bSAnirudh Venkataramanan * ice_parse_caps - parse function/device capabilities 10419c20346bSAnirudh Venkataramanan * @hw: pointer to the hw struct 10429c20346bSAnirudh Venkataramanan * @buf: pointer to a buffer containing function/device capability records 10439c20346bSAnirudh Venkataramanan * @cap_count: number of capability records in the list 10449c20346bSAnirudh Venkataramanan * @opc: type of capabilities list to parse 10459c20346bSAnirudh Venkataramanan * 10469c20346bSAnirudh Venkataramanan * Helper function to parse function(0x000a)/device(0x000b) capabilities list. 10479c20346bSAnirudh Venkataramanan */ 10489c20346bSAnirudh Venkataramanan static void 10499c20346bSAnirudh Venkataramanan ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count, 10509c20346bSAnirudh Venkataramanan enum ice_adminq_opc opc) 10519c20346bSAnirudh Venkataramanan { 10529c20346bSAnirudh Venkataramanan struct ice_aqc_list_caps_elem *cap_resp; 10539c20346bSAnirudh Venkataramanan struct ice_hw_func_caps *func_p = NULL; 10549c20346bSAnirudh Venkataramanan struct ice_hw_dev_caps *dev_p = NULL; 10559c20346bSAnirudh Venkataramanan struct ice_hw_common_caps *caps; 10569c20346bSAnirudh Venkataramanan u32 i; 10579c20346bSAnirudh Venkataramanan 10589c20346bSAnirudh Venkataramanan if (!buf) 10599c20346bSAnirudh Venkataramanan return; 10609c20346bSAnirudh Venkataramanan 10619c20346bSAnirudh Venkataramanan cap_resp = (struct ice_aqc_list_caps_elem *)buf; 10629c20346bSAnirudh Venkataramanan 10639c20346bSAnirudh Venkataramanan if (opc == ice_aqc_opc_list_dev_caps) { 10649c20346bSAnirudh Venkataramanan dev_p = &hw->dev_caps; 10659c20346bSAnirudh Venkataramanan caps = &dev_p->common_cap; 10669c20346bSAnirudh Venkataramanan } else if (opc == ice_aqc_opc_list_func_caps) { 10679c20346bSAnirudh Venkataramanan func_p = &hw->func_caps; 10689c20346bSAnirudh Venkataramanan caps = &func_p->common_cap; 10699c20346bSAnirudh Venkataramanan } else { 10709c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "wrong opcode\n"); 10719c20346bSAnirudh Venkataramanan return; 10729c20346bSAnirudh Venkataramanan } 10739c20346bSAnirudh Venkataramanan 10749c20346bSAnirudh Venkataramanan for (i = 0; caps && i < cap_count; i++, cap_resp++) { 10759c20346bSAnirudh Venkataramanan u32 logical_id = le32_to_cpu(cap_resp->logical_id); 10769c20346bSAnirudh Venkataramanan u32 phys_id = le32_to_cpu(cap_resp->phys_id); 10779c20346bSAnirudh Venkataramanan u32 number = le32_to_cpu(cap_resp->number); 10789c20346bSAnirudh Venkataramanan u16 cap = le16_to_cpu(cap_resp->cap); 10799c20346bSAnirudh Venkataramanan 10809c20346bSAnirudh Venkataramanan switch (cap) { 10819c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_VSI: 10829c20346bSAnirudh Venkataramanan if (dev_p) { 10839c20346bSAnirudh Venkataramanan dev_p->num_vsi_allocd_to_host = number; 10849c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 10859c20346bSAnirudh Venkataramanan "HW caps: Dev.VSI cnt = %d\n", 10869c20346bSAnirudh Venkataramanan dev_p->num_vsi_allocd_to_host); 10879c20346bSAnirudh Venkataramanan } else if (func_p) { 10889c20346bSAnirudh Venkataramanan func_p->guaranteed_num_vsi = number; 10899c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 10909c20346bSAnirudh Venkataramanan "HW caps: Func.VSI cnt = %d\n", 10919c20346bSAnirudh Venkataramanan func_p->guaranteed_num_vsi); 10929c20346bSAnirudh Venkataramanan } 10939c20346bSAnirudh Venkataramanan break; 10949c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_RSS: 10959c20346bSAnirudh Venkataramanan caps->rss_table_size = number; 10969c20346bSAnirudh Venkataramanan caps->rss_table_entry_width = logical_id; 10979c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 10989c20346bSAnirudh Venkataramanan "HW caps: RSS table size = %d\n", 10999c20346bSAnirudh Venkataramanan caps->rss_table_size); 11009c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11019c20346bSAnirudh Venkataramanan "HW caps: RSS table width = %d\n", 11029c20346bSAnirudh Venkataramanan caps->rss_table_entry_width); 11039c20346bSAnirudh Venkataramanan break; 11049c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_RXQS: 11059c20346bSAnirudh Venkataramanan caps->num_rxq = number; 11069c20346bSAnirudh Venkataramanan caps->rxq_first_id = phys_id; 11079c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11089c20346bSAnirudh Venkataramanan "HW caps: Num Rx Qs = %d\n", caps->num_rxq); 11099c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11109c20346bSAnirudh Venkataramanan "HW caps: Rx first queue ID = %d\n", 11119c20346bSAnirudh Venkataramanan caps->rxq_first_id); 11129c20346bSAnirudh Venkataramanan break; 11139c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_TXQS: 11149c20346bSAnirudh Venkataramanan caps->num_txq = number; 11159c20346bSAnirudh Venkataramanan caps->txq_first_id = phys_id; 11169c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11179c20346bSAnirudh Venkataramanan "HW caps: Num Tx Qs = %d\n", caps->num_txq); 11189c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11199c20346bSAnirudh Venkataramanan "HW caps: Tx first queue ID = %d\n", 11209c20346bSAnirudh Venkataramanan caps->txq_first_id); 11219c20346bSAnirudh Venkataramanan break; 11229c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_MSIX: 11239c20346bSAnirudh Venkataramanan caps->num_msix_vectors = number; 11249c20346bSAnirudh Venkataramanan caps->msix_vector_first_id = phys_id; 11259c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11269c20346bSAnirudh Venkataramanan "HW caps: MSIX vector count = %d\n", 11279c20346bSAnirudh Venkataramanan caps->num_msix_vectors); 11289c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11299c20346bSAnirudh Venkataramanan "HW caps: MSIX first vector index = %d\n", 11309c20346bSAnirudh Venkataramanan caps->msix_vector_first_id); 11319c20346bSAnirudh Venkataramanan break; 11329c20346bSAnirudh Venkataramanan case ICE_AQC_CAPS_MAX_MTU: 11339c20346bSAnirudh Venkataramanan caps->max_mtu = number; 11349c20346bSAnirudh Venkataramanan if (dev_p) 11359c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11369c20346bSAnirudh Venkataramanan "HW caps: Dev.MaxMTU = %d\n", 11379c20346bSAnirudh Venkataramanan caps->max_mtu); 11389c20346bSAnirudh Venkataramanan else if (func_p) 11399c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11409c20346bSAnirudh Venkataramanan "HW caps: func.MaxMTU = %d\n", 11419c20346bSAnirudh Venkataramanan caps->max_mtu); 11429c20346bSAnirudh Venkataramanan break; 11439c20346bSAnirudh Venkataramanan default: 11449c20346bSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 11459c20346bSAnirudh Venkataramanan "HW caps: Unknown capability[%d]: 0x%x\n", i, 11469c20346bSAnirudh Venkataramanan cap); 11479c20346bSAnirudh Venkataramanan break; 11489c20346bSAnirudh Venkataramanan } 11499c20346bSAnirudh Venkataramanan } 11509c20346bSAnirudh Venkataramanan } 11519c20346bSAnirudh Venkataramanan 11529c20346bSAnirudh Venkataramanan /** 11539c20346bSAnirudh Venkataramanan * ice_aq_discover_caps - query function/device capabilities 11549c20346bSAnirudh Venkataramanan * @hw: pointer to the hw struct 11559c20346bSAnirudh Venkataramanan * @buf: a virtual buffer to hold the capabilities 11569c20346bSAnirudh Venkataramanan * @buf_size: Size of the virtual buffer 11579c20346bSAnirudh Venkataramanan * @data_size: Size of the returned data, or buf size needed if AQ err==ENOMEM 11589c20346bSAnirudh Venkataramanan * @opc: capabilities type to discover - pass in the command opcode 11599c20346bSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 11609c20346bSAnirudh Venkataramanan * 11619c20346bSAnirudh Venkataramanan * Get the function(0x000a)/device(0x000b) capabilities description from 11629c20346bSAnirudh Venkataramanan * the firmware. 11639c20346bSAnirudh Venkataramanan */ 11649c20346bSAnirudh Venkataramanan static enum ice_status 11659c20346bSAnirudh Venkataramanan ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u16 *data_size, 11669c20346bSAnirudh Venkataramanan enum ice_adminq_opc opc, struct ice_sq_cd *cd) 11679c20346bSAnirudh Venkataramanan { 11689c20346bSAnirudh Venkataramanan struct ice_aqc_list_caps *cmd; 11699c20346bSAnirudh Venkataramanan struct ice_aq_desc desc; 11709c20346bSAnirudh Venkataramanan enum ice_status status; 11719c20346bSAnirudh Venkataramanan 11729c20346bSAnirudh Venkataramanan cmd = &desc.params.get_cap; 11739c20346bSAnirudh Venkataramanan 11749c20346bSAnirudh Venkataramanan if (opc != ice_aqc_opc_list_func_caps && 11759c20346bSAnirudh Venkataramanan opc != ice_aqc_opc_list_dev_caps) 11769c20346bSAnirudh Venkataramanan return ICE_ERR_PARAM; 11779c20346bSAnirudh Venkataramanan 11789c20346bSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, opc); 11799c20346bSAnirudh Venkataramanan 11809c20346bSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 11819c20346bSAnirudh Venkataramanan if (!status) 11829c20346bSAnirudh Venkataramanan ice_parse_caps(hw, buf, le32_to_cpu(cmd->count), opc); 11839c20346bSAnirudh Venkataramanan *data_size = le16_to_cpu(desc.datalen); 11849c20346bSAnirudh Venkataramanan 11859c20346bSAnirudh Venkataramanan return status; 11869c20346bSAnirudh Venkataramanan } 11879c20346bSAnirudh Venkataramanan 11889c20346bSAnirudh Venkataramanan /** 11899c20346bSAnirudh Venkataramanan * ice_get_caps - get info about the HW 11909c20346bSAnirudh Venkataramanan * @hw: pointer to the hardware structure 11919c20346bSAnirudh Venkataramanan */ 11929c20346bSAnirudh Venkataramanan enum ice_status ice_get_caps(struct ice_hw *hw) 11939c20346bSAnirudh Venkataramanan { 11949c20346bSAnirudh Venkataramanan enum ice_status status; 11959c20346bSAnirudh Venkataramanan u16 data_size = 0; 11969c20346bSAnirudh Venkataramanan u16 cbuf_len; 11979c20346bSAnirudh Venkataramanan u8 retries; 11989c20346bSAnirudh Venkataramanan 11999c20346bSAnirudh Venkataramanan /* The driver doesn't know how many capabilities the device will return 12009c20346bSAnirudh Venkataramanan * so the buffer size required isn't known ahead of time. The driver 12019c20346bSAnirudh Venkataramanan * starts with cbuf_len and if this turns out to be insufficient, the 12029c20346bSAnirudh Venkataramanan * device returns ICE_AQ_RC_ENOMEM and also the buffer size it needs. 12039c20346bSAnirudh Venkataramanan * The driver then allocates the buffer of this size and retries the 12049c20346bSAnirudh Venkataramanan * operation. So it follows that the retry count is 2. 12059c20346bSAnirudh Venkataramanan */ 12069c20346bSAnirudh Venkataramanan #define ICE_GET_CAP_BUF_COUNT 40 12079c20346bSAnirudh Venkataramanan #define ICE_GET_CAP_RETRY_COUNT 2 12089c20346bSAnirudh Venkataramanan 12099c20346bSAnirudh Venkataramanan cbuf_len = ICE_GET_CAP_BUF_COUNT * 12109c20346bSAnirudh Venkataramanan sizeof(struct ice_aqc_list_caps_elem); 12119c20346bSAnirudh Venkataramanan 12129c20346bSAnirudh Venkataramanan retries = ICE_GET_CAP_RETRY_COUNT; 12139c20346bSAnirudh Venkataramanan 12149c20346bSAnirudh Venkataramanan do { 12159c20346bSAnirudh Venkataramanan void *cbuf; 12169c20346bSAnirudh Venkataramanan 12179c20346bSAnirudh Venkataramanan cbuf = devm_kzalloc(ice_hw_to_dev(hw), cbuf_len, GFP_KERNEL); 12189c20346bSAnirudh Venkataramanan if (!cbuf) 12199c20346bSAnirudh Venkataramanan return ICE_ERR_NO_MEMORY; 12209c20346bSAnirudh Venkataramanan 12219c20346bSAnirudh Venkataramanan status = ice_aq_discover_caps(hw, cbuf, cbuf_len, &data_size, 12229c20346bSAnirudh Venkataramanan ice_aqc_opc_list_func_caps, NULL); 12239c20346bSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), cbuf); 12249c20346bSAnirudh Venkataramanan 12259c20346bSAnirudh Venkataramanan if (!status || hw->adminq.sq_last_status != ICE_AQ_RC_ENOMEM) 12269c20346bSAnirudh Venkataramanan break; 12279c20346bSAnirudh Venkataramanan 12289c20346bSAnirudh Venkataramanan /* If ENOMEM is returned, try again with bigger buffer */ 12299c20346bSAnirudh Venkataramanan cbuf_len = data_size; 12309c20346bSAnirudh Venkataramanan } while (--retries); 12319c20346bSAnirudh Venkataramanan 12329c20346bSAnirudh Venkataramanan return status; 12339c20346bSAnirudh Venkataramanan } 12349c20346bSAnirudh Venkataramanan 12359c20346bSAnirudh Venkataramanan /** 1236f31e4b6fSAnirudh Venkataramanan * ice_aq_clear_pxe_mode 1237f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hw struct 1238f31e4b6fSAnirudh Venkataramanan * 1239f31e4b6fSAnirudh Venkataramanan * Tell the firmware that the driver is taking over from PXE (0x0110). 1240f31e4b6fSAnirudh Venkataramanan */ 1241f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_aq_clear_pxe_mode(struct ice_hw *hw) 1242f31e4b6fSAnirudh Venkataramanan { 1243f31e4b6fSAnirudh Venkataramanan struct ice_aq_desc desc; 1244f31e4b6fSAnirudh Venkataramanan 1245f31e4b6fSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pxe_mode); 1246f31e4b6fSAnirudh Venkataramanan desc.params.clear_pxe.rx_cnt = ICE_AQC_CLEAR_PXE_RX_CNT; 1247f31e4b6fSAnirudh Venkataramanan 1248f31e4b6fSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 1249f31e4b6fSAnirudh Venkataramanan } 1250f31e4b6fSAnirudh Venkataramanan 1251f31e4b6fSAnirudh Venkataramanan /** 1252f31e4b6fSAnirudh Venkataramanan * ice_clear_pxe_mode - clear pxe operations mode 1253f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the hw struct 1254f31e4b6fSAnirudh Venkataramanan * 1255f31e4b6fSAnirudh Venkataramanan * Make sure all PXE mode settings are cleared, including things 1256f31e4b6fSAnirudh Venkataramanan * like descriptor fetch/write-back mode. 1257f31e4b6fSAnirudh Venkataramanan */ 1258f31e4b6fSAnirudh Venkataramanan void ice_clear_pxe_mode(struct ice_hw *hw) 1259f31e4b6fSAnirudh Venkataramanan { 1260f31e4b6fSAnirudh Venkataramanan if (ice_check_sq_alive(hw, &hw->adminq)) 1261f31e4b6fSAnirudh Venkataramanan ice_aq_clear_pxe_mode(hw); 1262f31e4b6fSAnirudh Venkataramanan } 1263cdedef59SAnirudh Venkataramanan 1264cdedef59SAnirudh Venkataramanan /** 1265fcea6f3dSAnirudh Venkataramanan * ice_aq_set_phy_cfg 1266fcea6f3dSAnirudh Venkataramanan * @hw: pointer to the hw struct 1267fcea6f3dSAnirudh Venkataramanan * @lport: logical port number 1268fcea6f3dSAnirudh Venkataramanan * @cfg: structure with PHY configuration data to be set 1269fcea6f3dSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 1270fcea6f3dSAnirudh Venkataramanan * 1271fcea6f3dSAnirudh Venkataramanan * Set the various PHY configuration parameters supported on the Port. 1272fcea6f3dSAnirudh Venkataramanan * One or more of the Set PHY config parameters may be ignored in an MFP 1273fcea6f3dSAnirudh Venkataramanan * mode as the PF may not have the privilege to set some of the PHY Config 1274fcea6f3dSAnirudh Venkataramanan * parameters. This status will be indicated by the command response (0x0601). 1275fcea6f3dSAnirudh Venkataramanan */ 1276fcea6f3dSAnirudh Venkataramanan static enum ice_status 1277fcea6f3dSAnirudh Venkataramanan ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport, 1278fcea6f3dSAnirudh Venkataramanan struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd) 1279fcea6f3dSAnirudh Venkataramanan { 1280fcea6f3dSAnirudh Venkataramanan struct ice_aqc_set_phy_cfg *cmd; 1281fcea6f3dSAnirudh Venkataramanan struct ice_aq_desc desc; 1282fcea6f3dSAnirudh Venkataramanan 1283fcea6f3dSAnirudh Venkataramanan if (!cfg) 1284fcea6f3dSAnirudh Venkataramanan return ICE_ERR_PARAM; 1285fcea6f3dSAnirudh Venkataramanan 1286fcea6f3dSAnirudh Venkataramanan cmd = &desc.params.set_phy; 1287fcea6f3dSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg); 1288fcea6f3dSAnirudh Venkataramanan cmd->lport_num = lport; 1289fcea6f3dSAnirudh Venkataramanan 1290fcea6f3dSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd); 1291fcea6f3dSAnirudh Venkataramanan } 1292fcea6f3dSAnirudh Venkataramanan 1293fcea6f3dSAnirudh Venkataramanan /** 1294fcea6f3dSAnirudh Venkataramanan * ice_update_link_info - update status of the HW network link 1295fcea6f3dSAnirudh Venkataramanan * @pi: port info structure of the interested logical port 1296fcea6f3dSAnirudh Venkataramanan */ 1297fcea6f3dSAnirudh Venkataramanan static enum ice_status 1298fcea6f3dSAnirudh Venkataramanan ice_update_link_info(struct ice_port_info *pi) 1299fcea6f3dSAnirudh Venkataramanan { 1300fcea6f3dSAnirudh Venkataramanan struct ice_aqc_get_phy_caps_data *pcaps; 1301fcea6f3dSAnirudh Venkataramanan struct ice_phy_info *phy_info; 1302fcea6f3dSAnirudh Venkataramanan enum ice_status status; 1303fcea6f3dSAnirudh Venkataramanan struct ice_hw *hw; 1304fcea6f3dSAnirudh Venkataramanan 1305fcea6f3dSAnirudh Venkataramanan if (!pi) 1306fcea6f3dSAnirudh Venkataramanan return ICE_ERR_PARAM; 1307fcea6f3dSAnirudh Venkataramanan 1308fcea6f3dSAnirudh Venkataramanan hw = pi->hw; 1309fcea6f3dSAnirudh Venkataramanan 1310fcea6f3dSAnirudh Venkataramanan pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL); 1311fcea6f3dSAnirudh Venkataramanan if (!pcaps) 1312fcea6f3dSAnirudh Venkataramanan return ICE_ERR_NO_MEMORY; 1313fcea6f3dSAnirudh Venkataramanan 1314fcea6f3dSAnirudh Venkataramanan phy_info = &pi->phy; 1315fcea6f3dSAnirudh Venkataramanan status = ice_aq_get_link_info(pi, true, NULL, NULL); 1316fcea6f3dSAnirudh Venkataramanan if (status) 1317fcea6f3dSAnirudh Venkataramanan goto out; 1318fcea6f3dSAnirudh Venkataramanan 1319fcea6f3dSAnirudh Venkataramanan if (phy_info->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) { 1320fcea6f3dSAnirudh Venkataramanan status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, 1321fcea6f3dSAnirudh Venkataramanan pcaps, NULL); 1322fcea6f3dSAnirudh Venkataramanan if (status) 1323fcea6f3dSAnirudh Venkataramanan goto out; 1324fcea6f3dSAnirudh Venkataramanan 1325fcea6f3dSAnirudh Venkataramanan memcpy(phy_info->link_info.module_type, &pcaps->module_type, 1326fcea6f3dSAnirudh Venkataramanan sizeof(phy_info->link_info.module_type)); 1327fcea6f3dSAnirudh Venkataramanan } 1328fcea6f3dSAnirudh Venkataramanan out: 1329fcea6f3dSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), pcaps); 1330fcea6f3dSAnirudh Venkataramanan return status; 1331fcea6f3dSAnirudh Venkataramanan } 1332fcea6f3dSAnirudh Venkataramanan 1333fcea6f3dSAnirudh Venkataramanan /** 1334fcea6f3dSAnirudh Venkataramanan * ice_set_fc 1335fcea6f3dSAnirudh Venkataramanan * @pi: port information structure 1336fcea6f3dSAnirudh Venkataramanan * @aq_failures: pointer to status code, specific to ice_set_fc routine 1337fcea6f3dSAnirudh Venkataramanan * @atomic_restart: enable automatic link update 1338fcea6f3dSAnirudh Venkataramanan * 1339fcea6f3dSAnirudh Venkataramanan * Set the requested flow control mode. 1340fcea6f3dSAnirudh Venkataramanan */ 1341fcea6f3dSAnirudh Venkataramanan enum ice_status 1342fcea6f3dSAnirudh Venkataramanan ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool atomic_restart) 1343fcea6f3dSAnirudh Venkataramanan { 1344fcea6f3dSAnirudh Venkataramanan struct ice_aqc_set_phy_cfg_data cfg = { 0 }; 1345fcea6f3dSAnirudh Venkataramanan struct ice_aqc_get_phy_caps_data *pcaps; 1346fcea6f3dSAnirudh Venkataramanan enum ice_status status; 1347fcea6f3dSAnirudh Venkataramanan u8 pause_mask = 0x0; 1348fcea6f3dSAnirudh Venkataramanan struct ice_hw *hw; 1349fcea6f3dSAnirudh Venkataramanan 1350fcea6f3dSAnirudh Venkataramanan if (!pi) 1351fcea6f3dSAnirudh Venkataramanan return ICE_ERR_PARAM; 1352fcea6f3dSAnirudh Venkataramanan hw = pi->hw; 1353fcea6f3dSAnirudh Venkataramanan *aq_failures = ICE_SET_FC_AQ_FAIL_NONE; 1354fcea6f3dSAnirudh Venkataramanan 1355fcea6f3dSAnirudh Venkataramanan switch (pi->fc.req_mode) { 1356fcea6f3dSAnirudh Venkataramanan case ICE_FC_FULL: 1357fcea6f3dSAnirudh Venkataramanan pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE; 1358fcea6f3dSAnirudh Venkataramanan pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE; 1359fcea6f3dSAnirudh Venkataramanan break; 1360fcea6f3dSAnirudh Venkataramanan case ICE_FC_RX_PAUSE: 1361fcea6f3dSAnirudh Venkataramanan pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE; 1362fcea6f3dSAnirudh Venkataramanan break; 1363fcea6f3dSAnirudh Venkataramanan case ICE_FC_TX_PAUSE: 1364fcea6f3dSAnirudh Venkataramanan pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE; 1365fcea6f3dSAnirudh Venkataramanan break; 1366fcea6f3dSAnirudh Venkataramanan default: 1367fcea6f3dSAnirudh Venkataramanan break; 1368fcea6f3dSAnirudh Venkataramanan } 1369fcea6f3dSAnirudh Venkataramanan 1370fcea6f3dSAnirudh Venkataramanan pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL); 1371fcea6f3dSAnirudh Venkataramanan if (!pcaps) 1372fcea6f3dSAnirudh Venkataramanan return ICE_ERR_NO_MEMORY; 1373fcea6f3dSAnirudh Venkataramanan 1374fcea6f3dSAnirudh Venkataramanan /* Get the current phy config */ 1375fcea6f3dSAnirudh Venkataramanan status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps, 1376fcea6f3dSAnirudh Venkataramanan NULL); 1377fcea6f3dSAnirudh Venkataramanan if (status) { 1378fcea6f3dSAnirudh Venkataramanan *aq_failures = ICE_SET_FC_AQ_FAIL_GET; 1379fcea6f3dSAnirudh Venkataramanan goto out; 1380fcea6f3dSAnirudh Venkataramanan } 1381fcea6f3dSAnirudh Venkataramanan 1382fcea6f3dSAnirudh Venkataramanan /* clear the old pause settings */ 1383fcea6f3dSAnirudh Venkataramanan cfg.caps = pcaps->caps & ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE | 1384fcea6f3dSAnirudh Venkataramanan ICE_AQC_PHY_EN_RX_LINK_PAUSE); 1385fcea6f3dSAnirudh Venkataramanan /* set the new capabilities */ 1386fcea6f3dSAnirudh Venkataramanan cfg.caps |= pause_mask; 1387fcea6f3dSAnirudh Venkataramanan /* If the capabilities have changed, then set the new config */ 1388fcea6f3dSAnirudh Venkataramanan if (cfg.caps != pcaps->caps) { 1389fcea6f3dSAnirudh Venkataramanan int retry_count, retry_max = 10; 1390fcea6f3dSAnirudh Venkataramanan 1391fcea6f3dSAnirudh Venkataramanan /* Auto restart link so settings take effect */ 1392fcea6f3dSAnirudh Venkataramanan if (atomic_restart) 1393fcea6f3dSAnirudh Venkataramanan cfg.caps |= ICE_AQ_PHY_ENA_ATOMIC_LINK; 1394fcea6f3dSAnirudh Venkataramanan /* Copy over all the old settings */ 1395fcea6f3dSAnirudh Venkataramanan cfg.phy_type_low = pcaps->phy_type_low; 1396fcea6f3dSAnirudh Venkataramanan cfg.low_power_ctrl = pcaps->low_power_ctrl; 1397fcea6f3dSAnirudh Venkataramanan cfg.eee_cap = pcaps->eee_cap; 1398fcea6f3dSAnirudh Venkataramanan cfg.eeer_value = pcaps->eeer_value; 1399fcea6f3dSAnirudh Venkataramanan cfg.link_fec_opt = pcaps->link_fec_options; 1400fcea6f3dSAnirudh Venkataramanan 1401fcea6f3dSAnirudh Venkataramanan status = ice_aq_set_phy_cfg(hw, pi->lport, &cfg, NULL); 1402fcea6f3dSAnirudh Venkataramanan if (status) { 1403fcea6f3dSAnirudh Venkataramanan *aq_failures = ICE_SET_FC_AQ_FAIL_SET; 1404fcea6f3dSAnirudh Venkataramanan goto out; 1405fcea6f3dSAnirudh Venkataramanan } 1406fcea6f3dSAnirudh Venkataramanan 1407fcea6f3dSAnirudh Venkataramanan /* Update the link info 1408fcea6f3dSAnirudh Venkataramanan * It sometimes takes a really long time for link to 1409fcea6f3dSAnirudh Venkataramanan * come back from the atomic reset. Thus, we wait a 1410fcea6f3dSAnirudh Venkataramanan * little bit. 1411fcea6f3dSAnirudh Venkataramanan */ 1412fcea6f3dSAnirudh Venkataramanan for (retry_count = 0; retry_count < retry_max; retry_count++) { 1413fcea6f3dSAnirudh Venkataramanan status = ice_update_link_info(pi); 1414fcea6f3dSAnirudh Venkataramanan 1415fcea6f3dSAnirudh Venkataramanan if (!status) 1416fcea6f3dSAnirudh Venkataramanan break; 1417fcea6f3dSAnirudh Venkataramanan 1418fcea6f3dSAnirudh Venkataramanan mdelay(100); 1419fcea6f3dSAnirudh Venkataramanan } 1420fcea6f3dSAnirudh Venkataramanan 1421fcea6f3dSAnirudh Venkataramanan if (status) 1422fcea6f3dSAnirudh Venkataramanan *aq_failures = ICE_SET_FC_AQ_FAIL_UPDATE; 1423fcea6f3dSAnirudh Venkataramanan } 1424fcea6f3dSAnirudh Venkataramanan 1425fcea6f3dSAnirudh Venkataramanan out: 1426fcea6f3dSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), pcaps); 1427fcea6f3dSAnirudh Venkataramanan return status; 1428fcea6f3dSAnirudh Venkataramanan } 1429fcea6f3dSAnirudh Venkataramanan 1430fcea6f3dSAnirudh Venkataramanan /** 14310b28b702SAnirudh Venkataramanan * ice_get_link_status - get status of the HW network link 14320b28b702SAnirudh Venkataramanan * @pi: port information structure 14330b28b702SAnirudh Venkataramanan * @link_up: pointer to bool (true/false = linkup/linkdown) 14340b28b702SAnirudh Venkataramanan * 14350b28b702SAnirudh Venkataramanan * Variable link_up is true if link is up, false if link is down. 14360b28b702SAnirudh Venkataramanan * The variable link_up is invalid if status is non zero. As a 14370b28b702SAnirudh Venkataramanan * result of this call, link status reporting becomes enabled 14380b28b702SAnirudh Venkataramanan */ 14390b28b702SAnirudh Venkataramanan enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up) 14400b28b702SAnirudh Venkataramanan { 14410b28b702SAnirudh Venkataramanan struct ice_phy_info *phy_info; 14420b28b702SAnirudh Venkataramanan enum ice_status status = 0; 14430b28b702SAnirudh Venkataramanan 14440b28b702SAnirudh Venkataramanan if (!pi) 14450b28b702SAnirudh Venkataramanan return ICE_ERR_PARAM; 14460b28b702SAnirudh Venkataramanan 14470b28b702SAnirudh Venkataramanan phy_info = &pi->phy; 14480b28b702SAnirudh Venkataramanan 14490b28b702SAnirudh Venkataramanan if (phy_info->get_link_info) { 14500b28b702SAnirudh Venkataramanan status = ice_update_link_info(pi); 14510b28b702SAnirudh Venkataramanan 14520b28b702SAnirudh Venkataramanan if (status) 14530b28b702SAnirudh Venkataramanan ice_debug(pi->hw, ICE_DBG_LINK, 14540b28b702SAnirudh Venkataramanan "get link status error, status = %d\n", 14550b28b702SAnirudh Venkataramanan status); 14560b28b702SAnirudh Venkataramanan } 14570b28b702SAnirudh Venkataramanan 14580b28b702SAnirudh Venkataramanan *link_up = phy_info->link_info.link_info & ICE_AQ_LINK_UP; 14590b28b702SAnirudh Venkataramanan 14600b28b702SAnirudh Venkataramanan return status; 14610b28b702SAnirudh Venkataramanan } 14620b28b702SAnirudh Venkataramanan 14630b28b702SAnirudh Venkataramanan /** 1464fcea6f3dSAnirudh Venkataramanan * ice_aq_set_link_restart_an 1465fcea6f3dSAnirudh Venkataramanan * @pi: pointer to the port information structure 1466fcea6f3dSAnirudh Venkataramanan * @ena_link: if true: enable link, if false: disable link 1467fcea6f3dSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 1468fcea6f3dSAnirudh Venkataramanan * 1469fcea6f3dSAnirudh Venkataramanan * Sets up the link and restarts the Auto-Negotiation over the link. 1470fcea6f3dSAnirudh Venkataramanan */ 1471fcea6f3dSAnirudh Venkataramanan enum ice_status 1472fcea6f3dSAnirudh Venkataramanan ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link, 1473fcea6f3dSAnirudh Venkataramanan struct ice_sq_cd *cd) 1474fcea6f3dSAnirudh Venkataramanan { 1475fcea6f3dSAnirudh Venkataramanan struct ice_aqc_restart_an *cmd; 1476fcea6f3dSAnirudh Venkataramanan struct ice_aq_desc desc; 1477fcea6f3dSAnirudh Venkataramanan 1478fcea6f3dSAnirudh Venkataramanan cmd = &desc.params.restart_an; 1479fcea6f3dSAnirudh Venkataramanan 1480fcea6f3dSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_restart_an); 1481fcea6f3dSAnirudh Venkataramanan 1482fcea6f3dSAnirudh Venkataramanan cmd->cmd_flags = ICE_AQC_RESTART_AN_LINK_RESTART; 1483fcea6f3dSAnirudh Venkataramanan cmd->lport_num = pi->lport; 1484fcea6f3dSAnirudh Venkataramanan if (ena_link) 1485fcea6f3dSAnirudh Venkataramanan cmd->cmd_flags |= ICE_AQC_RESTART_AN_LINK_ENABLE; 1486fcea6f3dSAnirudh Venkataramanan else 1487fcea6f3dSAnirudh Venkataramanan cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE; 1488fcea6f3dSAnirudh Venkataramanan 1489fcea6f3dSAnirudh Venkataramanan return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd); 1490fcea6f3dSAnirudh Venkataramanan } 1491fcea6f3dSAnirudh Venkataramanan 1492fcea6f3dSAnirudh Venkataramanan /** 14930b28b702SAnirudh Venkataramanan * ice_aq_set_event_mask 14940b28b702SAnirudh Venkataramanan * @hw: pointer to the hw struct 14950b28b702SAnirudh Venkataramanan * @port_num: port number of the physical function 14960b28b702SAnirudh Venkataramanan * @mask: event mask to be set 14970b28b702SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 14980b28b702SAnirudh Venkataramanan * 14990b28b702SAnirudh Venkataramanan * Set event mask (0x0613) 15000b28b702SAnirudh Venkataramanan */ 15010b28b702SAnirudh Venkataramanan enum ice_status 15020b28b702SAnirudh Venkataramanan ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask, 15030b28b702SAnirudh Venkataramanan struct ice_sq_cd *cd) 15040b28b702SAnirudh Venkataramanan { 15050b28b702SAnirudh Venkataramanan struct ice_aqc_set_event_mask *cmd; 15060b28b702SAnirudh Venkataramanan struct ice_aq_desc desc; 15070b28b702SAnirudh Venkataramanan 15080b28b702SAnirudh Venkataramanan cmd = &desc.params.set_event_mask; 15090b28b702SAnirudh Venkataramanan 15100b28b702SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_event_mask); 15110b28b702SAnirudh Venkataramanan 15120b28b702SAnirudh Venkataramanan cmd->lport_num = port_num; 15130b28b702SAnirudh Venkataramanan 15140b28b702SAnirudh Venkataramanan cmd->event_mask = cpu_to_le16(mask); 15150b28b702SAnirudh Venkataramanan 15160b28b702SAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 15170b28b702SAnirudh Venkataramanan } 15180b28b702SAnirudh Venkataramanan 15190b28b702SAnirudh Venkataramanan /** 1520d76a60baSAnirudh Venkataramanan * __ice_aq_get_set_rss_lut 1521d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 1522d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1523d76a60baSAnirudh Venkataramanan * @lut_type: LUT table type 1524d76a60baSAnirudh Venkataramanan * @lut: pointer to the LUT buffer provided by the caller 1525d76a60baSAnirudh Venkataramanan * @lut_size: size of the LUT buffer 1526d76a60baSAnirudh Venkataramanan * @glob_lut_idx: global LUT index 1527d76a60baSAnirudh Venkataramanan * @set: set true to set the table, false to get the table 1528d76a60baSAnirudh Venkataramanan * 1529d76a60baSAnirudh Venkataramanan * Internal function to get (0x0B05) or set (0x0B03) RSS look up table 1530d76a60baSAnirudh Venkataramanan */ 1531d76a60baSAnirudh Venkataramanan static enum ice_status 1532d76a60baSAnirudh Venkataramanan __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut, 1533d76a60baSAnirudh Venkataramanan u16 lut_size, u8 glob_lut_idx, bool set) 1534d76a60baSAnirudh Venkataramanan { 1535d76a60baSAnirudh Venkataramanan struct ice_aqc_get_set_rss_lut *cmd_resp; 1536d76a60baSAnirudh Venkataramanan struct ice_aq_desc desc; 1537d76a60baSAnirudh Venkataramanan enum ice_status status; 1538d76a60baSAnirudh Venkataramanan u16 flags = 0; 1539d76a60baSAnirudh Venkataramanan 1540d76a60baSAnirudh Venkataramanan cmd_resp = &desc.params.get_set_rss_lut; 1541d76a60baSAnirudh Venkataramanan 1542d76a60baSAnirudh Venkataramanan if (set) { 1543d76a60baSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut); 1544d76a60baSAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1545d76a60baSAnirudh Venkataramanan } else { 1546d76a60baSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut); 1547d76a60baSAnirudh Venkataramanan } 1548d76a60baSAnirudh Venkataramanan 1549d76a60baSAnirudh Venkataramanan cmd_resp->vsi_id = cpu_to_le16(((vsi_id << 1550d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_VSI_ID_S) & 1551d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_VSI_ID_M) | 1552d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_VSI_VALID); 1553d76a60baSAnirudh Venkataramanan 1554d76a60baSAnirudh Venkataramanan switch (lut_type) { 1555d76a60baSAnirudh Venkataramanan case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI: 1556d76a60baSAnirudh Venkataramanan case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF: 1557d76a60baSAnirudh Venkataramanan case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL: 1558d76a60baSAnirudh Venkataramanan flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) & 1559d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M); 1560d76a60baSAnirudh Venkataramanan break; 1561d76a60baSAnirudh Venkataramanan default: 1562d76a60baSAnirudh Venkataramanan status = ICE_ERR_PARAM; 1563d76a60baSAnirudh Venkataramanan goto ice_aq_get_set_rss_lut_exit; 1564d76a60baSAnirudh Venkataramanan } 1565d76a60baSAnirudh Venkataramanan 1566d76a60baSAnirudh Venkataramanan if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) { 1567d76a60baSAnirudh Venkataramanan flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) & 1568d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M); 1569d76a60baSAnirudh Venkataramanan 1570d76a60baSAnirudh Venkataramanan if (!set) 1571d76a60baSAnirudh Venkataramanan goto ice_aq_get_set_rss_lut_send; 1572d76a60baSAnirudh Venkataramanan } else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) { 1573d76a60baSAnirudh Venkataramanan if (!set) 1574d76a60baSAnirudh Venkataramanan goto ice_aq_get_set_rss_lut_send; 1575d76a60baSAnirudh Venkataramanan } else { 1576d76a60baSAnirudh Venkataramanan goto ice_aq_get_set_rss_lut_send; 1577d76a60baSAnirudh Venkataramanan } 1578d76a60baSAnirudh Venkataramanan 1579d76a60baSAnirudh Venkataramanan /* LUT size is only valid for Global and PF table types */ 1580d76a60baSAnirudh Venkataramanan if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128) { 1581d76a60baSAnirudh Venkataramanan flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG << 1582d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) & 1583d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M; 1584d76a60baSAnirudh Venkataramanan } else if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512) { 1585d76a60baSAnirudh Venkataramanan flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG << 1586d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) & 1587d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M; 1588d76a60baSAnirudh Venkataramanan } else if ((lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K) && 1589d76a60baSAnirudh Venkataramanan (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF)) { 1590d76a60baSAnirudh Venkataramanan flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG << 1591d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) & 1592d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M; 1593d76a60baSAnirudh Venkataramanan } else { 1594d76a60baSAnirudh Venkataramanan status = ICE_ERR_PARAM; 1595d76a60baSAnirudh Venkataramanan goto ice_aq_get_set_rss_lut_exit; 1596d76a60baSAnirudh Venkataramanan } 1597d76a60baSAnirudh Venkataramanan 1598d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_send: 1599d76a60baSAnirudh Venkataramanan cmd_resp->flags = cpu_to_le16(flags); 1600d76a60baSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL); 1601d76a60baSAnirudh Venkataramanan 1602d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_exit: 1603d76a60baSAnirudh Venkataramanan return status; 1604d76a60baSAnirudh Venkataramanan } 1605d76a60baSAnirudh Venkataramanan 1606d76a60baSAnirudh Venkataramanan /** 1607d76a60baSAnirudh Venkataramanan * ice_aq_get_rss_lut 1608d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 1609d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1610d76a60baSAnirudh Venkataramanan * @lut_type: LUT table type 1611d76a60baSAnirudh Venkataramanan * @lut: pointer to the LUT buffer provided by the caller 1612d76a60baSAnirudh Venkataramanan * @lut_size: size of the LUT buffer 1613d76a60baSAnirudh Venkataramanan * 1614d76a60baSAnirudh Venkataramanan * get the RSS lookup table, PF or VSI type 1615d76a60baSAnirudh Venkataramanan */ 1616d76a60baSAnirudh Venkataramanan enum ice_status 1617d76a60baSAnirudh Venkataramanan ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut, 1618d76a60baSAnirudh Venkataramanan u16 lut_size) 1619d76a60baSAnirudh Venkataramanan { 1620d76a60baSAnirudh Venkataramanan return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0, 1621d76a60baSAnirudh Venkataramanan false); 1622d76a60baSAnirudh Venkataramanan } 1623d76a60baSAnirudh Venkataramanan 1624d76a60baSAnirudh Venkataramanan /** 1625d76a60baSAnirudh Venkataramanan * ice_aq_set_rss_lut 1626d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 1627d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1628d76a60baSAnirudh Venkataramanan * @lut_type: LUT table type 1629d76a60baSAnirudh Venkataramanan * @lut: pointer to the LUT buffer provided by the caller 1630d76a60baSAnirudh Venkataramanan * @lut_size: size of the LUT buffer 1631d76a60baSAnirudh Venkataramanan * 1632d76a60baSAnirudh Venkataramanan * set the RSS lookup table, PF or VSI type 1633d76a60baSAnirudh Venkataramanan */ 1634d76a60baSAnirudh Venkataramanan enum ice_status 1635d76a60baSAnirudh Venkataramanan ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut, 1636d76a60baSAnirudh Venkataramanan u16 lut_size) 1637d76a60baSAnirudh Venkataramanan { 1638d76a60baSAnirudh Venkataramanan return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0, 1639d76a60baSAnirudh Venkataramanan true); 1640d76a60baSAnirudh Venkataramanan } 1641d76a60baSAnirudh Venkataramanan 1642d76a60baSAnirudh Venkataramanan /** 1643d76a60baSAnirudh Venkataramanan * __ice_aq_get_set_rss_key 1644d76a60baSAnirudh Venkataramanan * @hw: pointer to the hw struct 1645d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1646d76a60baSAnirudh Venkataramanan * @key: pointer to key info struct 1647d76a60baSAnirudh Venkataramanan * @set: set true to set the key, false to get the key 1648d76a60baSAnirudh Venkataramanan * 1649d76a60baSAnirudh Venkataramanan * get (0x0B04) or set (0x0B02) the RSS key per VSI 1650d76a60baSAnirudh Venkataramanan */ 1651d76a60baSAnirudh Venkataramanan static enum 1652d76a60baSAnirudh Venkataramanan ice_status __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id, 1653d76a60baSAnirudh Venkataramanan struct ice_aqc_get_set_rss_keys *key, 1654d76a60baSAnirudh Venkataramanan bool set) 1655d76a60baSAnirudh Venkataramanan { 1656d76a60baSAnirudh Venkataramanan struct ice_aqc_get_set_rss_key *cmd_resp; 1657d76a60baSAnirudh Venkataramanan u16 key_size = sizeof(*key); 1658d76a60baSAnirudh Venkataramanan struct ice_aq_desc desc; 1659d76a60baSAnirudh Venkataramanan 1660d76a60baSAnirudh Venkataramanan cmd_resp = &desc.params.get_set_rss_key; 1661d76a60baSAnirudh Venkataramanan 1662d76a60baSAnirudh Venkataramanan if (set) { 1663d76a60baSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key); 1664d76a60baSAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1665d76a60baSAnirudh Venkataramanan } else { 1666d76a60baSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key); 1667d76a60baSAnirudh Venkataramanan } 1668d76a60baSAnirudh Venkataramanan 1669d76a60baSAnirudh Venkataramanan cmd_resp->vsi_id = cpu_to_le16(((vsi_id << 1670d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_KEY_VSI_ID_S) & 1671d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_KEY_VSI_ID_M) | 1672d76a60baSAnirudh Venkataramanan ICE_AQC_GSET_RSS_KEY_VSI_VALID); 1673d76a60baSAnirudh Venkataramanan 1674d76a60baSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, key, key_size, NULL); 1675d76a60baSAnirudh Venkataramanan } 1676d76a60baSAnirudh Venkataramanan 1677d76a60baSAnirudh Venkataramanan /** 1678d76a60baSAnirudh Venkataramanan * ice_aq_get_rss_key 1679d76a60baSAnirudh Venkataramanan * @hw: pointer to the hw struct 1680d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1681d76a60baSAnirudh Venkataramanan * @key: pointer to key info struct 1682d76a60baSAnirudh Venkataramanan * 1683d76a60baSAnirudh Venkataramanan * get the RSS key per VSI 1684d76a60baSAnirudh Venkataramanan */ 1685d76a60baSAnirudh Venkataramanan enum ice_status 1686d76a60baSAnirudh Venkataramanan ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_id, 1687d76a60baSAnirudh Venkataramanan struct ice_aqc_get_set_rss_keys *key) 1688d76a60baSAnirudh Venkataramanan { 1689d76a60baSAnirudh Venkataramanan return __ice_aq_get_set_rss_key(hw, vsi_id, key, false); 1690d76a60baSAnirudh Venkataramanan } 1691d76a60baSAnirudh Venkataramanan 1692d76a60baSAnirudh Venkataramanan /** 1693d76a60baSAnirudh Venkataramanan * ice_aq_set_rss_key 1694d76a60baSAnirudh Venkataramanan * @hw: pointer to the hw struct 1695d76a60baSAnirudh Venkataramanan * @vsi_id: VSI FW index 1696d76a60baSAnirudh Venkataramanan * @keys: pointer to key info struct 1697d76a60baSAnirudh Venkataramanan * 1698d76a60baSAnirudh Venkataramanan * set the RSS key per VSI 1699d76a60baSAnirudh Venkataramanan */ 1700d76a60baSAnirudh Venkataramanan enum ice_status 1701d76a60baSAnirudh Venkataramanan ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_id, 1702d76a60baSAnirudh Venkataramanan struct ice_aqc_get_set_rss_keys *keys) 1703d76a60baSAnirudh Venkataramanan { 1704d76a60baSAnirudh Venkataramanan return __ice_aq_get_set_rss_key(hw, vsi_id, keys, true); 1705d76a60baSAnirudh Venkataramanan } 1706d76a60baSAnirudh Venkataramanan 1707d76a60baSAnirudh Venkataramanan /** 1708cdedef59SAnirudh Venkataramanan * ice_aq_add_lan_txq 1709cdedef59SAnirudh Venkataramanan * @hw: pointer to the hardware structure 1710cdedef59SAnirudh Venkataramanan * @num_qgrps: Number of added queue groups 1711cdedef59SAnirudh Venkataramanan * @qg_list: list of queue groups to be added 1712cdedef59SAnirudh Venkataramanan * @buf_size: size of buffer for indirect command 1713cdedef59SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 1714cdedef59SAnirudh Venkataramanan * 1715cdedef59SAnirudh Venkataramanan * Add Tx LAN queue (0x0C30) 1716cdedef59SAnirudh Venkataramanan * 1717cdedef59SAnirudh Venkataramanan * NOTE: 1718cdedef59SAnirudh Venkataramanan * Prior to calling add Tx LAN queue: 1719cdedef59SAnirudh Venkataramanan * Initialize the following as part of the Tx queue context: 1720cdedef59SAnirudh Venkataramanan * Completion queue ID if the queue uses Completion queue, Quanta profile, 1721cdedef59SAnirudh Venkataramanan * Cache profile and Packet shaper profile. 1722cdedef59SAnirudh Venkataramanan * 1723cdedef59SAnirudh Venkataramanan * After add Tx LAN queue AQ command is completed: 1724cdedef59SAnirudh Venkataramanan * Interrupts should be associated with specific queues, 1725cdedef59SAnirudh Venkataramanan * Association of Tx queue to Doorbell queue is not part of Add LAN Tx queue 1726cdedef59SAnirudh Venkataramanan * flow. 1727cdedef59SAnirudh Venkataramanan */ 1728cdedef59SAnirudh Venkataramanan static enum ice_status 1729cdedef59SAnirudh Venkataramanan ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps, 1730cdedef59SAnirudh Venkataramanan struct ice_aqc_add_tx_qgrp *qg_list, u16 buf_size, 1731cdedef59SAnirudh Venkataramanan struct ice_sq_cd *cd) 1732cdedef59SAnirudh Venkataramanan { 1733cdedef59SAnirudh Venkataramanan u16 i, sum_header_size, sum_q_size = 0; 1734cdedef59SAnirudh Venkataramanan struct ice_aqc_add_tx_qgrp *list; 1735cdedef59SAnirudh Venkataramanan struct ice_aqc_add_txqs *cmd; 1736cdedef59SAnirudh Venkataramanan struct ice_aq_desc desc; 1737cdedef59SAnirudh Venkataramanan 1738cdedef59SAnirudh Venkataramanan cmd = &desc.params.add_txqs; 1739cdedef59SAnirudh Venkataramanan 1740cdedef59SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_txqs); 1741cdedef59SAnirudh Venkataramanan 1742cdedef59SAnirudh Venkataramanan if (!qg_list) 1743cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1744cdedef59SAnirudh Venkataramanan 1745cdedef59SAnirudh Venkataramanan if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS) 1746cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1747cdedef59SAnirudh Venkataramanan 1748cdedef59SAnirudh Venkataramanan sum_header_size = num_qgrps * 1749cdedef59SAnirudh Venkataramanan (sizeof(*qg_list) - sizeof(*qg_list->txqs)); 1750cdedef59SAnirudh Venkataramanan 1751cdedef59SAnirudh Venkataramanan list = qg_list; 1752cdedef59SAnirudh Venkataramanan for (i = 0; i < num_qgrps; i++) { 1753cdedef59SAnirudh Venkataramanan struct ice_aqc_add_txqs_perq *q = list->txqs; 1754cdedef59SAnirudh Venkataramanan 1755cdedef59SAnirudh Venkataramanan sum_q_size += list->num_txqs * sizeof(*q); 1756cdedef59SAnirudh Venkataramanan list = (struct ice_aqc_add_tx_qgrp *)(q + list->num_txqs); 1757cdedef59SAnirudh Venkataramanan } 1758cdedef59SAnirudh Venkataramanan 1759cdedef59SAnirudh Venkataramanan if (buf_size != (sum_header_size + sum_q_size)) 1760cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1761cdedef59SAnirudh Venkataramanan 1762cdedef59SAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1763cdedef59SAnirudh Venkataramanan 1764cdedef59SAnirudh Venkataramanan cmd->num_qgrps = num_qgrps; 1765cdedef59SAnirudh Venkataramanan 1766cdedef59SAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd); 1767cdedef59SAnirudh Venkataramanan } 1768cdedef59SAnirudh Venkataramanan 1769cdedef59SAnirudh Venkataramanan /** 1770cdedef59SAnirudh Venkataramanan * ice_aq_dis_lan_txq 1771cdedef59SAnirudh Venkataramanan * @hw: pointer to the hardware structure 1772cdedef59SAnirudh Venkataramanan * @num_qgrps: number of groups in the list 1773cdedef59SAnirudh Venkataramanan * @qg_list: the list of groups to disable 1774cdedef59SAnirudh Venkataramanan * @buf_size: the total size of the qg_list buffer in bytes 1775cdedef59SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 1776cdedef59SAnirudh Venkataramanan * 1777cdedef59SAnirudh Venkataramanan * Disable LAN Tx queue (0x0C31) 1778cdedef59SAnirudh Venkataramanan */ 1779cdedef59SAnirudh Venkataramanan static enum ice_status 1780cdedef59SAnirudh Venkataramanan ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps, 1781cdedef59SAnirudh Venkataramanan struct ice_aqc_dis_txq_item *qg_list, u16 buf_size, 1782cdedef59SAnirudh Venkataramanan struct ice_sq_cd *cd) 1783cdedef59SAnirudh Venkataramanan { 1784cdedef59SAnirudh Venkataramanan struct ice_aqc_dis_txqs *cmd; 1785cdedef59SAnirudh Venkataramanan struct ice_aq_desc desc; 1786cdedef59SAnirudh Venkataramanan u16 i, sz = 0; 1787cdedef59SAnirudh Venkataramanan 1788cdedef59SAnirudh Venkataramanan cmd = &desc.params.dis_txqs; 1789cdedef59SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_dis_txqs); 1790cdedef59SAnirudh Venkataramanan 1791cdedef59SAnirudh Venkataramanan if (!qg_list) 1792cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1793cdedef59SAnirudh Venkataramanan 1794cdedef59SAnirudh Venkataramanan if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS) 1795cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1796cdedef59SAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1797cdedef59SAnirudh Venkataramanan cmd->num_entries = num_qgrps; 1798cdedef59SAnirudh Venkataramanan 1799cdedef59SAnirudh Venkataramanan for (i = 0; i < num_qgrps; ++i) { 1800cdedef59SAnirudh Venkataramanan /* Calculate the size taken up by the queue IDs in this group */ 1801cdedef59SAnirudh Venkataramanan sz += qg_list[i].num_qs * sizeof(qg_list[i].q_id); 1802cdedef59SAnirudh Venkataramanan 1803cdedef59SAnirudh Venkataramanan /* Add the size of the group header */ 1804cdedef59SAnirudh Venkataramanan sz += sizeof(qg_list[i]) - sizeof(qg_list[i].q_id); 1805cdedef59SAnirudh Venkataramanan 1806cdedef59SAnirudh Venkataramanan /* If the num of queues is even, add 2 bytes of padding */ 1807cdedef59SAnirudh Venkataramanan if ((qg_list[i].num_qs % 2) == 0) 1808cdedef59SAnirudh Venkataramanan sz += 2; 1809cdedef59SAnirudh Venkataramanan } 1810cdedef59SAnirudh Venkataramanan 1811cdedef59SAnirudh Venkataramanan if (buf_size != sz) 1812cdedef59SAnirudh Venkataramanan return ICE_ERR_PARAM; 1813cdedef59SAnirudh Venkataramanan 1814cdedef59SAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd); 1815cdedef59SAnirudh Venkataramanan } 1816cdedef59SAnirudh Venkataramanan 1817cdedef59SAnirudh Venkataramanan /* End of FW Admin Queue command wrappers */ 1818cdedef59SAnirudh Venkataramanan 1819cdedef59SAnirudh Venkataramanan /** 1820cdedef59SAnirudh Venkataramanan * ice_write_byte - write a byte to a packed context structure 1821cdedef59SAnirudh Venkataramanan * @src_ctx: the context structure to read from 1822cdedef59SAnirudh Venkataramanan * @dest_ctx: the context to be written to 1823cdedef59SAnirudh Venkataramanan * @ce_info: a description of the struct to be filled 1824cdedef59SAnirudh Venkataramanan */ 1825cdedef59SAnirudh Venkataramanan static void ice_write_byte(u8 *src_ctx, u8 *dest_ctx, 1826cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele *ce_info) 1827cdedef59SAnirudh Venkataramanan { 1828cdedef59SAnirudh Venkataramanan u8 src_byte, dest_byte, mask; 1829cdedef59SAnirudh Venkataramanan u8 *from, *dest; 1830cdedef59SAnirudh Venkataramanan u16 shift_width; 1831cdedef59SAnirudh Venkataramanan 1832cdedef59SAnirudh Venkataramanan /* copy from the next struct field */ 1833cdedef59SAnirudh Venkataramanan from = src_ctx + ce_info->offset; 1834cdedef59SAnirudh Venkataramanan 1835cdedef59SAnirudh Venkataramanan /* prepare the bits and mask */ 1836cdedef59SAnirudh Venkataramanan shift_width = ce_info->lsb % 8; 1837cdedef59SAnirudh Venkataramanan mask = (u8)(BIT(ce_info->width) - 1); 1838cdedef59SAnirudh Venkataramanan 1839cdedef59SAnirudh Venkataramanan src_byte = *from; 1840cdedef59SAnirudh Venkataramanan src_byte &= mask; 1841cdedef59SAnirudh Venkataramanan 1842cdedef59SAnirudh Venkataramanan /* shift to correct alignment */ 1843cdedef59SAnirudh Venkataramanan mask <<= shift_width; 1844cdedef59SAnirudh Venkataramanan src_byte <<= shift_width; 1845cdedef59SAnirudh Venkataramanan 1846cdedef59SAnirudh Venkataramanan /* get the current bits from the target bit string */ 1847cdedef59SAnirudh Venkataramanan dest = dest_ctx + (ce_info->lsb / 8); 1848cdedef59SAnirudh Venkataramanan 1849cdedef59SAnirudh Venkataramanan memcpy(&dest_byte, dest, sizeof(dest_byte)); 1850cdedef59SAnirudh Venkataramanan 1851cdedef59SAnirudh Venkataramanan dest_byte &= ~mask; /* get the bits not changing */ 1852cdedef59SAnirudh Venkataramanan dest_byte |= src_byte; /* add in the new bits */ 1853cdedef59SAnirudh Venkataramanan 1854cdedef59SAnirudh Venkataramanan /* put it all back */ 1855cdedef59SAnirudh Venkataramanan memcpy(dest, &dest_byte, sizeof(dest_byte)); 1856cdedef59SAnirudh Venkataramanan } 1857cdedef59SAnirudh Venkataramanan 1858cdedef59SAnirudh Venkataramanan /** 1859cdedef59SAnirudh Venkataramanan * ice_write_word - write a word to a packed context structure 1860cdedef59SAnirudh Venkataramanan * @src_ctx: the context structure to read from 1861cdedef59SAnirudh Venkataramanan * @dest_ctx: the context to be written to 1862cdedef59SAnirudh Venkataramanan * @ce_info: a description of the struct to be filled 1863cdedef59SAnirudh Venkataramanan */ 1864cdedef59SAnirudh Venkataramanan static void ice_write_word(u8 *src_ctx, u8 *dest_ctx, 1865cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele *ce_info) 1866cdedef59SAnirudh Venkataramanan { 1867cdedef59SAnirudh Venkataramanan u16 src_word, mask; 1868cdedef59SAnirudh Venkataramanan __le16 dest_word; 1869cdedef59SAnirudh Venkataramanan u8 *from, *dest; 1870cdedef59SAnirudh Venkataramanan u16 shift_width; 1871cdedef59SAnirudh Venkataramanan 1872cdedef59SAnirudh Venkataramanan /* copy from the next struct field */ 1873cdedef59SAnirudh Venkataramanan from = src_ctx + ce_info->offset; 1874cdedef59SAnirudh Venkataramanan 1875cdedef59SAnirudh Venkataramanan /* prepare the bits and mask */ 1876cdedef59SAnirudh Venkataramanan shift_width = ce_info->lsb % 8; 1877cdedef59SAnirudh Venkataramanan mask = BIT(ce_info->width) - 1; 1878cdedef59SAnirudh Venkataramanan 1879cdedef59SAnirudh Venkataramanan /* don't swizzle the bits until after the mask because the mask bits 1880cdedef59SAnirudh Venkataramanan * will be in a different bit position on big endian machines 1881cdedef59SAnirudh Venkataramanan */ 1882cdedef59SAnirudh Venkataramanan src_word = *(u16 *)from; 1883cdedef59SAnirudh Venkataramanan src_word &= mask; 1884cdedef59SAnirudh Venkataramanan 1885cdedef59SAnirudh Venkataramanan /* shift to correct alignment */ 1886cdedef59SAnirudh Venkataramanan mask <<= shift_width; 1887cdedef59SAnirudh Venkataramanan src_word <<= shift_width; 1888cdedef59SAnirudh Venkataramanan 1889cdedef59SAnirudh Venkataramanan /* get the current bits from the target bit string */ 1890cdedef59SAnirudh Venkataramanan dest = dest_ctx + (ce_info->lsb / 8); 1891cdedef59SAnirudh Venkataramanan 1892cdedef59SAnirudh Venkataramanan memcpy(&dest_word, dest, sizeof(dest_word)); 1893cdedef59SAnirudh Venkataramanan 1894cdedef59SAnirudh Venkataramanan dest_word &= ~(cpu_to_le16(mask)); /* get the bits not changing */ 1895cdedef59SAnirudh Venkataramanan dest_word |= cpu_to_le16(src_word); /* add in the new bits */ 1896cdedef59SAnirudh Venkataramanan 1897cdedef59SAnirudh Venkataramanan /* put it all back */ 1898cdedef59SAnirudh Venkataramanan memcpy(dest, &dest_word, sizeof(dest_word)); 1899cdedef59SAnirudh Venkataramanan } 1900cdedef59SAnirudh Venkataramanan 1901cdedef59SAnirudh Venkataramanan /** 1902cdedef59SAnirudh Venkataramanan * ice_write_dword - write a dword to a packed context structure 1903cdedef59SAnirudh Venkataramanan * @src_ctx: the context structure to read from 1904cdedef59SAnirudh Venkataramanan * @dest_ctx: the context to be written to 1905cdedef59SAnirudh Venkataramanan * @ce_info: a description of the struct to be filled 1906cdedef59SAnirudh Venkataramanan */ 1907cdedef59SAnirudh Venkataramanan static void ice_write_dword(u8 *src_ctx, u8 *dest_ctx, 1908cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele *ce_info) 1909cdedef59SAnirudh Venkataramanan { 1910cdedef59SAnirudh Venkataramanan u32 src_dword, mask; 1911cdedef59SAnirudh Venkataramanan __le32 dest_dword; 1912cdedef59SAnirudh Venkataramanan u8 *from, *dest; 1913cdedef59SAnirudh Venkataramanan u16 shift_width; 1914cdedef59SAnirudh Venkataramanan 1915cdedef59SAnirudh Venkataramanan /* copy from the next struct field */ 1916cdedef59SAnirudh Venkataramanan from = src_ctx + ce_info->offset; 1917cdedef59SAnirudh Venkataramanan 1918cdedef59SAnirudh Venkataramanan /* prepare the bits and mask */ 1919cdedef59SAnirudh Venkataramanan shift_width = ce_info->lsb % 8; 1920cdedef59SAnirudh Venkataramanan 1921cdedef59SAnirudh Venkataramanan /* if the field width is exactly 32 on an x86 machine, then the shift 1922cdedef59SAnirudh Venkataramanan * operation will not work because the SHL instructions count is masked 1923cdedef59SAnirudh Venkataramanan * to 5 bits so the shift will do nothing 1924cdedef59SAnirudh Venkataramanan */ 1925cdedef59SAnirudh Venkataramanan if (ce_info->width < 32) 1926cdedef59SAnirudh Venkataramanan mask = BIT(ce_info->width) - 1; 1927cdedef59SAnirudh Venkataramanan else 1928cdedef59SAnirudh Venkataramanan mask = (u32)~0; 1929cdedef59SAnirudh Venkataramanan 1930cdedef59SAnirudh Venkataramanan /* don't swizzle the bits until after the mask because the mask bits 1931cdedef59SAnirudh Venkataramanan * will be in a different bit position on big endian machines 1932cdedef59SAnirudh Venkataramanan */ 1933cdedef59SAnirudh Venkataramanan src_dword = *(u32 *)from; 1934cdedef59SAnirudh Venkataramanan src_dword &= mask; 1935cdedef59SAnirudh Venkataramanan 1936cdedef59SAnirudh Venkataramanan /* shift to correct alignment */ 1937cdedef59SAnirudh Venkataramanan mask <<= shift_width; 1938cdedef59SAnirudh Venkataramanan src_dword <<= shift_width; 1939cdedef59SAnirudh Venkataramanan 1940cdedef59SAnirudh Venkataramanan /* get the current bits from the target bit string */ 1941cdedef59SAnirudh Venkataramanan dest = dest_ctx + (ce_info->lsb / 8); 1942cdedef59SAnirudh Venkataramanan 1943cdedef59SAnirudh Venkataramanan memcpy(&dest_dword, dest, sizeof(dest_dword)); 1944cdedef59SAnirudh Venkataramanan 1945cdedef59SAnirudh Venkataramanan dest_dword &= ~(cpu_to_le32(mask)); /* get the bits not changing */ 1946cdedef59SAnirudh Venkataramanan dest_dword |= cpu_to_le32(src_dword); /* add in the new bits */ 1947cdedef59SAnirudh Venkataramanan 1948cdedef59SAnirudh Venkataramanan /* put it all back */ 1949cdedef59SAnirudh Venkataramanan memcpy(dest, &dest_dword, sizeof(dest_dword)); 1950cdedef59SAnirudh Venkataramanan } 1951cdedef59SAnirudh Venkataramanan 1952cdedef59SAnirudh Venkataramanan /** 1953cdedef59SAnirudh Venkataramanan * ice_write_qword - write a qword to a packed context structure 1954cdedef59SAnirudh Venkataramanan * @src_ctx: the context structure to read from 1955cdedef59SAnirudh Venkataramanan * @dest_ctx: the context to be written to 1956cdedef59SAnirudh Venkataramanan * @ce_info: a description of the struct to be filled 1957cdedef59SAnirudh Venkataramanan */ 1958cdedef59SAnirudh Venkataramanan static void ice_write_qword(u8 *src_ctx, u8 *dest_ctx, 1959cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele *ce_info) 1960cdedef59SAnirudh Venkataramanan { 1961cdedef59SAnirudh Venkataramanan u64 src_qword, mask; 1962cdedef59SAnirudh Venkataramanan __le64 dest_qword; 1963cdedef59SAnirudh Venkataramanan u8 *from, *dest; 1964cdedef59SAnirudh Venkataramanan u16 shift_width; 1965cdedef59SAnirudh Venkataramanan 1966cdedef59SAnirudh Venkataramanan /* copy from the next struct field */ 1967cdedef59SAnirudh Venkataramanan from = src_ctx + ce_info->offset; 1968cdedef59SAnirudh Venkataramanan 1969cdedef59SAnirudh Venkataramanan /* prepare the bits and mask */ 1970cdedef59SAnirudh Venkataramanan shift_width = ce_info->lsb % 8; 1971cdedef59SAnirudh Venkataramanan 1972cdedef59SAnirudh Venkataramanan /* if the field width is exactly 64 on an x86 machine, then the shift 1973cdedef59SAnirudh Venkataramanan * operation will not work because the SHL instructions count is masked 1974cdedef59SAnirudh Venkataramanan * to 6 bits so the shift will do nothing 1975cdedef59SAnirudh Venkataramanan */ 1976cdedef59SAnirudh Venkataramanan if (ce_info->width < 64) 1977cdedef59SAnirudh Venkataramanan mask = BIT_ULL(ce_info->width) - 1; 1978cdedef59SAnirudh Venkataramanan else 1979cdedef59SAnirudh Venkataramanan mask = (u64)~0; 1980cdedef59SAnirudh Venkataramanan 1981cdedef59SAnirudh Venkataramanan /* don't swizzle the bits until after the mask because the mask bits 1982cdedef59SAnirudh Venkataramanan * will be in a different bit position on big endian machines 1983cdedef59SAnirudh Venkataramanan */ 1984cdedef59SAnirudh Venkataramanan src_qword = *(u64 *)from; 1985cdedef59SAnirudh Venkataramanan src_qword &= mask; 1986cdedef59SAnirudh Venkataramanan 1987cdedef59SAnirudh Venkataramanan /* shift to correct alignment */ 1988cdedef59SAnirudh Venkataramanan mask <<= shift_width; 1989cdedef59SAnirudh Venkataramanan src_qword <<= shift_width; 1990cdedef59SAnirudh Venkataramanan 1991cdedef59SAnirudh Venkataramanan /* get the current bits from the target bit string */ 1992cdedef59SAnirudh Venkataramanan dest = dest_ctx + (ce_info->lsb / 8); 1993cdedef59SAnirudh Venkataramanan 1994cdedef59SAnirudh Venkataramanan memcpy(&dest_qword, dest, sizeof(dest_qword)); 1995cdedef59SAnirudh Venkataramanan 1996cdedef59SAnirudh Venkataramanan dest_qword &= ~(cpu_to_le64(mask)); /* get the bits not changing */ 1997cdedef59SAnirudh Venkataramanan dest_qword |= cpu_to_le64(src_qword); /* add in the new bits */ 1998cdedef59SAnirudh Venkataramanan 1999cdedef59SAnirudh Venkataramanan /* put it all back */ 2000cdedef59SAnirudh Venkataramanan memcpy(dest, &dest_qword, sizeof(dest_qword)); 2001cdedef59SAnirudh Venkataramanan } 2002cdedef59SAnirudh Venkataramanan 2003cdedef59SAnirudh Venkataramanan /** 2004cdedef59SAnirudh Venkataramanan * ice_set_ctx - set context bits in packed structure 2005cdedef59SAnirudh Venkataramanan * @src_ctx: pointer to a generic non-packed context structure 2006cdedef59SAnirudh Venkataramanan * @dest_ctx: pointer to memory for the packed structure 2007cdedef59SAnirudh Venkataramanan * @ce_info: a description of the structure to be transformed 2008cdedef59SAnirudh Venkataramanan */ 2009cdedef59SAnirudh Venkataramanan enum ice_status 2010cdedef59SAnirudh Venkataramanan ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) 2011cdedef59SAnirudh Venkataramanan { 2012cdedef59SAnirudh Venkataramanan int f; 2013cdedef59SAnirudh Venkataramanan 2014cdedef59SAnirudh Venkataramanan for (f = 0; ce_info[f].width; f++) { 2015cdedef59SAnirudh Venkataramanan /* We have to deal with each element of the FW response 2016cdedef59SAnirudh Venkataramanan * using the correct size so that we are correct regardless 2017cdedef59SAnirudh Venkataramanan * of the endianness of the machine. 2018cdedef59SAnirudh Venkataramanan */ 2019cdedef59SAnirudh Venkataramanan switch (ce_info[f].size_of) { 2020cdedef59SAnirudh Venkataramanan case sizeof(u8): 2021cdedef59SAnirudh Venkataramanan ice_write_byte(src_ctx, dest_ctx, &ce_info[f]); 2022cdedef59SAnirudh Venkataramanan break; 2023cdedef59SAnirudh Venkataramanan case sizeof(u16): 2024cdedef59SAnirudh Venkataramanan ice_write_word(src_ctx, dest_ctx, &ce_info[f]); 2025cdedef59SAnirudh Venkataramanan break; 2026cdedef59SAnirudh Venkataramanan case sizeof(u32): 2027cdedef59SAnirudh Venkataramanan ice_write_dword(src_ctx, dest_ctx, &ce_info[f]); 2028cdedef59SAnirudh Venkataramanan break; 2029cdedef59SAnirudh Venkataramanan case sizeof(u64): 2030cdedef59SAnirudh Venkataramanan ice_write_qword(src_ctx, dest_ctx, &ce_info[f]); 2031cdedef59SAnirudh Venkataramanan break; 2032cdedef59SAnirudh Venkataramanan default: 2033cdedef59SAnirudh Venkataramanan return ICE_ERR_INVAL_SIZE; 2034cdedef59SAnirudh Venkataramanan } 2035cdedef59SAnirudh Venkataramanan } 2036cdedef59SAnirudh Venkataramanan 2037cdedef59SAnirudh Venkataramanan return 0; 2038cdedef59SAnirudh Venkataramanan } 2039cdedef59SAnirudh Venkataramanan 2040cdedef59SAnirudh Venkataramanan /** 2041cdedef59SAnirudh Venkataramanan * ice_ena_vsi_txq 2042cdedef59SAnirudh Venkataramanan * @pi: port information structure 2043cdedef59SAnirudh Venkataramanan * @vsi_id: VSI id 2044cdedef59SAnirudh Venkataramanan * @tc: tc number 2045cdedef59SAnirudh Venkataramanan * @num_qgrps: Number of added queue groups 2046cdedef59SAnirudh Venkataramanan * @buf: list of queue groups to be added 2047cdedef59SAnirudh Venkataramanan * @buf_size: size of buffer for indirect command 2048cdedef59SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 2049cdedef59SAnirudh Venkataramanan * 2050cdedef59SAnirudh Venkataramanan * This function adds one lan q 2051cdedef59SAnirudh Venkataramanan */ 2052cdedef59SAnirudh Venkataramanan enum ice_status 2053cdedef59SAnirudh Venkataramanan ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps, 2054cdedef59SAnirudh Venkataramanan struct ice_aqc_add_tx_qgrp *buf, u16 buf_size, 2055cdedef59SAnirudh Venkataramanan struct ice_sq_cd *cd) 2056cdedef59SAnirudh Venkataramanan { 2057cdedef59SAnirudh Venkataramanan struct ice_aqc_txsched_elem_data node = { 0 }; 2058cdedef59SAnirudh Venkataramanan struct ice_sched_node *parent; 2059cdedef59SAnirudh Venkataramanan enum ice_status status; 2060cdedef59SAnirudh Venkataramanan struct ice_hw *hw; 2061cdedef59SAnirudh Venkataramanan 2062cdedef59SAnirudh Venkataramanan if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) 2063cdedef59SAnirudh Venkataramanan return ICE_ERR_CFG; 2064cdedef59SAnirudh Venkataramanan 2065cdedef59SAnirudh Venkataramanan if (num_qgrps > 1 || buf->num_txqs > 1) 2066cdedef59SAnirudh Venkataramanan return ICE_ERR_MAX_LIMIT; 2067cdedef59SAnirudh Venkataramanan 2068cdedef59SAnirudh Venkataramanan hw = pi->hw; 2069cdedef59SAnirudh Venkataramanan 2070cdedef59SAnirudh Venkataramanan mutex_lock(&pi->sched_lock); 2071cdedef59SAnirudh Venkataramanan 2072cdedef59SAnirudh Venkataramanan /* find a parent node */ 2073cdedef59SAnirudh Venkataramanan parent = ice_sched_get_free_qparent(pi, vsi_id, tc, 2074cdedef59SAnirudh Venkataramanan ICE_SCHED_NODE_OWNER_LAN); 2075cdedef59SAnirudh Venkataramanan if (!parent) { 2076cdedef59SAnirudh Venkataramanan status = ICE_ERR_PARAM; 2077cdedef59SAnirudh Venkataramanan goto ena_txq_exit; 2078cdedef59SAnirudh Venkataramanan } 2079cdedef59SAnirudh Venkataramanan buf->parent_teid = parent->info.node_teid; 2080cdedef59SAnirudh Venkataramanan node.parent_teid = parent->info.node_teid; 2081cdedef59SAnirudh Venkataramanan /* Mark that the values in the "generic" section as valid. The default 2082cdedef59SAnirudh Venkataramanan * value in the "generic" section is zero. This means that : 2083cdedef59SAnirudh Venkataramanan * - Scheduling mode is Bytes Per Second (BPS), indicated by Bit 0. 2084cdedef59SAnirudh Venkataramanan * - 0 priority among siblings, indicated by Bit 1-3. 2085cdedef59SAnirudh Venkataramanan * - WFQ, indicated by Bit 4. 2086cdedef59SAnirudh Venkataramanan * - 0 Adjustment value is used in PSM credit update flow, indicated by 2087cdedef59SAnirudh Venkataramanan * Bit 5-6. 2088cdedef59SAnirudh Venkataramanan * - Bit 7 is reserved. 2089cdedef59SAnirudh Venkataramanan * Without setting the generic section as valid in valid_sections, the 2090cdedef59SAnirudh Venkataramanan * Admin Q command will fail with error code ICE_AQ_RC_EINVAL. 2091cdedef59SAnirudh Venkataramanan */ 2092cdedef59SAnirudh Venkataramanan buf->txqs[0].info.valid_sections = ICE_AQC_ELEM_VALID_GENERIC; 2093cdedef59SAnirudh Venkataramanan 2094cdedef59SAnirudh Venkataramanan /* add the lan q */ 2095cdedef59SAnirudh Venkataramanan status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd); 2096cdedef59SAnirudh Venkataramanan if (status) 2097cdedef59SAnirudh Venkataramanan goto ena_txq_exit; 2098cdedef59SAnirudh Venkataramanan 2099cdedef59SAnirudh Venkataramanan node.node_teid = buf->txqs[0].q_teid; 2100cdedef59SAnirudh Venkataramanan node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF; 2101cdedef59SAnirudh Venkataramanan 2102cdedef59SAnirudh Venkataramanan /* add a leaf node into schduler tree q layer */ 2103cdedef59SAnirudh Venkataramanan status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node); 2104cdedef59SAnirudh Venkataramanan 2105cdedef59SAnirudh Venkataramanan ena_txq_exit: 2106cdedef59SAnirudh Venkataramanan mutex_unlock(&pi->sched_lock); 2107cdedef59SAnirudh Venkataramanan return status; 2108cdedef59SAnirudh Venkataramanan } 2109cdedef59SAnirudh Venkataramanan 2110cdedef59SAnirudh Venkataramanan /** 2111cdedef59SAnirudh Venkataramanan * ice_dis_vsi_txq 2112cdedef59SAnirudh Venkataramanan * @pi: port information structure 2113cdedef59SAnirudh Venkataramanan * @num_queues: number of queues 2114cdedef59SAnirudh Venkataramanan * @q_ids: pointer to the q_id array 2115cdedef59SAnirudh Venkataramanan * @q_teids: pointer to queue node teids 2116cdedef59SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 2117cdedef59SAnirudh Venkataramanan * 2118cdedef59SAnirudh Venkataramanan * This function removes queues and their corresponding nodes in SW DB 2119cdedef59SAnirudh Venkataramanan */ 2120cdedef59SAnirudh Venkataramanan enum ice_status 2121cdedef59SAnirudh Venkataramanan ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids, 2122cdedef59SAnirudh Venkataramanan u32 *q_teids, struct ice_sq_cd *cd) 2123cdedef59SAnirudh Venkataramanan { 2124cdedef59SAnirudh Venkataramanan enum ice_status status = ICE_ERR_DOES_NOT_EXIST; 2125cdedef59SAnirudh Venkataramanan struct ice_aqc_dis_txq_item qg_list; 2126cdedef59SAnirudh Venkataramanan u16 i; 2127cdedef59SAnirudh Venkataramanan 2128cdedef59SAnirudh Venkataramanan if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) 2129cdedef59SAnirudh Venkataramanan return ICE_ERR_CFG; 2130cdedef59SAnirudh Venkataramanan 2131cdedef59SAnirudh Venkataramanan mutex_lock(&pi->sched_lock); 2132cdedef59SAnirudh Venkataramanan 2133cdedef59SAnirudh Venkataramanan for (i = 0; i < num_queues; i++) { 2134cdedef59SAnirudh Venkataramanan struct ice_sched_node *node; 2135cdedef59SAnirudh Venkataramanan 2136cdedef59SAnirudh Venkataramanan node = ice_sched_find_node_by_teid(pi->root, q_teids[i]); 2137cdedef59SAnirudh Venkataramanan if (!node) 2138cdedef59SAnirudh Venkataramanan continue; 2139cdedef59SAnirudh Venkataramanan qg_list.parent_teid = node->info.parent_teid; 2140cdedef59SAnirudh Venkataramanan qg_list.num_qs = 1; 2141cdedef59SAnirudh Venkataramanan qg_list.q_id[0] = cpu_to_le16(q_ids[i]); 2142cdedef59SAnirudh Venkataramanan status = ice_aq_dis_lan_txq(pi->hw, 1, &qg_list, 2143cdedef59SAnirudh Venkataramanan sizeof(qg_list), cd); 2144cdedef59SAnirudh Venkataramanan 2145cdedef59SAnirudh Venkataramanan if (status) 2146cdedef59SAnirudh Venkataramanan break; 2147cdedef59SAnirudh Venkataramanan ice_free_sched_node(pi, node); 2148cdedef59SAnirudh Venkataramanan } 2149cdedef59SAnirudh Venkataramanan mutex_unlock(&pi->sched_lock); 2150cdedef59SAnirudh Venkataramanan return status; 2151cdedef59SAnirudh Venkataramanan } 21525513b920SAnirudh Venkataramanan 21535513b920SAnirudh Venkataramanan /** 21545513b920SAnirudh Venkataramanan * ice_cfg_vsi_qs - configure the new/exisiting VSI queues 21555513b920SAnirudh Venkataramanan * @pi: port information structure 21565513b920SAnirudh Venkataramanan * @vsi_id: VSI Id 21575513b920SAnirudh Venkataramanan * @tc_bitmap: TC bitmap 21585513b920SAnirudh Venkataramanan * @maxqs: max queues array per TC 21595513b920SAnirudh Venkataramanan * @owner: lan or rdma 21605513b920SAnirudh Venkataramanan * 21615513b920SAnirudh Venkataramanan * This function adds/updates the VSI queues per TC. 21625513b920SAnirudh Venkataramanan */ 21635513b920SAnirudh Venkataramanan static enum ice_status 21645513b920SAnirudh Venkataramanan ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap, 21655513b920SAnirudh Venkataramanan u16 *maxqs, u8 owner) 21665513b920SAnirudh Venkataramanan { 21675513b920SAnirudh Venkataramanan enum ice_status status = 0; 21685513b920SAnirudh Venkataramanan u8 i; 21695513b920SAnirudh Venkataramanan 21705513b920SAnirudh Venkataramanan if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) 21715513b920SAnirudh Venkataramanan return ICE_ERR_CFG; 21725513b920SAnirudh Venkataramanan 21735513b920SAnirudh Venkataramanan mutex_lock(&pi->sched_lock); 21745513b920SAnirudh Venkataramanan 21755513b920SAnirudh Venkataramanan for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) { 21765513b920SAnirudh Venkataramanan /* configuration is possible only if TC node is present */ 21775513b920SAnirudh Venkataramanan if (!ice_sched_get_tc_node(pi, i)) 21785513b920SAnirudh Venkataramanan continue; 21795513b920SAnirudh Venkataramanan 21805513b920SAnirudh Venkataramanan status = ice_sched_cfg_vsi(pi, vsi_id, i, maxqs[i], owner, 21815513b920SAnirudh Venkataramanan ice_is_tc_ena(tc_bitmap, i)); 21825513b920SAnirudh Venkataramanan if (status) 21835513b920SAnirudh Venkataramanan break; 21845513b920SAnirudh Venkataramanan } 21855513b920SAnirudh Venkataramanan 21865513b920SAnirudh Venkataramanan mutex_unlock(&pi->sched_lock); 21875513b920SAnirudh Venkataramanan return status; 21885513b920SAnirudh Venkataramanan } 21895513b920SAnirudh Venkataramanan 21905513b920SAnirudh Venkataramanan /** 21915513b920SAnirudh Venkataramanan * ice_cfg_vsi_lan - configure VSI lan queues 21925513b920SAnirudh Venkataramanan * @pi: port information structure 21935513b920SAnirudh Venkataramanan * @vsi_id: VSI Id 21945513b920SAnirudh Venkataramanan * @tc_bitmap: TC bitmap 21955513b920SAnirudh Venkataramanan * @max_lanqs: max lan queues array per TC 21965513b920SAnirudh Venkataramanan * 21975513b920SAnirudh Venkataramanan * This function adds/updates the VSI lan queues per TC. 21985513b920SAnirudh Venkataramanan */ 21995513b920SAnirudh Venkataramanan enum ice_status 22005513b920SAnirudh Venkataramanan ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap, 22015513b920SAnirudh Venkataramanan u16 *max_lanqs) 22025513b920SAnirudh Venkataramanan { 22035513b920SAnirudh Venkataramanan return ice_cfg_vsi_qs(pi, vsi_id, tc_bitmap, max_lanqs, 22045513b920SAnirudh Venkataramanan ICE_SCHED_NODE_OWNER_LAN); 22055513b920SAnirudh Venkataramanan } 2206