diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_common.c')
| -rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_common.c | 361 | 
1 files changed, 282 insertions, 79 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 11a9ffebf8d8..0bae22da014d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1,7 +1,7 @@  /*******************************************************************************   *   * Intel Ethernet Controller XL710 Family Linux Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation.   *   * This program is free software; you can redistribute it and/or modify it   * under the terms and conditions of the GNU General Public License, @@ -51,6 +51,7 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)  		case I40E_DEV_ID_QSFP_B:  		case I40E_DEV_ID_QSFP_C:  		case I40E_DEV_ID_10G_BASE_T: +		case I40E_DEV_ID_20G_KR2:  			hw->mac.type = I40E_MAC_XL710;  			break;  		case I40E_DEV_ID_VF: @@ -85,46 +86,53 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,  {  	struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;  	u16 len = le16_to_cpu(aq_desc->datalen); -	u8 *aq_buffer = (u8 *)buffer; -	u32 data[4]; -	u32 i = 0; +	u8 *buf = (u8 *)buffer; +	u16 i = 0;  	if ((!(mask & hw->debug_mask)) || (desc == NULL))  		return;  	i40e_debug(hw, mask,  		   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n", -		   aq_desc->opcode, aq_desc->flags, aq_desc->datalen, -		   aq_desc->retval); +		   le16_to_cpu(aq_desc->opcode), +		   le16_to_cpu(aq_desc->flags), +		   le16_to_cpu(aq_desc->datalen), +		   le16_to_cpu(aq_desc->retval));  	i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n", -		   aq_desc->cookie_high, aq_desc->cookie_low); +		   le32_to_cpu(aq_desc->cookie_high), +		   le32_to_cpu(aq_desc->cookie_low));  	i40e_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n", -		   aq_desc->params.internal.param0, -		   aq_desc->params.internal.param1); +		   le32_to_cpu(aq_desc->params.internal.param0), +		   le32_to_cpu(aq_desc->params.internal.param1));  	i40e_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n", -		   aq_desc->params.external.addr_high, -		   aq_desc->params.external.addr_low); +		   le32_to_cpu(aq_desc->params.external.addr_high), +		   le32_to_cpu(aq_desc->params.external.addr_low));  	if ((buffer != NULL) && (aq_desc->datalen != 0)) { -		memset(data, 0, sizeof(data));  		i40e_debug(hw, mask, "AQ CMD Buffer:\n");  		if (buf_len < len)  			len = buf_len; -		for (i = 0; i < len; i++) { -			data[((i % 16) / 4)] |= -				((u32)aq_buffer[i]) << (8 * (i % 4)); -			if ((i % 16) == 15) { -				i40e_debug(hw, mask, -					   "\t0x%04X  %08X %08X %08X %08X\n", -					   i - 15, data[0], data[1], data[2], -					   data[3]); -				memset(data, 0, sizeof(data)); -			} +		/* write the full 16-byte chunks */ +		for (i = 0; i < (len - 16); i += 16) +			i40e_debug(hw, mask, +				   "\t0x%04X  %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", +				   i, buf[i], buf[i + 1], buf[i + 2], +				   buf[i + 3], buf[i + 4], buf[i + 5], +				   buf[i + 6], buf[i + 7], buf[i + 8], +				   buf[i + 9], buf[i + 10], buf[i + 11], +				   buf[i + 12], buf[i + 13], buf[i + 14], +				   buf[i + 15]); +		/* write whatever's left over without overrunning the buffer */ +		if (i < len) { +			char d_buf[80]; +			int j = 0; + +			memset(d_buf, 0, sizeof(d_buf)); +			j += sprintf(d_buf, "\t0x%04X ", i); +			while (i < len) +				j += sprintf(&d_buf[j], " %02X", buf[i++]); +			i40e_debug(hw, mask, "%s\n", d_buf);  		} -		if ((i % 16) != 0) -			i40e_debug(hw, mask, "\t0x%04X  %08X %08X %08X %08X\n", -				   i - (i % 16), data[0], data[1], data[2], -				   data[3]);  	}  } @@ -534,7 +542,6 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {  	I40E_PTT_UNUSED_ENTRY(255)  }; -  /**   * i40e_init_shared_code - Initialize the shared code   * @hw: pointer to hardware structure @@ -685,7 +692,7 @@ i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)  /**   * i40e_pre_tx_queue_cfg - pre tx queue configure   * @hw: pointer to the HW structure - * @queue: target pf queue index + * @queue: target PF queue index   * @enable: state change request   *   * Handles hw requirement to indicate intention to enable @@ -827,12 +834,15 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)  	case I40E_PHY_TYPE_10GBASE_CR1:  	case I40E_PHY_TYPE_40GBASE_CR4:  	case I40E_PHY_TYPE_10GBASE_SFPP_CU: +	case I40E_PHY_TYPE_40GBASE_AOC: +	case I40E_PHY_TYPE_10GBASE_AOC:  		media = I40E_MEDIA_TYPE_DA;  		break;  	case I40E_PHY_TYPE_1000BASE_KX:  	case I40E_PHY_TYPE_10GBASE_KX4:  	case I40E_PHY_TYPE_10GBASE_KR:  	case I40E_PHY_TYPE_40GBASE_KR4: +	case I40E_PHY_TYPE_20GBASE_KR2:  		media = I40E_MEDIA_TYPE_BACKPLANE;  		break;  	case I40E_PHY_TYPE_SGMII: @@ -849,7 +859,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)  }  #define I40E_PF_RESET_WAIT_COUNT_A0	200 -#define I40E_PF_RESET_WAIT_COUNT	110 +#define I40E_PF_RESET_WAIT_COUNT	200  /**   * i40e_pf_reset - Reset the PF   * @hw: pointer to the hardware structure @@ -868,8 +878,9 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)  	 * The grst delay value is in 100ms units, and we'll wait a  	 * couple counts longer to be sure we don't just miss the end.  	 */ -	grst_del = rd32(hw, I40E_GLGEN_RSTCTL) & I40E_GLGEN_RSTCTL_GRSTDEL_MASK -			>> I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT; +	grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) & +		    I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >> +		    I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;  	for (cnt = 0; cnt < grst_del + 2; cnt++) {  		reg = rd32(hw, I40E_GLGEN_RSTAT);  		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) @@ -946,7 +957,7 @@ void i40e_clear_hw(struct i40e_hw *hw)  	u32 val;  	u32 eol = 0x7ff; -	/* get number of interrupts, queues, and vfs */ +	/* get number of interrupts, queues, and VFs */  	val = rd32(hw, I40E_GLPCI_CNF2);  	num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>  		     I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT; @@ -1075,8 +1086,11 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)  	return gpio_val;  } -#define I40E_LED0 22 +#define I40E_COMBINED_ACTIVITY 0xA +#define I40E_FILTER_ACTIVITY 0xE  #define I40E_LINK_ACTIVITY 0xC +#define I40E_MAC_ACTIVITY 0xD +#define I40E_LED0 22  /**   * i40e_led_get - return current on/off mode @@ -1089,6 +1103,7 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)   **/  u32 i40e_led_get(struct i40e_hw *hw)  { +	u32 current_mode = 0;  	u32 mode = 0;  	int i; @@ -1101,6 +1116,20 @@ u32 i40e_led_get(struct i40e_hw *hw)  		if (!gpio_val)  			continue; +		/* ignore gpio LED src mode entries related to the activity +		 * LEDs +		 */ +		current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) +				>> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); +		switch (current_mode) { +		case I40E_COMBINED_ACTIVITY: +		case I40E_FILTER_ACTIVITY: +		case I40E_MAC_ACTIVITY: +			continue; +		default: +			break; +		} +  		mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>  			I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;  		break; @@ -1120,6 +1149,7 @@ u32 i40e_led_get(struct i40e_hw *hw)   **/  void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)  { +	u32 current_mode = 0;  	int i;  	if (mode & 0xfffffff0) @@ -1134,6 +1164,20 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)  		if (!gpio_val)  			continue; +		/* ignore gpio LED src mode entries related to the activity +		 * LEDs +		 */ +		current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) +				>> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); +		switch (current_mode) { +		case I40E_COMBINED_ACTIVITY: +		case I40E_FILTER_ACTIVITY: +		case I40E_MAC_ACTIVITY: +			continue; +		default: +			break; +		} +  		gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;  		/* this & is a bit of paranoia, but serves as a range check */  		gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) & @@ -1297,14 +1341,14 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,  			*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;  	}  	/* Update the link info */ -	status = i40e_update_link_info(hw, true); +	status = i40e_aq_get_link_info(hw, true, NULL, NULL);  	if (status) {  		/* Wait a little bit (on 40G cards it sometimes takes a really  		 * long time for link to come back from the atomic reset)  		 * and try once more  		 */  		msleep(1000); -		status = i40e_update_link_info(hw, true); +		status = i40e_aq_get_link_info(hw, true, NULL, NULL);  	}  	if (status)  		*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE; @@ -1440,6 +1484,10 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,  	else  		hw_link_info->lse_enable = false; +	if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 && +	     hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE) +		hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU; +  	/* save link status information */  	if (link)  		*link = *hw_link_info; @@ -1452,35 +1500,6 @@ aq_get_link_info_exit:  }  /** - * i40e_update_link_info - * @hw: pointer to the hw struct - * @enable_lse: enable/disable LinkStatusEvent reporting - * - * Returns the link status of the adapter - **/ -i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse) -{ -	struct i40e_aq_get_phy_abilities_resp abilities; -	i40e_status status; - -	status = i40e_aq_get_link_info(hw, enable_lse, NULL, NULL); -	if (status) -		return status; - -	status = i40e_aq_get_phy_capabilities(hw, false, false, -					      &abilities, NULL); -	if (status) -		return status; - -	if (abilities.abilities & I40E_AQ_PHY_AN_ENABLED) -		hw->phy.link_info.an_enabled = true; -	else -		hw->phy.link_info.an_enabled = false; - -	return status; -} - -/**   * i40e_aq_set_phy_int_mask   * @hw: pointer to the hw struct   * @mask: interrupt mask to be set @@ -1759,6 +1778,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,   * @hw: pointer to the hw struct   * @fw_major_version: firmware major version   * @fw_minor_version: firmware minor version + * @fw_build: firmware build number   * @api_major_version: major queue version   * @api_minor_version: minor queue version   * @cmd_details: pointer to command details structure or NULL @@ -1767,6 +1787,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,   **/  i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,  				u16 *fw_major_version, u16 *fw_minor_version, +				u32 *fw_build,  				u16 *api_major_version, u16 *api_minor_version,  				struct i40e_asq_cmd_details *cmd_details)  { @@ -1780,13 +1801,15 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,  	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);  	if (!status) { -		if (fw_major_version != NULL) +		if (fw_major_version)  			*fw_major_version = le16_to_cpu(resp->fw_major); -		if (fw_minor_version != NULL) +		if (fw_minor_version)  			*fw_minor_version = le16_to_cpu(resp->fw_minor); -		if (api_major_version != NULL) +		if (fw_build) +			*fw_build = le32_to_cpu(resp->fw_build); +		if (api_major_version)  			*api_major_version = le16_to_cpu(resp->api_major); -		if (api_minor_version != NULL) +		if (api_minor_version)  			*api_minor_version = le16_to_cpu(resp->api_minor);  	} @@ -1816,7 +1839,7 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,  	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version); -	desc.flags |= cpu_to_le16(I40E_AQ_FLAG_SI); +	desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);  	cmd->driver_major_ver = dv->major_version;  	cmd->driver_minor_ver = dv->minor_version;  	cmd->driver_build_ver = dv->build_version; @@ -1996,7 +2019,7 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,  	if (count == 0 || !mv_list || !hw)  		return I40E_ERR_PARAM; -	buf_size = count * sizeof(struct i40e_aqc_add_macvlan_element_data); +	buf_size = count * sizeof(*mv_list);  	/* prep the rest of the request */  	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan); @@ -2038,7 +2061,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,  	if (count == 0 || !mv_list || !hw)  		return I40E_ERR_PARAM; -	buf_size = count * sizeof(struct i40e_aqc_remove_macvlan_element_data); +	buf_size = count * sizeof(*mv_list);  	/* prep the rest of the request */  	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan); @@ -2060,7 +2083,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,  /**   * i40e_aq_send_msg_to_vf   * @hw: pointer to the hardware structure - * @vfid: vf id to send msg + * @vfid: VF id to send msg   * @v_opcode: opcodes for VF-PF communication   * @v_retval: return error code   * @msg: pointer to the msg buffer @@ -2105,7 +2128,7 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,   * Read the register using the admin queue commands   **/  i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw, -				u32  reg_addr, u64 *reg_val, +				u32 reg_addr, u64 *reg_val,  				struct i40e_asq_cmd_details *cmd_details)  {  	struct i40e_aq_desc desc; @@ -2116,17 +2139,15 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,  	if (reg_val == NULL)  		return I40E_ERR_PARAM; -	i40e_fill_default_direct_cmd_desc(&desc, -					  i40e_aqc_opc_debug_read_reg); +	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);  	cmd_resp->address = cpu_to_le32(reg_addr);  	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);  	if (!status) { -		*reg_val = ((u64)cmd_resp->value_high << 32) | -			    (u64)cmd_resp->value_low; -		*reg_val = le64_to_cpu(*reg_val); +		*reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) | +			   (u64)le32_to_cpu(cmd_resp->value_low);  	}  	return status; @@ -2376,6 +2397,7 @@ i40e_aq_erase_nvm_exit:  #define I40E_DEV_FUNC_CAP_LED		0x61  #define I40E_DEV_FUNC_CAP_SDP		0x62  #define I40E_DEV_FUNC_CAP_MDIO		0x63 +#define I40E_DEV_FUNC_CAP_WR_CSR_PROT	0x64  /**   * i40e_parse_discover_capabilities @@ -2520,11 +2542,18 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,  			p->fd_filters_guaranteed = number;  			p->fd_filters_best_effort = logical_id;  			break; +		case I40E_DEV_FUNC_CAP_WR_CSR_PROT: +			p->wr_csr_prot = (u64)number; +			p->wr_csr_prot |= (u64)logical_id << 32; +			break;  		default:  			break;  		}  	} +	if (p->fcoe) +		i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n"); +  	/* Software override ensuring FCoE is disabled if npar or mfp  	 * mode because it is not supported in these modes.  	 */ @@ -2846,7 +2875,7 @@ i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,  	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); -	if (!status) +	if (!status && filter_index)  		*filter_index = resp->index;  	return status; @@ -3376,6 +3405,47 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,  }  /** + * i40e_aq_alternate_read + * @hw: pointer to the hardware structure + * @reg_addr0: address of first dword to be read + * @reg_val0: pointer for data read from 'reg_addr0' + * @reg_addr1: address of second dword to be read + * @reg_val1: pointer for data read from 'reg_addr1' + * + * Read one or two dwords from alternate structure. Fields are indicated + * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer + * is not passed then only register at 'reg_addr0' is read. + * + **/ +static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw, +					  u32 reg_addr0, u32 *reg_val0, +					  u32 reg_addr1, u32 *reg_val1) +{ +	struct i40e_aq_desc desc; +	struct i40e_aqc_alternate_write *cmd_resp = +		(struct i40e_aqc_alternate_write *)&desc.params.raw; +	i40e_status status; + +	if (!reg_val0) +		return I40E_ERR_PARAM; + +	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read); +	cmd_resp->address0 = cpu_to_le32(reg_addr0); +	cmd_resp->address1 = cpu_to_le32(reg_addr1); + +	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL); + +	if (!status) { +		*reg_val0 = le32_to_cpu(cmd_resp->data0); + +		if (reg_val1) +			*reg_val1 = le32_to_cpu(cmd_resp->data1); +	} + +	return status; +} + +/**   * i40e_aq_resume_port_tx   * @hw: pointer to the hardware structure   * @cmd_details: pointer to command details structure or NULL @@ -3439,3 +3509,136 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)  		break;  	}  } + +/** + * i40e_aq_debug_dump + * @hw: pointer to the hardware structure + * @cluster_id: specific cluster to dump + * @table_id: table id within cluster + * @start_index: index of line in the block to read + * @buff_size: dump buffer size + * @buff: dump buffer + * @ret_buff_size: actual buffer size returned + * @ret_next_table: next block to read + * @ret_next_index: next index to read + * + * Dump internal FW/HW data for debug purposes. + * + **/ +i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id, +			       u8 table_id, u32 start_index, u16 buff_size, +			       void *buff, u16 *ret_buff_size, +			       u8 *ret_next_table, u32 *ret_next_index, +			       struct i40e_asq_cmd_details *cmd_details) +{ +	struct i40e_aq_desc desc; +	struct i40e_aqc_debug_dump_internals *cmd = +		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw; +	struct i40e_aqc_debug_dump_internals *resp = +		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw; +	i40e_status status; + +	if (buff_size == 0 || !buff) +		return I40E_ERR_PARAM; + +	i40e_fill_default_direct_cmd_desc(&desc, +					  i40e_aqc_opc_debug_dump_internals); +	/* Indirect Command */ +	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF); +	if (buff_size > I40E_AQ_LARGE_BUF) +		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB); + +	cmd->cluster_id = cluster_id; +	cmd->table_id = table_id; +	cmd->idx = cpu_to_le32(start_index); + +	desc.datalen = cpu_to_le16(buff_size); + +	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); +	if (!status) { +		if (ret_buff_size) +			*ret_buff_size = le16_to_cpu(desc.datalen); +		if (ret_next_table) +			*ret_next_table = resp->table_id; +		if (ret_next_index) +			*ret_next_index = le32_to_cpu(resp->idx); +	} + +	return status; +} + +/** + * i40e_read_bw_from_alt_ram + * @hw: pointer to the hardware structure + * @max_bw: pointer for max_bw read + * @min_bw: pointer for min_bw read + * @min_valid: pointer for bool that is true if min_bw is a valid value + * @max_valid: pointer for bool that is true if max_bw is a valid value + * + * Read bw from the alternate ram for the given pf + **/ +i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw, +				      u32 *max_bw, u32 *min_bw, +				      bool *min_valid, bool *max_valid) +{ +	i40e_status status; +	u32 max_bw_addr, min_bw_addr; + +	/* Calculate the address of the min/max bw registers */ +	max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET + +		      I40E_ALT_STRUCT_MAX_BW_OFFSET + +		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id); +	min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET + +		      I40E_ALT_STRUCT_MIN_BW_OFFSET + +		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id); + +	/* Read the bandwidths from alt ram */ +	status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw, +					min_bw_addr, min_bw); + +	if (*min_bw & I40E_ALT_BW_VALID_MASK) +		*min_valid = true; +	else +		*min_valid = false; + +	if (*max_bw & I40E_ALT_BW_VALID_MASK) +		*max_valid = true; +	else +		*max_valid = false; + +	return status; +} + +/** + * i40e_aq_configure_partition_bw + * @hw: pointer to the hardware structure + * @bw_data: Buffer holding valid pfs and bw limits + * @cmd_details: pointer to command details + * + * Configure partitions guaranteed/max bw + **/ +i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw, +			struct i40e_aqc_configure_partition_bw_data *bw_data, +			struct i40e_asq_cmd_details *cmd_details) +{ +	i40e_status status; +	struct i40e_aq_desc desc; +	u16 bwd_size = sizeof(*bw_data); + +	i40e_fill_default_direct_cmd_desc(&desc, +					  i40e_aqc_opc_configure_partition_bw); + +	/* Indirect command */ +	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF); +	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD); + +	if (bwd_size > I40E_AQ_LARGE_BUF) +		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB); + +	desc.datalen = cpu_to_le16(bwd_size); + +	status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, +				       cmd_details); + +	return status; +}  |