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

-queue

Tony Nguyen says:

====================
i40e: Simplify VSI and VEB handling

Ivan Vecera says:

The series simplifies handling of VSIs and VEBs by introducing for-each
iterating macros, 'find' helper functions. Also removes the VEB
recursion because the VEBs cannot have sub-VEBs according datasheet and
fixes the support for floating VEBs.

The series content:
Patch 1 - Uses existing helper function for find FDIR VSI instead of loop
Patch 2 - Adds and uses macros to iterate VSI and VEB arrays
Patch 3 - Adds 2 helper functions to find VSIs and VEBs by their SEID
Patch 4 - Fixes broken support for floating VEBs
Patch 5 - Removes VEB recursion and simplifies VEB handling
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d0bcc15c f09cbb6c
Loading
Loading
Loading
Loading
+87 −6
Original line number Diff line number Diff line
@@ -686,6 +686,54 @@ struct i40e_pf {
	struct list_head ddp_old_prof;
};

/**
 * __i40e_pf_next_vsi - get next valid VSI
 * @pf: pointer to the PF struct
 * @idx: pointer to start position number
 *
 * Find and return next non-NULL VSI pointer in pf->vsi array and
 * updates idx position. Returns NULL if no VSI is found.
 **/
static __always_inline struct i40e_vsi *
__i40e_pf_next_vsi(struct i40e_pf *pf, int *idx)
{
	while (*idx < pf->num_alloc_vsi) {
		if (pf->vsi[*idx])
			return pf->vsi[*idx];
		(*idx)++;
	}
	return NULL;
}

#define i40e_pf_for_each_vsi(_pf, _i, _vsi)			\
	for (_i = 0, _vsi = __i40e_pf_next_vsi(_pf, &_i);	\
	     _vsi;						\
	     _i++, _vsi = __i40e_pf_next_vsi(_pf, &_i))

/**
 * __i40e_pf_next_veb - get next valid VEB
 * @pf: pointer to the PF struct
 * @idx: pointer to start position number
 *
 * Find and return next non-NULL VEB pointer in pf->veb array and
 * updates idx position. Returns NULL if no VEB is found.
 **/
static __always_inline struct i40e_veb *
__i40e_pf_next_veb(struct i40e_pf *pf, int *idx)
{
	while (*idx < I40E_MAX_VEB) {
		if (pf->veb[*idx])
			return pf->veb[*idx];
		(*idx)++;
	}
	return NULL;
}

#define i40e_pf_for_each_veb(_pf, _i, _veb)			\
	for (_i = 0, _veb = __i40e_pf_next_veb(_pf, &_i);	\
	     _veb;						\
	     _i++, _veb = __i40e_pf_next_veb(_pf, &_i))

/**
 * i40e_mac_to_hkey - Convert a 6-byte MAC Address to a u64 hash key
 * @macaddr: the MAC Address as the base key
@@ -735,7 +783,6 @@ struct i40e_new_mac_filter {
struct i40e_veb {
	struct i40e_pf *pf;
	u16 idx;
	u16 veb_idx;		/* index of VEB parent */
	u16 seid;
	u16 uplink_seid;
	u16 stats_idx;		/* index of VEB parent */
@@ -1120,14 +1167,12 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
static inline struct i40e_vsi *
i40e_find_vsi_by_type(struct i40e_pf *pf, u16 type)
{
	struct i40e_vsi *vsi;
	int i;

	for (i = 0; i < pf->num_alloc_vsi; i++) {
		struct i40e_vsi *vsi = pf->vsi[i];

		if (vsi && vsi->type == type)
	i40e_pf_for_each_vsi(pf, i, vsi)
		if (vsi->type == type)
			return vsi;
	}

	return NULL;
}
@@ -1309,4 +1354,40 @@ static inline struct i40e_pf *i40e_hw_to_pf(struct i40e_hw *hw)

struct device *i40e_hw_to_dev(struct i40e_hw *hw);

/**
 * i40e_pf_get_vsi_by_seid - find VSI by SEID
 * @pf: pointer to a PF
 * @seid: SEID of the VSI
 **/
static inline struct i40e_vsi *
i40e_pf_get_vsi_by_seid(struct i40e_pf *pf, u16 seid)
{
	struct i40e_vsi *vsi;
	int i;

	i40e_pf_for_each_vsi(pf, i, vsi)
		if (vsi->seid == seid)
			return vsi;

	return NULL;
}

/**
 * i40e_pf_get_veb_by_seid - find VEB by SEID
 * @pf: pointer to a PF
 * @seid: SEID of the VSI
 **/
static inline struct i40e_veb *
i40e_pf_get_veb_by_seid(struct i40e_pf *pf, u16 seid)
{
	struct i40e_veb *veb;
	int i;

	i40e_pf_for_each_veb(pf, i, veb)
		if (veb->seid == seid)
			return veb;

	return NULL;
}

#endif /* _I40E_H_ */
+5 −5
Original line number Diff line number Diff line
@@ -947,17 +947,17 @@ static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi,
static void i40e_dcbnl_del_app(struct i40e_pf *pf,
			       struct i40e_dcb_app_priority_table *app)
{
	struct i40e_vsi *vsi;
	int v, err;

	for (v = 0; v < pf->num_alloc_vsi; v++) {
		if (pf->vsi[v] && pf->vsi[v]->netdev) {
			err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app);
	i40e_pf_for_each_vsi(pf, v, vsi)
		if (vsi->netdev) {
			err = i40e_dcbnl_vsi_del_app(vsi, app);
			dev_dbg(&pf->pdev->dev, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n",
				pf->vsi[v]->seid, err, app->selector,
				vsi->seid, err, app->selector,
				app->protocolid, app->priority);
		}
}
}

/**
 * i40e_dcbnl_find_app - Search APP in given DCB config
+41 −56
Original line number Diff line number Diff line
@@ -24,31 +24,13 @@ enum ring_type {
 **/
static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid)
{
	int i;

	if (seid < 0)
	if (seid < 0) {
		dev_info(&pf->pdev->dev, "%d: bad seid\n", seid);
	else
		for (i = 0; i < pf->num_alloc_vsi; i++)
			if (pf->vsi[i] && (pf->vsi[i]->seid == seid))
				return pf->vsi[i];

		return NULL;
	}

/**
 * i40e_dbg_find_veb - searches for the veb with the given seid
 * @pf: the PF structure to search for the veb
 * @seid: seid of the veb it is searching for
 **/
static struct i40e_veb *i40e_dbg_find_veb(struct i40e_pf *pf, int seid)
{
	int i;

	for (i = 0; i < I40E_MAX_VEB; i++)
		if (pf->veb[i] && pf->veb[i]->seid == seid)
			return pf->veb[i];
	return NULL;
	return i40e_pf_get_vsi_by_seid(pf, seid);
}

/**************************************************************
@@ -653,12 +635,11 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
 **/
static void i40e_dbg_dump_vsi_no_seid(struct i40e_pf *pf)
{
	struct i40e_vsi *vsi;
	int i;

	for (i = 0; i < pf->num_alloc_vsi; i++)
		if (pf->vsi[i])
			dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n",
				 i, pf->vsi[i]->seid);
	i40e_pf_for_each_vsi(pf, i, vsi)
		dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n", i, vsi->seid);
}

/**
@@ -696,15 +677,14 @@ static void i40e_dbg_dump_veb_seid(struct i40e_pf *pf, int seid)
{
	struct i40e_veb *veb;

	veb = i40e_dbg_find_veb(pf, seid);
	veb = i40e_pf_get_veb_by_seid(pf, seid);
	if (!veb) {
		dev_info(&pf->pdev->dev, "can't find veb %d\n", seid);
		return;
	}
	dev_info(&pf->pdev->dev,
		 "veb idx=%d,%d stats_ic=%d  seid=%d uplink=%d mode=%s\n",
		 veb->idx, veb->veb_idx, veb->stats_idx, veb->seid,
		 veb->uplink_seid,
		 "veb idx=%d stats_ic=%d  seid=%d uplink=%d mode=%s\n",
		 veb->idx, veb->stats_idx, veb->seid, veb->uplink_seid,
		 veb->bridge_mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
	i40e_dbg_dump_eth_stats(pf, &veb->stats);
}
@@ -718,12 +698,9 @@ static void i40e_dbg_dump_veb_all(struct i40e_pf *pf)
	struct i40e_veb *veb;
	int i;

	for (i = 0; i < I40E_MAX_VEB; i++) {
		veb = pf->veb[i];
		if (veb)
	i40e_pf_for_each_veb(pf, i, veb)
		i40e_dbg_dump_veb_seid(pf, veb->seid);
}
}

/**
 * i40e_dbg_dump_vf - dump VF info
@@ -851,10 +828,14 @@ static ssize_t i40e_dbg_command_write(struct file *filp,

	} else if (strncmp(cmd_buf, "add relay", 9) == 0) {
		struct i40e_veb *veb;
		int uplink_seid, i;
		u8 enabled_tc = 0x1;
		int uplink_seid;

		cnt = sscanf(&cmd_buf[9], "%i %i", &uplink_seid, &vsi_seid);
		if (cnt != 2) {
		if (cnt == 0) {
			uplink_seid = 0;
			vsi_seid = 0;
		} else if (cnt != 2) {
			dev_info(&pf->pdev->dev,
				 "add relay: bad command string, cnt=%d\n",
				 cnt);
@@ -866,33 +847,36 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
			goto command_write_done;
		}

		vsi = i40e_dbg_find_vsi(pf, vsi_seid);
		if (uplink_seid != 0 && uplink_seid != pf->mac_seid) {
			dev_info(&pf->pdev->dev,
				 "add relay: relay uplink %d not found\n",
				 uplink_seid);
			goto command_write_done;
		} else if (uplink_seid) {
			vsi = i40e_pf_get_vsi_by_seid(pf, vsi_seid);
			if (!vsi) {
				dev_info(&pf->pdev->dev,
				 "add relay: VSI %d not found\n", vsi_seid);
					 "add relay: VSI %d not found\n",
					 vsi_seid);
				goto command_write_done;
			}

		for (i = 0; i < I40E_MAX_VEB; i++)
			if (pf->veb[i] && pf->veb[i]->seid == uplink_seid)
				break;
		if (i >= I40E_MAX_VEB && uplink_seid != 0 &&
		    uplink_seid != pf->mac_seid) {
			enabled_tc = vsi->tc_config.enabled_tc;
		} else if (vsi_seid) {
			dev_info(&pf->pdev->dev,
				 "add relay: relay uplink %d not found\n",
				 uplink_seid);
				 "add relay: VSI must be 0 for floating relay\n");
			goto command_write_done;
		}

		veb = i40e_veb_setup(pf, 0, uplink_seid, vsi_seid,
				     vsi->tc_config.enabled_tc);
		veb = i40e_veb_setup(pf, 0, uplink_seid, vsi_seid, enabled_tc);
		if (veb)
			dev_info(&pf->pdev->dev, "added relay %d\n", veb->seid);
		else
			dev_info(&pf->pdev->dev, "add relay failed\n");

	} else if (strncmp(cmd_buf, "del relay", 9) == 0) {
		struct i40e_veb *veb;
		int i;

		cnt = sscanf(&cmd_buf[9], "%i", &veb_seid);
		if (cnt != 1) {
			dev_info(&pf->pdev->dev,
@@ -906,9 +890,10 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
		}

		/* find the veb */
		for (i = 0; i < I40E_MAX_VEB; i++)
			if (pf->veb[i] && pf->veb[i]->seid == veb_seid)
		i40e_pf_for_each_veb(pf, i, veb)
			if (veb->seid == veb_seid)
				break;

		if (i >= I40E_MAX_VEB) {
			dev_info(&pf->pdev->dev,
				 "del relay: relay %d not found\n", veb_seid);
@@ -916,7 +901,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
		}

		dev_info(&pf->pdev->dev, "deleting relay %d\n", veb_seid);
		i40e_veb_release(pf->veb[i]);
		i40e_veb_release(veb);
	} else if (strncmp(cmd_buf, "add pvid", 8) == 0) {
		unsigned int v;
		int ret;
@@ -1251,8 +1236,8 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
			if (cnt == 0) {
				int i;

				for (i = 0; i < pf->num_alloc_vsi; i++)
					i40e_vsi_reset_stats(pf->vsi[i]);
				i40e_pf_for_each_vsi(pf, i, vsi)
					i40e_vsi_reset_stats(vsi);
				dev_info(&pf->pdev->dev, "vsi clear stats called for all vsi's\n");
			} else if (cnt == 1) {
				vsi = i40e_dbg_find_vsi(pf, vsi_seid);
+240 −323

File changed.

Preview size limit exceeded, changes collapsed.