Commit 417d18d3 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2017-02-11

This series contains updates to i40e and i40evf only.

Jake makes a minor change to prevent a minor bit of work, if it is not
necessary.  In the case where we do not have a client, there is no need
to check the client params, so move the check till after we have ensured
we have a client.  Correct a code comment which incorrectly implied
that raw_packet buffers were freed in i40e_clean_tx_ring(), so fixed
the code comment to better explain where memory is freed.  Reduce the
severity and frequency of the message notifying we cleared the receive
timestamp register, since the logic has a much better detection scheme
that could detect a stalled receive timestamp register.  The improved
logic was actually causing the notification message to occur more
frequently and was giving the user a false perception that a timestamp
event was missed for a valid packet, so reduce the severity from
dev_warn to dev_dbg and only fire off the message when 3 or 4 of the
RXTIME registers are stalled and get cleared within the same
watchdog event.  Fixed a bug, where we were modifying the mac_filter
outside a lock when handling the addition of broadcast filters.  Fix
this by updating i40e_update_filter_state logic so that it knows to
avoid broadcast filters, which ensures that we do not have to remove
the filter separately and can put it back using the normal flow.
Refactored how we add new filters to firmware to avoid a race condition
that can occur due to removing filters from the hash temporarily.

Mitch adds a sleep (without timeout) so that we wait for a reply from
the PF before we continue, since the iWarp client cannot continue until
the operation is completed.  Fixed up a function which could never
return an error, to be void and cleaned up the checking of the now
null and void return value.

Scott limits the DMA sync to CPU to the actual length of the incoming
packet, versus the syncing of the entire buffer.  Also reduces the
receive buffer struct (by a single pointer) and align the driver to be
more consistent with other Intel drivers with respect to packets that
span buffers.

Sudheer adds a field to track the bus number info and modified log
statements to print bus, device and function information.

