Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfa2eb86 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-02-19

This series contains updates to i40e/i40evf only.

Alex Duyck splits up the descriptor count function from the function that
stops the ring to have access to the descriptor count used for the data
portion of the frame.  The rewrites the logic for how we determine if we
can transmit the frame or if it needs to be linearized.  Place the checksum
close to TSO since they have a lot in common and it can help to reduce the
decision tree for how to handle the frame as the first check in TSO is to
see if checksumming is offloaded.

Carolyn adds functions to blink leds on devices using 10GBaseT PHY since
MAC registers used in other designs do not work in this device configuration.
Fixes an issue where a previously removed message has returned.

Kevin increases the timeout when checking GLGEN_RSTAT_DEVSTATE bit since
linking with particular PHY types, the amount of time it takes for the
GLGEN_RSTAT_DEVSTATE to be set increases greatly.

Neerav changes the receive queues to not wait to be disabled before DCB
has been reconfigured, like transmit queues.

Anjali adds new register definitions for programming the parser, flow
director and RSS blocks in the hardware.

Shannon adds the new opcodes and structures used for asking the firmware
to update receive control registers that need extra care when being
accessed while under heavy traffic.  Integrates the new AdminQ functions
for safely accessing the receive control registers that may be affected
by heavy small packet traffic.

Mitch provides another colorful patch description on letting go of
the stale local VSI pointer when the VF resets.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d289cbed b8f1343a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@
#define I40E_OEM_VER_PATCH_MASK    0xff
#define I40E_OEM_VER_BUILD_SHIFT   8
#define I40E_OEM_VER_SHIFT         24
#define I40E_PHY_DEBUG_PORT        BIT(4)

/* The values in here are decimal coded as hex as is the case in the NVM map*/
#define I40E_CURRENT_NVM_VERSION_HI 0x2
@@ -355,6 +356,7 @@ struct i40e_pf {
#define I40E_FLAG_NO_DCB_SUPPORT		BIT_ULL(45)
#define I40E_FLAG_USE_SET_LLDP_MIB		BIT_ULL(46)
#define I40E_FLAG_STOP_FW_LLDP			BIT_ULL(47)
#define I40E_FLAG_HAVE_10GBASET_PHY		BIT_ULL(48)
#define I40E_FLAG_PF_MAC			BIT_ULL(50)

	/* tracks features that get auto disabled by errors */
@@ -440,6 +442,7 @@ struct i40e_pf {

	u32 ioremap_len;
	u32 fd_inv;
	u16 phy_led_val;
};

struct i40e_mac_filter {
+16 −0
Original line number Diff line number Diff line
@@ -146,6 +146,8 @@ enum i40e_admin_queue_opc {
	i40e_aqc_opc_set_port_parameters	= 0x0203,
	i40e_aqc_opc_get_switch_resource_alloc	= 0x0204,
	i40e_aqc_opc_set_switch_config		= 0x0205,
	i40e_aqc_opc_rx_ctl_reg_read		= 0x0206,
	i40e_aqc_opc_rx_ctl_reg_write		= 0x0207,

	i40e_aqc_opc_add_vsi			= 0x0210,
	i40e_aqc_opc_update_vsi_parameters	= 0x0211,
@@ -696,6 +698,20 @@ struct i40e_aqc_set_switch_config {

I40E_CHECK_CMD_LENGTH(i40e_aqc_set_switch_config);

/* Read Receive control registers  (direct 0x0206)
 * Write Receive control registers (direct 0x0207)
 *     used for accessing Rx control registers that can be
 *     slow and need special handling when under high Rx load
 */
struct i40e_aqc_rx_ctl_reg_read_write {
	__le32 reserved1;
	__le32 address;
	__le32 reserved2;
	__le32 value;
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_rx_ctl_reg_read_write);

/* Add VSI (indirect 0x0210)
 *    this indirect command uses struct i40e_aqc_vsi_properties_data
 *    as the indirect buffer (128 bytes)
+486 −3
Original line number Diff line number Diff line
@@ -1239,7 +1239,13 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
	grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
		    I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
		    I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
	for (cnt = 0; cnt < grst_del + 10; cnt++) {

	/* It can take upto 15 secs for GRST steady state.
	 * Bump it to 16 secs max to be safe.
	 */
	grst_del = grst_del * 20;

	for (cnt = 0; cnt < grst_del; cnt++) {
		reg = rd32(hw, I40E_GLGEN_RSTAT);
		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
			break;
@@ -1887,6 +1893,32 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
	return status;
}

/**
 * i40e_aq_set_phy_debug
 * @hw: pointer to the hw struct
 * @cmd_flags: debug command flags
 * @cmd_details: pointer to command details structure or NULL
 *
 * Reset the external PHY.
 **/
enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
					struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_set_phy_debug *cmd =
		(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
	enum i40e_status_code status;

	i40e_fill_default_direct_cmd_desc(&desc,
					  i40e_aqc_opc_set_phy_debug);

	cmd->command_flags = cmd_flags;

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
}

/**
 * i40e_aq_add_vsi
 * @hw: pointer to the hw struct
@@ -3850,7 +3882,7 @@ i40e_status i40e_set_filter_control(struct i40e_hw *hw,
		return ret;

	/* Read the PF Queue Filter control register */
	val = rd32(hw, I40E_PFQF_CTL_0);
	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);

	/* Program required PE hash buckets for the PF */
	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
@@ -3887,7 +3919,7 @@ i40e_status i40e_set_filter_control(struct i40e_hw *hw,
	if (settings->enable_macvlan)
		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;

	wr32(hw, I40E_PFQF_CTL_0, val);
	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);

	return 0;
}
@@ -4214,3 +4246,454 @@ i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,

	return status;
}

/**
 * i40e_read_phy_register
 * @hw: pointer to the HW structure
 * @page: registers page number
 * @reg: register address in the page
 * @phy_adr: PHY address on MDIO interface
 * @value: PHY register value
 *
 * Reads specified PHY register value
 **/
i40e_status i40e_read_phy_register(struct i40e_hw *hw,
				   u8 page, u16 reg, u8 phy_addr,
				   u16 *value)
{
	i40e_status status = I40E_ERR_TIMEOUT;
	u32 command = 0;
	u16 retry = 1000;
	u8 port_num = hw->func_caps.mdio_port_num;

	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
		  (I40E_MDIO_OPCODE_ADDRESS) |
		  (I40E_MDIO_STCODE) |
		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
	do {
		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
			status = 0;
			break;
		}
		usleep_range(10, 20);
		retry--;
	} while (retry);

	if (status) {
		i40e_debug(hw, I40E_DEBUG_PHY,
			   "PHY: Can't write command to external PHY.\n");
		goto phy_read_end;
	}

	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
		  (I40E_MDIO_OPCODE_READ) |
		  (I40E_MDIO_STCODE) |
		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
	status = I40E_ERR_TIMEOUT;
	retry = 1000;
	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
	do {
		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
			status = 0;
			break;
		}
		usleep_range(10, 20);
		retry--;
	} while (retry);

	if (!status) {
		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
	} else {
		i40e_debug(hw, I40E_DEBUG_PHY,
			   "PHY: Can't read register value from external PHY.\n");
	}

phy_read_end:
	return status;
}

/**
 * i40e_write_phy_register
 * @hw: pointer to the HW structure
 * @page: registers page number
 * @reg: register address in the page
 * @phy_adr: PHY address on MDIO interface
 * @value: PHY register value
 *
 * Writes value to specified PHY register
 **/
i40e_status i40e_write_phy_register(struct i40e_hw *hw,
				    u8 page, u16 reg, u8 phy_addr,
				    u16 value)
{
	i40e_status status = I40E_ERR_TIMEOUT;
	u32 command = 0;
	u16 retry = 1000;
	u8 port_num = hw->func_caps.mdio_port_num;

	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
		  (I40E_MDIO_OPCODE_ADDRESS) |
		  (I40E_MDIO_STCODE) |
		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
	do {
		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
			status = 0;
			break;
		}
		usleep_range(10, 20);
		retry--;
	} while (retry);
	if (status) {
		i40e_debug(hw, I40E_DEBUG_PHY,
			   "PHY: Can't write command to external PHY.\n");
		goto phy_write_end;
	}

	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);

	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
		  (I40E_MDIO_OPCODE_WRITE) |
		  (I40E_MDIO_STCODE) |
		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
	status = I40E_ERR_TIMEOUT;
	retry = 1000;
	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
	do {
		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
			status = 0;
			break;
		}
		usleep_range(10, 20);
		retry--;
	} while (retry);

phy_write_end:
	return status;
}

/**
 * i40e_get_phy_address
 * @hw: pointer to the HW structure
 * @dev_num: PHY port num that address we want
 * @phy_addr: Returned PHY address
 *
 * Gets PHY address for current port
 **/
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
{
	u8 port_num = hw->func_caps.mdio_port_num;
	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));

	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
}

/**
 * i40e_blink_phy_led
 * @hw: pointer to the HW structure
 * @time: time how long led will blinks in secs
 * @interval: gap between LED on and off in msecs
 *
 * Blinks PHY link LED
 **/
i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
				    u32 time, u32 interval)
{
	i40e_status status = 0;
	u32 i;
	u16 led_ctl;
	u16 gpio_led_port;
	u16 led_reg;
	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
	u8 phy_addr = 0;
	u8 port_num;

	i = rd32(hw, I40E_PFGEN_PORTNUM);
	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
	phy_addr = i40e_get_phy_address(hw, port_num);

	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
	     led_addr++) {
		status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
						led_addr, phy_addr, &led_reg);
		if (status)
			goto phy_blinking_end;
		led_ctl = led_reg;
		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
			led_reg = 0;
			status = i40e_write_phy_register(hw,
							 I40E_PHY_COM_REG_PAGE,
							 led_addr, phy_addr,
							 led_reg);
			if (status)
				goto phy_blinking_end;
			break;
		}
	}

	if (time > 0 && interval > 0) {
		for (i = 0; i < time * 1000; i += interval) {
			status = i40e_read_phy_register(hw,
							I40E_PHY_COM_REG_PAGE,
							led_addr, phy_addr,
							&led_reg);
			if (status)
				goto restore_config;
			if (led_reg & I40E_PHY_LED_MANUAL_ON)
				led_reg = 0;
			else
				led_reg = I40E_PHY_LED_MANUAL_ON;
			status = i40e_write_phy_register(hw,
							 I40E_PHY_COM_REG_PAGE,
							 led_addr, phy_addr,
							 led_reg);
			if (status)
				goto restore_config;
			msleep(interval);
		}
	}

restore_config:
	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
					 phy_addr, led_ctl);

phy_blinking_end:
	return status;
}

/**
 * i40e_led_get_phy - return current on/off mode
 * @hw: pointer to the hw struct
 * @led_addr: address of led register to use
 * @val: original value of register to use
 *
 **/
i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
			     u16 *val)
{
	i40e_status status = 0;
	u16 gpio_led_port;
	u8 phy_addr = 0;
	u16 reg_val;
	u16 temp_addr;
	u8 port_num;
	u32 i;

	temp_addr = I40E_PHY_LED_PROV_REG_1;
	i = rd32(hw, I40E_PFGEN_PORTNUM);
	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
	phy_addr = i40e_get_phy_address(hw, port_num);

	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
	     temp_addr++) {
		status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
						temp_addr, phy_addr, &reg_val);
		if (status)
			return status;
		*val = reg_val;
		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
			*led_addr = temp_addr;
			break;
		}
	}
	return status;
}

/**
 * i40e_led_set_phy
 * @hw: pointer to the HW structure
 * @on: true or false
 * @mode: original val plus bit for set or ignore
 * Set led's on or off when controlled by the PHY
 *
 **/
i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
			     u16 led_addr, u32 mode)
{
	i40e_status status = 0;
	u16 led_ctl = 0;
	u16 led_reg = 0;
	u8 phy_addr = 0;
	u8 port_num;
	u32 i;

	i = rd32(hw, I40E_PFGEN_PORTNUM);
	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
	phy_addr = i40e_get_phy_address(hw, port_num);

	status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
					phy_addr, &led_reg);
	if (status)
		return status;
	led_ctl = led_reg;
	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
		led_reg = 0;
		status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
						 led_addr, phy_addr, led_reg);
		if (status)
			return status;
	}
	status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
					led_addr, phy_addr, &led_reg);
	if (status)
		goto restore_config;
	if (on)
		led_reg = I40E_PHY_LED_MANUAL_ON;
	else
		led_reg = 0;
	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
					 led_addr, phy_addr, led_reg);
	if (status)
		goto restore_config;
	if (mode & I40E_PHY_LED_MODE_ORIG) {
		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
		status = i40e_write_phy_register(hw,
						 I40E_PHY_COM_REG_PAGE,
						 led_addr, phy_addr, led_ctl);
	}
	return status;
restore_config:
	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
					 phy_addr, led_ctl);
	return status;
}

/**
 * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
 * @hw: pointer to the hw struct
 * @reg_addr: register address
 * @reg_val: ptr to register value
 * @cmd_details: pointer to command details structure or NULL
 *
 * Use the firmware to read the Rx control register,
 * especially useful if the Rx unit is under heavy pressure
 **/
i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
				u32 reg_addr, u32 *reg_val,
				struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
	i40e_status status;

	if (!reg_val)
		return I40E_ERR_PARAM;

	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);

	cmd_resp->address = cpu_to_le32(reg_addr);

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	if (status == 0)
		*reg_val = le32_to_cpu(cmd_resp->value);

	return status;
}

/**
 * i40e_read_rx_ctl - read from an Rx control register
 * @hw: pointer to the hw struct
 * @reg_addr: register address
 **/
u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
{
	i40e_status status = 0;
	bool use_register;
	int retry = 5;
	u32 val = 0;

	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
	if (!use_register) {
do_retry:
		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
			usleep_range(1000, 2000);
			retry--;
			goto do_retry;
		}
	}

	/* if the AQ access failed, try the old-fashioned way */
	if (status || use_register)
		val = rd32(hw, reg_addr);

	return val;
}

/**
 * i40e_aq_rx_ctl_write_register
 * @hw: pointer to the hw struct
 * @reg_addr: register address
 * @reg_val: register value
 * @cmd_details: pointer to command details structure or NULL
 *
 * Use the firmware to write to an Rx control register,
 * especially useful if the Rx unit is under heavy pressure
 **/
i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
				u32 reg_addr, u32 reg_val,
				struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
	i40e_status status;

	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);

	cmd->address = cpu_to_le32(reg_addr);
	cmd->value = cpu_to_le32(reg_val);

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
}

/**
 * i40e_write_rx_ctl - write to an Rx control register
 * @hw: pointer to the hw struct
 * @reg_addr: register address
 * @reg_val: register value
 **/
