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

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


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-10-28

This series contains updates to i40e and i40evf only.

Carolyn provides a couple of fixes, first resolving a problem in the
client interface that was causing random stack traces in the RDMA driver
which was due to a timing related NULL pointer dereference.  Fixed a
problem where it could take a very long time to print the link down
notification, by changing how often we update link info from firmware.

Alex provides a number of changes, first is a re-write of the bust wait
loop in the Flow Director transmit function to reduce code size.  Cleans
up unused code in favor of the same functionality which can be inlined.
Dropped the functionality for SCTP since we cannot currently support it.
Cleans up redundant code in the receive clean-up path.  Finally cleaned
up the convoluted configuration for how the driver handled the debug
flags contained in msg_level.

Filip fixes an incorrect bit mask which was being used for testing the
"get link status".  Cleaned up a workaround that is no longer needed
for production NICs and was causing frames to pass while disregarding
the VLAN tagging.

Mitch brings another fix for the client interface supporting the VF RDMA
driver to allow clients to recover from reset by re-opening existing
clients.

Alan fixes a bug in which a "perfect storm" can occur and cause interrupts
to fail to be correctly affinitized.

Lihong fixes a confusing dmesg reported when users were using ethtool -L
option.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ebb676da 5d4ca23e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -607,6 +607,8 @@ struct i40e_q_vector {
	unsigned long hung_detected; /* Set/Reset for hung_detection logic */

	cpumask_t affinity_mask;
	struct irq_affinity_notify affinity_notify;

	struct rcu_head rcu;	/* to avoid race with update stats on free */
	char name[I40E_INT_NAME_STR_LEN];
	bool arm_wb_state;
@@ -728,8 +730,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
				u16 uplink, u32 param1);
int i40e_vsi_release(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, enum i40e_vsi_type type,
				 struct i40e_vsi *start_vsi);
#ifdef I40E_FCOE
void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
			      struct i40e_vsi_context *ctxt,
+19 −66
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset)
			}
			cdev->client->ops->close(&cdev->lan_info, cdev->client,
						 reset);
			clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
			i40e_client_release_qvlist(&cdev->lan_info);
		}
	}
@@ -405,37 +406,6 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id,
	return capable;
}

/**
 * i40e_vsi_lookup - finds a matching VSI from the PF list starting at start_vsi
 * @pf: board private structure
 * @type: vsi type
 * @start_vsi: a VSI pointer from where to start the search
 *
 * Returns non NULL on success or NULL for failure
 **/
struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf,
				 enum i40e_vsi_type type,
				 struct i40e_vsi *start_vsi)
{
	struct i40e_vsi *vsi;
	int i = 0;

	if (start_vsi) {
		for (i = 0; i < pf->num_alloc_vsi; i++) {
			vsi = pf->vsi[i];
			if (vsi == start_vsi)
				break;
		}
	}
	for (; i < pf->num_alloc_vsi; i++) {
		vsi = pf->vsi[i];
		if (vsi && vsi->type == type)
			return vsi;
	}

	return NULL;
}

/**
 * i40e_client_add_instance - add a client instance struct to the instance list
 * @pf: pointer to the board struct
@@ -565,7 +535,7 @@ void i40e_client_subtask(struct i40e_pf *pf)
			if (test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state))
				continue;
		} else {
			dev_warn(&pf->pdev->dev, "This client %s is being instanciated at probe\n",
			dev_warn(&pf->pdev->dev, "This client %s is being instantiated at probe\n",
				 client->name);
		}

@@ -575,29 +545,25 @@ void i40e_client_subtask(struct i40e_pf *pf)
			continue;

		if (!existing) {
			/* Also up the ref_cnt for no. of instances of this
			 * client.
			 */
			atomic_inc(&client->ref_cnt);
			dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x func=0x%02x\n",
				 client->name, pf->hw.pf_id,
				 pf->hw.bus.device, pf->hw.bus.func);
		}

		mutex_lock(&i40e_client_instance_mutex);
		if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
			      &cdev->state)) {
			/* Send an Open request to the client */
		atomic_inc(&cdev->ref_cnt);
			if (client->ops && client->ops->open)
			ret = client->ops->open(&cdev->lan_info, client);
		atomic_dec(&cdev->ref_cnt);
				ret = client->ops->open(&cdev->lan_info,
							client);
			if (!ret) {
			set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
				set_bit(__I40E_CLIENT_INSTANCE_OPENED,
					&cdev->state);
			} else {
				/* remove client instance */
			mutex_unlock(&i40e_client_instance_mutex);
				i40e_client_del_instance(pf, client);
			atomic_dec(&client->ref_cnt);
			continue;
			}
		}
		mutex_unlock(&i40e_client_instance_mutex);
	}
@@ -694,10 +660,6 @@ static int i40e_client_release(struct i40e_client *client)
			continue;
		pf = (struct i40e_pf *)cdev->lan_info.pf;
		if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
			if (atomic_read(&cdev->ref_cnt) > 0) {
				ret = I40E_ERR_NOT_READY;
				goto out;
			}
			if (client->ops && client->ops->close)
				client->ops->close(&cdev->lan_info, client,
						   false);
@@ -710,11 +672,9 @@ static int i40e_client_release(struct i40e_client *client)
		}
		/* delete the client instance from the list */
		list_move(&cdev->list, &cdevs_tmp);
		atomic_dec(&client->ref_cnt);
		dev_info(&pf->pdev->dev, "Deleted client instance of Client %s\n",
			 client->name);
	}
out:
	mutex_unlock(&i40e_client_instance_mutex);

	/* free the client device and release its vsi */
@@ -1040,17 +1000,10 @@ int i40e_unregister_client(struct i40e_client *client)
		ret = -ENODEV;
		goto out;
	}
	if (atomic_read(&client->ref_cnt) == 0) {
	clear_bit(__I40E_CLIENT_REGISTERED, &client->state);
	list_del(&client->list);
	pr_info("i40e: Unregistered client %s with return code %d\n",
		client->name, ret);
	} else {
		ret = I40E_ERR_NOT_READY;
		pr_err("i40e: Client %s failed unregister - client has open instances\n",
		       client->name);
	}

out:
	mutex_unlock(&i40e_client_mutex);
	return ret;
+0 −2
Original line number Diff line number Diff line
@@ -203,8 +203,6 @@ struct i40e_client_instance {
	struct i40e_info lan_info;
	struct i40e_client *client;
	unsigned long  state;
	/* A count of all the in-progress calls to the client */
	atomic_t ref_cnt;
};

struct i40e_client {
+5 −2
Original line number Diff line number Diff line
@@ -1849,7 +1849,7 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
	else
		hw_link_info->crc_enable = false;

	if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_ENABLE))
	if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_IS_ENABLED))
		hw_link_info->lse_enable = true;
	else
		hw_link_info->lse_enable = false;
@@ -2494,7 +2494,10 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw)
	if (status)
		return status;

	if (hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) {
	/* extra checking needed to ensure link info to user is timely */
	if ((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
	    ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
	     !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) {
		status = i40e_aq_get_phy_capabilities(hw, false, false,
						      &abilities, NULL);
		if (status)
+0 −19
Original line number Diff line number Diff line
@@ -1210,24 +1210,6 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
			dev_info(&pf->pdev->dev,
				 "dump debug fwdata <cluster_id> <table_id> <index>\n");
		}

	} else if (strncmp(cmd_buf, "msg_enable", 10) == 0) {
		u32 level;
		cnt = sscanf(&cmd_buf[10], "%i", &level);
		if (cnt) {
			if (I40E_DEBUG_USER & level) {
				pf->hw.debug_mask = level;
				dev_info(&pf->pdev->dev,
					 "set hw.debug_mask = 0x%08x\n",
					 pf->hw.debug_mask);
			}
			pf->msg_enable = level;
			dev_info(&pf->pdev->dev, "set msg_enable = 0x%08x\n",
				 pf->msg_enable);
		} else {
			dev_info(&pf->pdev->dev, "msg_enable = 0x%08x\n",
				 pf->msg_enable);
		}
	} else if (strncmp(cmd_buf, "pfr", 3) == 0) {
		dev_info(&pf->pdev->dev, "debugfs: forcing PFR\n");
		i40e_do_reset_safe(pf, BIT(__I40E_PF_RESET_REQUESTED));
@@ -1644,7 +1626,6 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
		dev_info(&pf->pdev->dev, "  dump desc aq\n");
		dev_info(&pf->pdev->dev, "  dump reset stats\n");
		dev_info(&pf->pdev->dev, "  dump debug fwdata <cluster_id> <table_id> <index>\n");
		dev_info(&pf->pdev->dev, "  msg_enable [level]\n");
		dev_info(&pf->pdev->dev, "  read <reg>\n");
		dev_info(&pf->pdev->dev, "  write <reg> <value>\n");
		dev_info(&pf->pdev->dev, "  clear_stats vsi [seid]\n");
Loading