Skip to content

Commit

Permalink
i40e: refactor Rx filter handling
Browse files Browse the repository at this point in the history
Properly track filter adds and deletes so the driver doesn't lose filters
during resets and up/down cycles. Add a tracking mechanism so that the
driver knows when to enter and leave promiscuous mode.

Implement a simple state machine so the driver can track the status of
each filter throughout its lifecycle. Properly manage the overflow promiscuous
state for the each VSI, and provide a way for the driver to detect when to exit
overflow promiscuous mode.

Remove all possible default MAC filters that the firmware may have set up so
that the driver can manage these correctly, particularly when VLANs come into
play. Remove the LAA flag for filters; instead just send whatever we get through
set_mac to the firmware as the LAA for wakeup purposes.

Finally, add the state of each filter to debugfs output so we can see what's
going on inside the driver's pointy little head.

Change-ID: I97c5e366fac2254fa01eaff4f65c0af61dcf2e1f
Signed-off-by: Mitch Williams <[email protected]>
Tested-by: Andrew Bowers <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
  • Loading branch information
mawilli1 authored and Jeff Kirsher committed Jul 22, 2016
1 parent 9287141 commit c3c7ea2
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 279 deletions.
14 changes: 12 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,14 @@ struct i40e_pf {
u16 phy_led_val;
};

enum i40e_filter_state {
I40E_FILTER_INVALID = 0, /* Invalid state */
I40E_FILTER_NEW, /* New, not sent to FW yet */
I40E_FILTER_ACTIVE, /* Added to switch by FW */
I40E_FILTER_FAILED, /* Rejected by FW */
I40E_FILTER_REMOVE, /* To be removed */
/* There is no 'removed' state; the filter struct is freed */
};
struct i40e_mac_filter {
struct list_head list;
u8 macaddr[ETH_ALEN];
Expand All @@ -456,8 +464,7 @@ struct i40e_mac_filter {
u8 counter; /* number of instances of this filter */
bool is_vf; /* filter belongs to a VF */
bool is_netdev; /* filter belongs to a netdev */
bool changed; /* filter needs to be sync'd to the HW */
bool is_laa; /* filter is a Locally Administered Address */
enum i40e_filter_state state;
};

struct i40e_veb {
Expand Down Expand Up @@ -523,6 +530,9 @@ struct i40e_vsi {
struct i40e_ring **rx_rings;
struct i40e_ring **tx_rings;

u32 active_filters;
u32 promisc_threshold;

u16 work_limit;
u16 int_rate_limit; /* value in usecs */

Expand Down
16 changes: 14 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ static ssize_t i40e_dbg_command_read(struct file *filp, char __user *buffer,
return len;
}

static char *i40e_filter_state_string[] = {
"INVALID",
"NEW",
"ACTIVE",
"FAILED",
"REMOVE",
};

/**
* i40e_dbg_dump_vsi_seid - handles dump vsi seid write into command datum
* @pf: the i40e_pf created in command write
Expand Down Expand Up @@ -160,10 +168,14 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
pf->hw.mac.port_addr);
list_for_each_entry(f, &vsi->mac_filter_list, list) {
dev_info(&pf->pdev->dev,
" mac_filter_list: %pM vid=%d, is_netdev=%d is_vf=%d counter=%d\n",
" mac_filter_list: %pM vid=%d, is_netdev=%d is_vf=%d counter=%d, state %s\n",
f->macaddr, f->vlan, f->is_netdev, f->is_vf,
f->counter);
f->counter, i40e_filter_state_string[f->state]);
}
dev_info(&pf->pdev->dev, " active_filters %d, promisc_threshold %d, overflow promisc %s\n",
vsi->active_filters, vsi->promisc_threshold,
(test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state) ?
"ON" : "OFF"));
nstat = i40e_get_vsi_stats_struct(vsi);
dev_info(&pf->pdev->dev,
" net_stats: rx_packets = %lu, rx_bytes = %lu, rx_errors = %lu, rx_dropped = %lu\n",
Expand Down
Loading

0 comments on commit c3c7ea2

Please sign in to comment.