void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
{
	i40e_status status = 0;
	bool use_register;
	int retry = 5;

	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
	if (!use_register) {
do_retry:
		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
						       reg_val, NULL);
		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
			usleep_range(1000, 2000);
			retry--;
			goto do_retry;
		}
	}

	/* if the AQ access failed, try the old-fashioned way */
	if (status || use_register)
		wr32(hw, reg_addr, reg_val);
}
+34 −10
Original line number Diff line number Diff line
@@ -1826,27 +1826,51 @@ static int i40e_set_phys_id(struct net_device *netdev,
			    enum ethtool_phys_id_state state)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	i40e_status ret = 0;
	struct i40e_pf *pf = np->vsi->back;
	struct i40e_hw *hw = &pf->hw;
	int blink_freq = 2;
	u16 temp_status;

	switch (state) {
	case ETHTOOL_ID_ACTIVE:
		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
			pf->led_status = i40e_led_get(hw);
		} else {
			i40e_aq_set_phy_debug(hw, I40E_PHY_DEBUG_PORT, NULL);
			ret = i40e_led_get_phy(hw, &temp_status,
					       &pf->phy_led_val);
			pf->led_status = temp_status;
		}
		return blink_freq;
	case ETHTOOL_ID_ON:
		i40e_led_set(hw, 0xF, false);
		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
			i40e_led_set(hw, 0xf, false);
		else
			ret = i40e_led_set_phy(hw, true, pf->led_status, 0);
		break;
	case ETHTOOL_ID_OFF:
		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
			i40e_led_set(hw, 0x0, false);
		else
			ret = i40e_led_set_phy(hw, false, pf->led_status, 0);
		break;
	case ETHTOOL_ID_INACTIVE:
		i40e_led_set(hw, pf->led_status, false);
		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
			i40e_led_set(hw, false, pf->led_status);
		} else {
			ret = i40e_led_set_phy(hw, false, pf->led_status,
					       (pf->phy_led_val |
					       I40E_PHY_LED_MODE_ORIG));
			i40e_aq_set_phy_debug(hw, 0, NULL);
		}
		break;
	default:
		break;
	}

		if (ret)
			return -ENOENT;
		else
			return 0;
}

@@ -2157,8 +2181,8 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
{
	struct i40e_hw *hw = &pf->hw;
	u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
		   ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
	u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
		   ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);

	/* RSS does not support anything other than hashing
	 * to queues on src and dst IPs and ports
@@ -2267,8 +2291,8 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
		return -EINVAL;
	}

	wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
	wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
	i40e_flush(hw);

	/* Save setting for future output/update */
+22 −6
Original line number Diff line number Diff line
@@ -295,11 +295,11 @@ void i40e_init_pf_fcoe(struct i40e_pf *pf)
	}

	/* enable FCoE hash filter */
	val = rd32(hw, I40E_PFQF_HENA(1));
	val = i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1));
	val |= BIT(I40E_FILTER_PCTYPE_FCOE_OX - 32);
	val |= BIT(I40E_FILTER_PCTYPE_FCOE_RX - 32);
	val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
	wr32(hw, I40E_PFQF_HENA(1), val);
	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), val);

	/* enable flag */
	pf->flags |= I40E_FLAG_FCOE_ENABLED;
@@ -317,11 +317,11 @@ void i40e_init_pf_fcoe(struct i40e_pf *pf)
	pf->filter_settings.fcoe_cntx_num = I40E_DMA_CNTX_SIZE_4K;

	/* Setup max frame with FCoE_MTU plus L2 overheads */
	val = rd32(hw, I40E_GLFCOE_RCTL);
	val = i40e_read_rx_ctl(hw, I40E_GLFCOE_RCTL);
	val &= ~I40E_GLFCOE_RCTL_MAX_SIZE_MASK;
	val |= ((FCOE_MTU + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
		 << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT);
	wr32(hw, I40E_GLFCOE_RCTL, val);
	i40e_write_rx_ctl(hw, I40E_GLFCOE_RCTL, val);

	dev_info(&pf->pdev->dev, "FCoE is supported.\n");
}
@@ -1359,16 +1359,32 @@ static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
	struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
	struct i40e_tx_buffer *first;
	u32 tx_flags = 0;
	int fso, count;
	u8 hdr_len = 0;
	u8 sof = 0;
	u8 eof = 0;
	int fso;

	if (i40e_fcoe_set_skb_header(skb))
		goto out_drop;

	if (!i40e_xmit_descriptor_count(skb, tx_ring))
	count = i40e_xmit_descriptor_count(skb);
	if (i40e_chk_linearize(skb, count)) {
		if (__skb_linearize(skb))
			goto out_drop;
		count = TXD_USE_COUNT(skb->len);
		tx_ring->tx_stats.tx_linearize++;
	}

	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
	 *       + 4 desc gap to avoid the cache line where head is,
	 *       + 1 desc for context descriptor,
	 * otherwise try next time
	 */
	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
		tx_ring->tx_stats.tx_busy++;
		return NETDEV_TX_BUSY;
	}

	/* prepare the xmit flags */
	if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
Loading