Henry adds the ability to store the FEC status bits from the link up
event.  Also adds the ethtool support for FEC capabilities and 25G
link types.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8f9000a5 b7eaf8f1
...@@ -467,6 +467,22 @@ struct i40e_mac_filter { ...@@ -467,6 +467,22 @@ struct i40e_mac_filter {
enum i40e_filter_state state; enum i40e_filter_state state;
}; };
/* Wrapper structure to keep track of filters while we are preparing to send
* firmware commands. We cannot send firmware commands while holding a
* spinlock, since it might sleep. To avoid this, we wrap the added filters in
* a separate structure, which will track the state change and update the real
* filter while under lock. We can't simply hold the filters in a separate
* list, as this opens a window for a race condition when adding new MAC
* addresses to all VLANs, or when adding new VLANs to all MAC addresses.
*/
struct i40e_new_mac_filter {
struct hlist_node hlist;
struct i40e_mac_filter *f;
/* Track future changes to state separately */
enum i40e_filter_state state;
};
struct i40e_veb { struct i40e_veb {
struct i40e_pf *pf; struct i40e_pf *pf;
u16 idx; u16 idx;
......
...@@ -174,8 +174,6 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) ...@@ -174,8 +174,6 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi)
if (!vsi) if (!vsi)
return; return;
memset(&params, 0, sizeof(params));
i40e_client_get_params(vsi, &params);
mutex_lock(&i40e_client_instance_mutex); mutex_lock(&i40e_client_instance_mutex);
list_for_each_entry(cdev, &i40e_client_instances, list) { list_for_each_entry(cdev, &i40e_client_instances, list) {
if (cdev->lan_info.pf == vsi->back) { if (cdev->lan_info.pf == vsi->back) {
...@@ -186,6 +184,8 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) ...@@ -186,6 +184,8 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi)
"Cannot locate client instance l2_param_change routine\n"); "Cannot locate client instance l2_param_change routine\n");
continue; continue;
} }
memset(&params, 0, sizeof(params));
i40e_client_get_params(vsi, &params);
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) { &cdev->state)) {
dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n"); dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n");
...@@ -510,9 +510,10 @@ void i40e_client_subtask(struct i40e_pf *pf) ...@@ -510,9 +510,10 @@ void i40e_client_subtask(struct i40e_pf *pf)
continue; continue;
if (!existing) { if (!existing) {
dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x func=0x%02x\n", dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
client->name, pf->hw.pf_id, client->name, pf->hw.pf_id,
pf->hw.bus.device, pf->hw.bus.func); pf->hw.bus.bus_id, pf->hw.bus.device,
pf->hw.bus.func);
} }
mutex_lock(&i40e_client_instance_mutex); mutex_lock(&i40e_client_instance_mutex);
...@@ -561,8 +562,9 @@ int i40e_lan_add_device(struct i40e_pf *pf) ...@@ -561,8 +562,9 @@ int i40e_lan_add_device(struct i40e_pf *pf)
ldev->pf = pf; ldev->pf = pf;
INIT_LIST_HEAD(&ldev->list); INIT_LIST_HEAD(&ldev->list);
list_add(&ldev->list, &i40e_devices); list_add(&ldev->list, &i40e_devices);
dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x func=0x%02x\n", dev_info(&pf->pdev->dev, "Added LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
pf->hw.pf_id, pf->hw.bus.device, pf->hw.bus.func); pf->hw.pf_id, pf->hw.bus.bus_id,
pf->hw.bus.device, pf->hw.bus.func);
/* Since in some cases register may have happened before a device gets /* Since in some cases register may have happened before a device gets
* added, we can schedule a subtask to go initiate the clients if * added, we can schedule a subtask to go initiate the clients if
...@@ -590,9 +592,9 @@ int i40e_lan_del_device(struct i40e_pf *pf) ...@@ -590,9 +592,9 @@ int i40e_lan_del_device(struct i40e_pf *pf)
mutex_lock(&i40e_device_mutex); mutex_lock(&i40e_device_mutex);
list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) { list_for_each_entry_safe(ldev, tmp, &i40e_devices, list) {
if (ldev->pf == pf) { if (ldev->pf == pf) {
dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x func=0x%02x\n", dev_info(&pf->pdev->dev, "Deleted LAN device PF%d bus=0x%02x dev=0x%02x func=0x%02x\n",
pf->hw.pf_id, pf->hw.bus.device, pf->hw.pf_id, pf->hw.bus.bus_id,
pf->hw.bus.func); pf->hw.bus.device, pf->hw.bus.func);
list_del(&ldev->list); list_del(&ldev->list);
kfree(ldev); kfree(ldev);
ret = 0; ret = 0;
...@@ -653,13 +655,11 @@ static int i40e_client_release(struct i40e_client *client) ...@@ -653,13 +655,11 @@ static int i40e_client_release(struct i40e_client *client)
* i40e_client_prepare - prepare client specific resources * i40e_client_prepare - prepare client specific resources
* @client: pointer to the registered client * @client: pointer to the registered client
* *
* Return 0 on success or < 0 on error
**/ **/
static int i40e_client_prepare(struct i40e_client *client) static void i40e_client_prepare(struct i40e_client *client)
{ {
struct i40e_device *ldev; struct i40e_device *ldev;
struct i40e_pf *pf; struct i40e_pf *pf;
int ret = 0;
mutex_lock(&i40e_device_mutex); mutex_lock(&i40e_device_mutex);
list_for_each_entry(ldev, &i40e_devices, list) { list_for_each_entry(ldev, &i40e_devices, list) {
...@@ -669,7 +669,6 @@ static int i40e_client_prepare(struct i40e_client *client) ...@@ -669,7 +669,6 @@ static int i40e_client_prepare(struct i40e_client *client)
i40e_service_event_schedule(pf); i40e_service_event_schedule(pf);
} }
mutex_unlock(&i40e_device_mutex); mutex_unlock(&i40e_device_mutex);
return ret;
} }
/** /**
...@@ -926,13 +925,9 @@ int i40e_register_client(struct i40e_client *client) ...@@ -926,13 +925,9 @@ int i40e_register_client(struct i40e_client *client)
set_bit(__I40E_CLIENT_REGISTERED, &client->state); set_bit(__I40E_CLIENT_REGISTERED, &client->state);
mutex_unlock(&i40e_client_mutex); mutex_unlock(&i40e_client_mutex);
if (i40e_client_prepare(client)) { i40e_client_prepare(client);
ret = -EIO;
goto out;
}
pr_info("i40e: Registered client %s with return code %d\n", pr_info("i40e: Registered client %s\n", client->name);
client->name, ret);
out: out:
return ret; return ret;
} }
......
...@@ -1838,6 +1838,8 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw, ...@@ -1838,6 +1838,8 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed; hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
hw_link_info->link_info = resp->link_info; hw_link_info->link_info = resp->link_info;
hw_link_info->an_info = resp->an_info; hw_link_info->an_info = resp->an_info;
hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
I40E_AQ_CONFIG_FEC_RS_ENA);
hw_link_info->ext_info = resp->ext_info; hw_link_info->ext_info = resp->ext_info;
hw_link_info->loopback = resp->loopback; hw_link_info->loopback = resp->loopback;
hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size); hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
......
...@@ -803,9 +803,12 @@ static int i40e_set_settings(struct net_device *netdev, ...@@ -803,9 +803,12 @@ static int i40e_set_settings(struct net_device *netdev,
if (change || (abilities.link_speed != config.link_speed)) { if (change || (abilities.link_speed != config.link_speed)) {
/* copy over the rest of the abilities */ /* copy over the rest of the abilities */
config.phy_type = abilities.phy_type; config.phy_type = abilities.phy_type;
config.phy_type_ext = abilities.phy_type_ext;
config.eee_capability = abilities.eee_capability; config.eee_capability = abilities.eee_capability;
config.eeer = abilities.eeer_val; config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan; config.low_power_ctrl = abilities.d3_lpan;
config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
I40E_AQ_PHY_FEC_CONFIG_MASK;
/* save the requested speeds */ /* save the requested speeds */
hw->phy.link_info.requested_speeds = config.link_speed; hw->phy.link_info.requested_speeds = config.link_speed;
......
This diff is collapsed.
...@@ -69,12 +69,12 @@ struct i40e_virt_mem { ...@@ -69,12 +69,12 @@ struct i40e_virt_mem {
#define i40e_allocate_virt_mem(h, m, s) i40e_allocate_virt_mem_d(h, m, s) #define i40e_allocate_virt_mem(h, m, s) i40e_allocate_virt_mem_d(h, m, s)
#define i40e_free_virt_mem(h, m) i40e_free_virt_mem_d(h, m) #define i40e_free_virt_mem(h, m) i40e_free_virt_mem_d(h, m)
#define i40e_debug(h, m, s, ...) \ #define i40e_debug(h, m, s, ...) \
do { \ do { \
if (((m) & (h)->debug_mask)) \ if (((m) & (h)->debug_mask)) \
pr_info("i40e %02x.%x " s, \ pr_info("i40e %02x:%02x.%x " s, \
(h)->bus.device, (h)->bus.func, \ (h)->bus.bus_id, (h)->bus.device, \
##__VA_ARGS__); \ (h)->bus.func, ##__VA_ARGS__); \
} while (0) } while (0)
typedef enum i40e_status_code i40e_status; typedef enum i40e_status_code i40e_status;
......
...@@ -280,7 +280,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi) ...@@ -280,7 +280,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi)
{ {
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
int i; unsigned int i, cleared = 0;
/* Since we cannot turn off the Rx timestamp logic if the device is /* Since we cannot turn off the Rx timestamp logic if the device is
* configured for Tx timestamping, we check if Rx timestamping is * configured for Tx timestamping, we check if Rx timestamping is
...@@ -306,14 +306,25 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi) ...@@ -306,14 +306,25 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi)
time_is_before_jiffies(pf->latch_events[i] + HZ)) { time_is_before_jiffies(pf->latch_events[i] + HZ)) {
rd32(hw, I40E_PRTTSYN_RXTIME_H(i)); rd32(hw, I40E_PRTTSYN_RXTIME_H(i));
pf->latch_event_flags &= ~BIT(i); pf->latch_event_flags &= ~BIT(i);
pf->rx_hwtstamp_cleared++; cleared++;
dev_warn(&pf->pdev->dev,
"Clearing a missed Rx timestamp event for RXTIME[%d]\n",
i);
} }
} }
spin_unlock_bh(&pf->ptp_rx_lock); spin_unlock_bh(&pf->ptp_rx_lock);
/* Log a warning if more than 2 timestamps got dropped in the same
* check. We don't want to warn about all drops because it can occur
* in normal scenarios such as PTP frames on multicast addresses we
* aren't listening to. However, administrator should know if this is
* the reason packets aren't receiving timestamps.
*/
if (cleared > 2)
dev_dbg(&pf->pdev->dev,
"Dropped %d missed RXTIME timestamp events\n",
cleared);
/* Finally, update the rx_hwtstamp_cleared counter */
pf->rx_hwtstamp_cleared += cleared;
} }
/** /**
......
This diff is collapsed.
...@@ -253,7 +253,6 @@ struct i40e_tx_buffer { ...@@ -253,7 +253,6 @@ struct i40e_tx_buffer {
}; };
struct i40e_rx_buffer { struct i40e_rx_buffer {
struct sk_buff *skb;
dma_addr_t dma; dma_addr_t dma;
struct page *page; struct page *page;
unsigned int page_offset; unsigned int page_offset;
...@@ -354,6 +353,14 @@ struct i40e_ring { ...@@ -354,6 +353,14 @@ struct i40e_ring {
struct rcu_head rcu; /* to avoid race on free */ struct rcu_head rcu; /* to avoid race on free */
u16 next_to_alloc; u16 next_to_alloc;
struct sk_buff *skb; /* When i40e_clean_rx_ring_irq() must
* return before it sees the EOP for
* the current packet, we save that skb
* here and resume receiving this
* packet the next time
* i40e_clean_rx_ring_irq() is called
* for this ring.
*/
} ____cacheline_internodealigned_in_smp; } ____cacheline_internodealigned_in_smp;
enum i40e_latency_range { enum i40e_latency_range {
......
...@@ -184,6 +184,7 @@ struct i40e_link_status { ...@@ -184,6 +184,7 @@ struct i40e_link_status {
enum i40e_aq_link_speed link_speed; enum i40e_aq_link_speed link_speed;
u8 link_info; u8 link_info;
u8 an_info; u8 an_info;
u8 fec_info;
u8 ext_info; u8 ext_info;
u8 loopback; u8 loopback;
/* is Link Status Event notification to SW enabled */ /* is Link Status Event notification to SW enabled */
...@@ -469,6 +470,7 @@ struct i40e_bus_info { ...@@ -469,6 +470,7 @@ struct i40e_bus_info {
u16 func; u16 func;
u16 device; u16 device;
u16 lan_id; u16 lan_id;
u16 bus_id;
}; };
/* Flow control (FC) parameters */ /* Flow control (FC) parameters */
......
...@@ -239,7 +239,6 @@ struct i40e_tx_buffer { ...@@ -239,7 +239,6 @@ struct i40e_tx_buffer {
}; };
struct i40e_rx_buffer { struct i40e_rx_buffer {
struct sk_buff *skb;
dma_addr_t dma; dma_addr_t dma;
struct page *page; struct page *page;
unsigned int page_offset; unsigned int page_offset;
...@@ -340,6 +339,14 @@ struct i40e_ring { ...@@ -340,6 +339,14 @@ struct i40e_ring {
struct rcu_head rcu; /* to avoid race on free */ struct rcu_head rcu; /* to avoid race on free */
u16 next_to_alloc; u16 next_to_alloc;
struct sk_buff *skb; /* When i40evf_clean_rx_ring_irq() must
* return before it sees the EOP for
* the current packet, we save that skb
* here and resume receiving this
* packet the next time
* i40evf_clean_rx_ring_irq() is called
* for this ring.
*/
} ____cacheline_internodealigned_in_smp; } ____cacheline_internodealigned_in_smp;
enum i40e_latency_range { enum i40e_latency_range {
......
...@@ -158,6 +158,7 @@ struct i40e_link_status { ...@@ -158,6 +158,7 @@ struct i40e_link_status {
enum i40e_aq_link_speed link_speed; enum i40e_aq_link_speed link_speed;
u8 link_info; u8 link_info;
u8 an_info; u8 an_info;
u8 fec_info;
u8 ext_info; u8 ext_info;
u8 loopback; u8 loopback;
/* is Link Status Event notification to SW enabled */ /* is Link Status Event notification to SW enabled */
...@@ -442,6 +443,7 @@ struct i40e_bus_info { ...@@ -442,6 +443,7 @@ struct i40e_bus_info {
u16 func; u16 func;
u16 device; u16 device;
u16 lan_id; u16 lan_id;
u16 bus_id;
}; };
/* Flow control (FC) parameters */ /* Flow control (FC) parameters */
......
...@@ -81,6 +81,7 @@ enum i40e_virtchnl_ops { ...@@ -81,6 +81,7 @@ enum i40e_virtchnl_ops {
I40E_VIRTCHNL_OP_GET_STATS = 15, I40E_VIRTCHNL_OP_GET_STATS = 15,
I40E_VIRTCHNL_OP_FCOE = 16, I40E_VIRTCHNL_OP_FCOE = 16,
I40E_VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */ I40E_VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */
I40E_VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21,
I40E_VIRTCHNL_OP_CONFIG_RSS_KEY = 23, I40E_VIRTCHNL_OP_CONFIG_RSS_KEY = 23,
I40E_VIRTCHNL_OP_CONFIG_RSS_LUT = 24, I40E_VIRTCHNL_OP_CONFIG_RSS_LUT = 24,
I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25, I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25,
......
...@@ -195,6 +195,7 @@ struct i40evf_adapter { ...@@ -195,6 +195,7 @@ struct i40evf_adapter {
u64 hw_csum_rx_error; u64 hw_csum_rx_error;
u32 rx_desc_count; u32 rx_desc_count;
int num_msix_vectors; int num_msix_vectors;
u32 client_pending;
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
u32 flags; u32 flags;
......
...@@ -38,7 +38,7 @@ static const char i40evf_driver_string[] = ...@@ -38,7 +38,7 @@ static const char i40evf_driver_string[] =
#define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 6 #define DRV_VERSION_MINOR 6
#define DRV_VERSION_BUILD 25 #define DRV_VERSION_BUILD 27
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) \ __stringify(DRV_VERSION_BUILD) \
...@@ -2726,6 +2726,7 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2726,6 +2726,7 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->subsystem_device_id = pdev->subsystem_device; hw->subsystem_device_id = pdev->subsystem_device;
hw->bus.device = PCI_SLOT(pdev->devfn); hw->bus.device = PCI_SLOT(pdev->devfn);
hw->bus.func = PCI_FUNC(pdev->devfn); hw->bus.func = PCI_FUNC(pdev->devfn);
hw->bus.bus_id = pdev->bus->number;
/* set up the locks for the AQ, do this only once in probe /* set up the locks for the AQ, do this only once in probe
* and destroy them only once in remove * and destroy them only once in remove
......
...@@ -999,6 +999,10 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, ...@@ -999,6 +999,10 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
if (v_opcode != adapter->current_op) if (v_opcode != adapter->current_op)
return; return;
break; break;
case I40E_VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP:
adapter->client_pending &=
~(BIT(I40E_VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP));
break;
case I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS: { case I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS: {
struct i40e_virtchnl_rss_hena *vrh = struct i40e_virtchnl_rss_hena *vrh =
(struct i40e_virtchnl_rss_hena *)msg; (struct i40e_virtchnl_rss_hena *)msg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment