Merge branch 'i40e'
Aaron Brown says: ==================== Intel Wired LAN Driver Updates This series contains updates to i40e and i40evf, primarily reset handling / refactoring along with a fair amount of minor cleanup. Jesse fixes some spelling, bumps the version and other trivial fixes. Akeem sets a bit that is needed before shutdown in the case of tx_timeout recovery failure. Mitch refactors reset handling along with a whole bunch of clean up. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0e42aa4fb0
|
@ -647,9 +647,8 @@ static u16 i40e_clean_asq(struct i40e_hw *hw)
|
||||||
desc_cb = *desc;
|
desc_cb = *desc;
|
||||||
cb_func(hw, &desc_cb);
|
cb_func(hw, &desc_cb);
|
||||||
}
|
}
|
||||||
memset((void *)desc, 0, sizeof(struct i40e_aq_desc));
|
memset(desc, 0, sizeof(*desc));
|
||||||
memset((void *)details, 0,
|
memset(details, 0, sizeof(*details));
|
||||||
sizeof(struct i40e_asq_cmd_details));
|
|
||||||
ntc++;
|
ntc++;
|
||||||
if (ntc == asq->count)
|
if (ntc == asq->count)
|
||||||
ntc = 0;
|
ntc = 0;
|
||||||
|
|
|
@ -38,7 +38,7 @@ static const char i40e_driver_string[] =
|
||||||
|
|
||||||
#define DRV_VERSION_MAJOR 0
|
#define DRV_VERSION_MAJOR 0
|
||||||
#define DRV_VERSION_MINOR 3
|
#define DRV_VERSION_MINOR 3
|
||||||
#define DRV_VERSION_BUILD 30
|
#define DRV_VERSION_BUILD 31
|
||||||
#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) DRV_KERN
|
__stringify(DRV_VERSION_BUILD) DRV_KERN
|
||||||
|
@ -305,6 +305,7 @@ static void i40e_tx_timeout(struct net_device *netdev)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
netdev_err(netdev, "tx_timeout recovery unsuccessful\n");
|
netdev_err(netdev, "tx_timeout recovery unsuccessful\n");
|
||||||
|
set_bit(__I40E_DOWN, &vsi->state);
|
||||||
i40e_down(vsi);
|
i40e_down(vsi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5331,6 +5332,11 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
|
||||||
/* restart the VSIs that were rebuilt and running before the reset */
|
/* restart the VSIs that were rebuilt and running before the reset */
|
||||||
i40e_pf_unquiesce_all_vsi(pf);
|
i40e_pf_unquiesce_all_vsi(pf);
|
||||||
|
|
||||||
|
if (pf->num_alloc_vfs) {
|
||||||
|
for (v = 0; v < pf->num_alloc_vfs; v++)
|
||||||
|
i40e_reset_vf(&pf->vf[v], true);
|
||||||
|
}
|
||||||
|
|
||||||
/* tell the firmware that we're starting */
|
/* tell the firmware that we're starting */
|
||||||
dv.major_version = DRV_VERSION_MAJOR;
|
dv.major_version = DRV_VERSION_MAJOR;
|
||||||
dv.minor_version = DRV_VERSION_MINOR;
|
dv.minor_version = DRV_VERSION_MINOR;
|
||||||
|
@ -8070,6 +8076,16 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK;
|
val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK;
|
||||||
wr32(hw, I40E_PFGEN_PORTMDIO_NUM, val);
|
wr32(hw, I40E_PFGEN_PORTMDIO_NUM, val);
|
||||||
i40e_flush(hw);
|
i40e_flush(hw);
|
||||||
|
|
||||||
|
if (pci_num_vf(pdev)) {
|
||||||
|
dev_info(&pdev->dev,
|
||||||
|
"Active VFs found, allocating resources.\n");
|
||||||
|
err = i40e_alloc_vfs(pf, pci_num_vf(pdev));
|
||||||
|
if (err)
|
||||||
|
dev_info(&pdev->dev,
|
||||||
|
"Error %d allocating resources for existing VFs\n",
|
||||||
|
err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pfs_found++;
|
pfs_found++;
|
||||||
|
@ -8165,16 +8181,16 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||||
|
|
||||||
i40e_ptp_stop(pf);
|
i40e_ptp_stop(pf);
|
||||||
|
|
||||||
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
|
||||||
i40e_free_vfs(pf);
|
|
||||||
pf->flags &= ~I40E_FLAG_SRIOV_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no more scheduling of any task */
|
/* no more scheduling of any task */
|
||||||
set_bit(__I40E_DOWN, &pf->state);
|
set_bit(__I40E_DOWN, &pf->state);
|
||||||
del_timer_sync(&pf->service_timer);
|
del_timer_sync(&pf->service_timer);
|
||||||
cancel_work_sync(&pf->service_task);
|
cancel_work_sync(&pf->service_task);
|
||||||
|
|
||||||
|
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
||||||
|
i40e_free_vfs(pf);
|
||||||
|
pf->flags &= ~I40E_FLAG_SRIOV_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
i40e_fdir_teardown(pf);
|
i40e_fdir_teardown(pf);
|
||||||
|
|
||||||
/* If there is a switch structure or any orphans, remove them.
|
/* If there is a switch structure or any orphans, remove them.
|
||||||
|
|
|
@ -892,7 +892,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
|
||||||
rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT)))
|
rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* likely incorrect csum if alternate IP extention headers found */
|
/* likely incorrect csum if alternate IP extension headers found */
|
||||||
if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
|
if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -408,18 +408,10 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
|
||||||
"Could not allocate VF broadcast filter\n");
|
"Could not allocate VF broadcast filter\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f) {
|
|
||||||
dev_err(&pf->pdev->dev, "Unable to add ucast filter\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto error_alloc_vsi_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* program mac filter */
|
/* program mac filter */
|
||||||
ret = i40e_sync_vsi_filters(vsi);
|
ret = i40e_sync_vsi_filters(vsi);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
|
dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
|
||||||
goto error_alloc_vsi_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_alloc_vsi_res:
|
error_alloc_vsi_res:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -682,6 +674,7 @@ complete_reset:
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
i40e_alloc_vf_res(vf);
|
i40e_alloc_vf_res(vf);
|
||||||
i40e_enable_vf_mappings(vf);
|
i40e_enable_vf_mappings(vf);
|
||||||
|
set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
|
||||||
|
|
||||||
/* tell the VF the reset is done */
|
/* tell the VF the reset is done */
|
||||||
wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
|
wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
|
||||||
|
@ -847,7 +840,7 @@ void i40e_free_vfs(struct i40e_pf *pf)
|
||||||
*
|
*
|
||||||
* allocate vf resources
|
* allocate vf resources
|
||||||
**/
|
**/
|
||||||
static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
|
int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
|
||||||
{
|
{
|
||||||
struct i40e_vf *vfs;
|
struct i40e_vf *vfs;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
@ -855,14 +848,16 @@ static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
|
||||||
/* Disable interrupt 0 so we don't try to handle the VFLR. */
|
/* Disable interrupt 0 so we don't try to handle the VFLR. */
|
||||||
i40e_irq_dynamic_disable_icr0(pf);
|
i40e_irq_dynamic_disable_icr0(pf);
|
||||||
|
|
||||||
|
/* Check to see if we're just allocating resources for extant VFs */
|
||||||
|
if (pci_num_vf(pf->pdev) != num_alloc_vfs) {
|
||||||
ret = pci_enable_sriov(pf->pdev, num_alloc_vfs);
|
ret = pci_enable_sriov(pf->pdev, num_alloc_vfs);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pf->pdev->dev,
|
dev_err(&pf->pdev->dev,
|
||||||
"pci_enable_sriov failed with error %d!\n", ret);
|
"Failed to enable SR-IOV, error %d.\n", ret);
|
||||||
pf->num_alloc_vfs = 0;
|
pf->num_alloc_vfs = 0;
|
||||||
goto err_iov;
|
goto err_iov;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* allocate memory */
|
/* allocate memory */
|
||||||
vfs = kzalloc(num_alloc_vfs * sizeof(struct i40e_vf), GFP_KERNEL);
|
vfs = kzalloc(num_alloc_vfs * sizeof(struct i40e_vf), GFP_KERNEL);
|
||||||
if (!vfs) {
|
if (!vfs) {
|
||||||
|
@ -1873,6 +1868,7 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
|
||||||
/* clear the bit in GLGEN_VFLRSTAT */
|
/* clear the bit in GLGEN_VFLRSTAT */
|
||||||
wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
|
wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
|
||||||
|
|
||||||
|
if (!test_bit(__I40E_DOWN, &pf->state))
|
||||||
i40e_reset_vf(vf, true);
|
i40e_reset_vf(vf, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ struct i40e_vf {
|
||||||
|
|
||||||
void i40e_free_vfs(struct i40e_pf *pf);
|
void i40e_free_vfs(struct i40e_pf *pf);
|
||||||
int i40e_pci_sriov_configure(struct pci_dev *dev, int num_vfs);
|
int i40e_pci_sriov_configure(struct pci_dev *dev, int num_vfs);
|
||||||
|
int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs);
|
||||||
int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
|
int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
|
||||||
u32 v_retval, u8 *msg, u16 msglen);
|
u32 v_retval, u8 *msg, u16 msglen);
|
||||||
int i40e_vc_process_vflr_event(struct i40e_pf *pf);
|
int i40e_vc_process_vflr_event(struct i40e_pf *pf);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
||||||
* Copyright(c) 2013 Intel Corporation.
|
* Copyright(c) 2013 - 2014 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -722,7 +722,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
|
||||||
rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT)))
|
rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* likely incorrect csum if alternate IP extention headers found */
|
/* likely incorrect csum if alternate IP extension headers found */
|
||||||
if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
|
if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -807,8 +807,8 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
|
||||||
|
|
||||||
rx_desc = I40E_RX_DESC(rx_ring, i);
|
rx_desc = I40E_RX_DESC(rx_ring, i);
|
||||||
qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
|
qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
|
||||||
rx_status = (qword & I40E_RXD_QW1_STATUS_MASK)
|
rx_status = (qword & I40E_RXD_QW1_STATUS_MASK) >>
|
||||||
>> I40E_RXD_QW1_STATUS_SHIFT;
|
I40E_RXD_QW1_STATUS_SHIFT;
|
||||||
|
|
||||||
while (rx_status & (1 << I40E_RX_DESC_STATUS_DD_SHIFT)) {
|
while (rx_status & (1 << I40E_RX_DESC_STATUS_DD_SHIFT)) {
|
||||||
union i40e_rx_desc *next_rxd;
|
union i40e_rx_desc *next_rxd;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
||||||
* Copyright(c) 2013 Intel Corporation.
|
* Copyright(c) 2013 - 2014 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -64,8 +64,6 @@
|
||||||
struct i40e_hw;
|
struct i40e_hw;
|
||||||
typedef void (*I40E_ADMINQ_CALLBACK)(struct i40e_hw *, struct i40e_aq_desc *);
|
typedef void (*I40E_ADMINQ_CALLBACK)(struct i40e_hw *, struct i40e_aq_desc *);
|
||||||
|
|
||||||
#define ETH_ALEN 6
|
|
||||||
|
|
||||||
/* Data type manipulation macros. */
|
/* Data type manipulation macros. */
|
||||||
|
|
||||||
#define I40E_DESC_UNUSED(R) \
|
#define I40E_DESC_UNUSED(R) \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
||||||
* Copyright(c) 2013 Intel Corporation.
|
* Copyright(c) 2013 - 2014 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -164,15 +164,14 @@ struct i40evf_vlan_filter {
|
||||||
/* Driver state. The order of these is important! */
|
/* Driver state. The order of these is important! */
|
||||||
enum i40evf_state_t {
|
enum i40evf_state_t {
|
||||||
__I40EVF_STARTUP, /* driver loaded, probe complete */
|
__I40EVF_STARTUP, /* driver loaded, probe complete */
|
||||||
__I40EVF_FAILED, /* PF communication failed. Fatal. */
|
|
||||||
__I40EVF_REMOVE, /* driver is being unloaded */
|
__I40EVF_REMOVE, /* driver is being unloaded */
|
||||||
__I40EVF_INIT_VERSION_CHECK, /* aq msg sent, awaiting reply */
|
__I40EVF_INIT_VERSION_CHECK, /* aq msg sent, awaiting reply */
|
||||||
__I40EVF_INIT_GET_RESOURCES, /* aq msg sent, awaiting reply */
|
__I40EVF_INIT_GET_RESOURCES, /* aq msg sent, awaiting reply */
|
||||||
__I40EVF_INIT_SW, /* got resources, setting up structs */
|
__I40EVF_INIT_SW, /* got resources, setting up structs */
|
||||||
|
__I40EVF_RESETTING, /* in reset */
|
||||||
/* Below here, watchdog is running */
|
/* Below here, watchdog is running */
|
||||||
__I40EVF_DOWN, /* ready, can be opened */
|
__I40EVF_DOWN, /* ready, can be opened */
|
||||||
__I40EVF_TESTING, /* in ethtool self-test */
|
__I40EVF_TESTING, /* in ethtool self-test */
|
||||||
__I40EVF_RESETTING, /* in reset */
|
|
||||||
__I40EVF_RUNNING, /* opened, working */
|
__I40EVF_RUNNING, /* opened, working */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,47 +184,27 @@ enum i40evf_critical_section_t {
|
||||||
/* board specific private data structure */
|
/* board specific private data structure */
|
||||||
struct i40evf_adapter {
|
struct i40evf_adapter {
|
||||||
struct timer_list watchdog_timer;
|
struct timer_list watchdog_timer;
|
||||||
struct vlan_group *vlgrp;
|
|
||||||
struct work_struct reset_task;
|
struct work_struct reset_task;
|
||||||
struct work_struct adminq_task;
|
struct work_struct adminq_task;
|
||||||
struct delayed_work init_task;
|
struct delayed_work init_task;
|
||||||
struct i40e_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
|
struct i40e_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
|
||||||
struct list_head vlan_filter_list;
|
struct list_head vlan_filter_list;
|
||||||
char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
|
char misc_vector_name[IFNAMSIZ + 9];
|
||||||
|
|
||||||
/* Interrupt Throttle Rate */
|
|
||||||
u32 itr_setting;
|
|
||||||
u16 eitr_low;
|
|
||||||
u16 eitr_high;
|
|
||||||
|
|
||||||
/* TX */
|
/* TX */
|
||||||
struct i40e_ring *tx_rings[I40E_MAX_VSI_QP];
|
struct i40e_ring *tx_rings[I40E_MAX_VSI_QP];
|
||||||
u64 restart_queue;
|
|
||||||
u64 hw_csum_tx_good;
|
|
||||||
u64 lsc_int;
|
|
||||||
u64 hw_tso_ctxt;
|
|
||||||
u64 hw_tso6_ctxt;
|
|
||||||
u32 tx_timeout_count;
|
u32 tx_timeout_count;
|
||||||
struct list_head mac_filter_list;
|
struct list_head mac_filter_list;
|
||||||
#ifdef DEBUG
|
|
||||||
bool detect_tx_hung;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* RX */
|
/* RX */
|
||||||
struct i40e_ring *rx_rings[I40E_MAX_VSI_QP];
|
struct i40e_ring *rx_rings[I40E_MAX_VSI_QP];
|
||||||
int txd_count;
|
int txd_count;
|
||||||
int rxd_count;
|
int rxd_count;
|
||||||
u64 hw_csum_rx_error;
|
u64 hw_csum_rx_error;
|
||||||
u64 hw_rx_no_dma_resources;
|
|
||||||
u64 hw_csum_rx_good;
|
|
||||||
u64 non_eop_descs;
|
|
||||||
int num_msix_vectors;
|
int num_msix_vectors;
|
||||||
struct msix_entry *msix_entries;
|
struct msix_entry *msix_entries;
|
||||||
|
|
||||||
u64 rx_hdr_split;
|
u32 flags;
|
||||||
|
|
||||||
u32 init_state;
|
|
||||||
volatile unsigned long flags;
|
|
||||||
#define I40EVF_FLAG_RX_CSUM_ENABLED (u32)(1)
|
#define I40EVF_FLAG_RX_CSUM_ENABLED (u32)(1)
|
||||||
#define I40EVF_FLAG_RX_1BUF_CAPABLE (u32)(1 << 1)
|
#define I40EVF_FLAG_RX_1BUF_CAPABLE (u32)(1 << 1)
|
||||||
#define I40EVF_FLAG_RX_PS_CAPABLE (u32)(1 << 2)
|
#define I40EVF_FLAG_RX_PS_CAPABLE (u32)(1 << 2)
|
||||||
|
@ -234,6 +213,8 @@ struct i40evf_adapter {
|
||||||
#define I40EVF_FLAG_IMIR_ENABLED (u32)(1 << 5)
|
#define I40EVF_FLAG_IMIR_ENABLED (u32)(1 << 5)
|
||||||
#define I40EVF_FLAG_MQ_CAPABLE (u32)(1 << 6)
|
#define I40EVF_FLAG_MQ_CAPABLE (u32)(1 << 6)
|
||||||
#define I40EVF_FLAG_NEED_LINK_UPDATE (u32)(1 << 7)
|
#define I40EVF_FLAG_NEED_LINK_UPDATE (u32)(1 << 7)
|
||||||
|
#define I40EVF_FLAG_PF_COMMS_FAILED (u32)(1 << 8)
|
||||||
|
#define I40EVF_FLAG_RESET_PENDING (u32)(1 << 9)
|
||||||
/* duplcates for common code */
|
/* duplcates for common code */
|
||||||
#define I40E_FLAG_FDIR_ATR_ENABLED 0
|
#define I40E_FLAG_FDIR_ATR_ENABLED 0
|
||||||
#define I40E_FLAG_DCB_ENABLED 0
|
#define I40E_FLAG_DCB_ENABLED 0
|
||||||
|
@ -251,21 +232,19 @@ struct i40evf_adapter {
|
||||||
#define I40EVF_FLAG_AQ_CONFIGURE_QUEUES (u32)(1 << 6)
|
#define I40EVF_FLAG_AQ_CONFIGURE_QUEUES (u32)(1 << 6)
|
||||||
#define I40EVF_FLAG_AQ_MAP_VECTORS (u32)(1 << 7)
|
#define I40EVF_FLAG_AQ_MAP_VECTORS (u32)(1 << 7)
|
||||||
#define I40EVF_FLAG_AQ_HANDLE_RESET (u32)(1 << 8)
|
#define I40EVF_FLAG_AQ_HANDLE_RESET (u32)(1 << 8)
|
||||||
|
|
||||||
/* OS defined structs */
|
/* OS defined structs */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
struct net_device_stats net_stats;
|
struct net_device_stats net_stats;
|
||||||
|
|
||||||
/* structs defined in i40e_vf.h */
|
struct i40e_hw hw; /* defined in i40e_type.h */
|
||||||
struct i40e_hw hw;
|
|
||||||
|
|
||||||
enum i40evf_state_t state;
|
enum i40evf_state_t state;
|
||||||
volatile unsigned long crit_section;
|
volatile unsigned long crit_section;
|
||||||
u64 tx_busy;
|
|
||||||
|
|
||||||
struct work_struct watchdog_task;
|
struct work_struct watchdog_task;
|
||||||
bool netdev_registered;
|
bool netdev_registered;
|
||||||
bool dev_closed;
|
|
||||||
bool link_up;
|
bool link_up;
|
||||||
enum i40e_virtchnl_ops current_op;
|
enum i40e_virtchnl_ops current_op;
|
||||||
struct i40e_virtchnl_vf_resource *vf_res; /* incl. all VSIs */
|
struct i40e_virtchnl_vf_resource *vf_res; /* incl. all VSIs */
|
||||||
|
@ -276,11 +255,6 @@ struct i40evf_adapter {
|
||||||
u32 aq_wait_count;
|
u32 aq_wait_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct i40evf_info {
|
|
||||||
enum i40e_mac_type mac;
|
|
||||||
unsigned int flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* needed by i40evf_ethtool.c */
|
/* needed by i40evf_ethtool.c */
|
||||||
extern char i40evf_driver_name[];
|
extern char i40evf_driver_name[];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
||||||
* Copyright(c) 2013 Intel Corporation.
|
* Copyright(c) 2013 - 2014 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -511,9 +511,10 @@ static int i40evf_request_misc_irq(struct i40evf_adapter *adapter)
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sprintf(adapter->name[0], "i40evf:mbx");
|
sprintf(adapter->misc_vector_name, "i40evf:mbx");
|
||||||
err = request_irq(adapter->msix_entries[0].vector,
|
err = request_irq(adapter->msix_entries[0].vector,
|
||||||
&i40evf_msix_aq, 0, adapter->name[0], netdev);
|
&i40evf_msix_aq, 0,
|
||||||
|
adapter->misc_vector_name, netdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&adapter->pdev->dev,
|
dev_err(&adapter->pdev->dev,
|
||||||
"request_irq for msix_aq failed: %d\n", err);
|
"request_irq for msix_aq failed: %d\n", err);
|
||||||
|
@ -963,16 +964,18 @@ void i40evf_down(struct i40evf_adapter *adapter)
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
struct i40evf_mac_filter *f;
|
struct i40evf_mac_filter *f;
|
||||||
|
|
||||||
/* remove all MAC filters from the VSI */
|
/* remove all MAC filters */
|
||||||
list_for_each_entry(f, &adapter->mac_filter_list, list) {
|
list_for_each_entry(f, &adapter->mac_filter_list, list) {
|
||||||
f->remove = true;
|
f->remove = true;
|
||||||
}
|
}
|
||||||
|
if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) &&
|
||||||
|
adapter->state != __I40EVF_RESETTING) {
|
||||||
adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
|
adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
|
||||||
/* disable receives */
|
/* disable receives */
|
||||||
adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
|
adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
|
||||||
mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
|
mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
|
||||||
msleep(20);
|
msleep(20);
|
||||||
|
}
|
||||||
netif_tx_disable(netdev);
|
netif_tx_disable(netdev);
|
||||||
|
|
||||||
netif_tx_stop_all_queues(netdev);
|
netif_tx_stop_all_queues(netdev);
|
||||||
|
@ -1291,19 +1294,47 @@ static void i40evf_watchdog_task(struct work_struct *work)
|
||||||
watchdog_task);
|
watchdog_task);
|
||||||
struct i40e_hw *hw = &adapter->hw;
|
struct i40e_hw *hw = &adapter->hw;
|
||||||
|
|
||||||
if (adapter->state < __I40EVF_DOWN)
|
|
||||||
goto watchdog_done;
|
|
||||||
|
|
||||||
if (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section))
|
if (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section))
|
||||||
|
goto restart_watchdog;
|
||||||
|
|
||||||
|
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) {
|
||||||
|
dev_info(&adapter->pdev->dev, "Checking for redemption\n");
|
||||||
|
if ((rd32(hw, I40E_VFGEN_RSTAT) & 0x3) == I40E_VFR_VFACTIVE) {
|
||||||
|
/* A chance for redemption! */
|
||||||
|
dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attempting reinit.\n");
|
||||||
|
adapter->state = __I40EVF_STARTUP;
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_PF_COMMS_FAILED;
|
||||||
|
schedule_delayed_work(&adapter->init_task, 10);
|
||||||
|
clear_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||||
|
&adapter->crit_section);
|
||||||
|
/* Don't reschedule the watchdog, since we've restarted
|
||||||
|
* the init task. When init_task contacts the PF and
|
||||||
|
* gets everything set up again, it'll restart the
|
||||||
|
* watchdog for us. Down, boy. Sit. Stay. Woof.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adapter->aq_pending = 0;
|
||||||
|
adapter->aq_required = 0;
|
||||||
|
adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
|
||||||
|
goto watchdog_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((adapter->state < __I40EVF_DOWN) ||
|
||||||
|
(adapter->flags & I40EVF_FLAG_RESET_PENDING))
|
||||||
goto watchdog_done;
|
goto watchdog_done;
|
||||||
|
|
||||||
/* check for unannounced reset */
|
/* check for reset */
|
||||||
if ((adapter->state != __I40EVF_RESETTING) &&
|
if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING) &&
|
||||||
(rd32(hw, I40E_VFGEN_RSTAT) & 0x3) != I40E_VFR_VFACTIVE) {
|
(rd32(hw, I40E_VFGEN_RSTAT) & 0x3) != I40E_VFR_VFACTIVE) {
|
||||||
adapter->state = __I40EVF_RESETTING;
|
adapter->state = __I40EVF_RESETTING;
|
||||||
|
adapter->flags |= I40EVF_FLAG_RESET_PENDING;
|
||||||
|
dev_err(&adapter->pdev->dev, "Hardware reset detected.\n");
|
||||||
|
dev_info(&adapter->pdev->dev, "Scheduling reset task\n");
|
||||||
schedule_work(&adapter->reset_task);
|
schedule_work(&adapter->reset_task);
|
||||||
dev_info(&adapter->pdev->dev, "%s: hardware reset detected\n",
|
adapter->aq_pending = 0;
|
||||||
__func__);
|
adapter->aq_required = 0;
|
||||||
|
adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
|
||||||
goto watchdog_done;
|
goto watchdog_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,13 +1389,15 @@ static void i40evf_watchdog_task(struct work_struct *work)
|
||||||
|
|
||||||
i40evf_irq_enable(adapter, true);
|
i40evf_irq_enable(adapter, true);
|
||||||
i40evf_fire_sw_int(adapter, 0xFF);
|
i40evf_fire_sw_int(adapter, 0xFF);
|
||||||
|
|
||||||
watchdog_done:
|
watchdog_done:
|
||||||
|
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
||||||
|
restart_watchdog:
|
||||||
if (adapter->aq_required)
|
if (adapter->aq_required)
|
||||||
mod_timer(&adapter->watchdog_timer,
|
mod_timer(&adapter->watchdog_timer,
|
||||||
jiffies + msecs_to_jiffies(20));
|
jiffies + msecs_to_jiffies(20));
|
||||||
else
|
else
|
||||||
mod_timer(&adapter->watchdog_timer, jiffies + (HZ * 2));
|
mod_timer(&adapter->watchdog_timer, jiffies + (HZ * 2));
|
||||||
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
|
||||||
schedule_work(&adapter->adminq_task);
|
schedule_work(&adapter->adminq_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,6 +1444,8 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
|
||||||
i40e_flush(hw);
|
i40e_flush(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define I40EVF_RESET_WAIT_MS 100
|
||||||
|
#define I40EVF_RESET_WAIT_COUNT 200
|
||||||
/**
|
/**
|
||||||
* i40evf_reset_task - Call-back task to handle hardware reset
|
* i40evf_reset_task - Call-back task to handle hardware reset
|
||||||
* @work: pointer to work_struct
|
* @work: pointer to work_struct
|
||||||
|
@ -1421,8 +1456,9 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
|
||||||
**/
|
**/
|
||||||
static void i40evf_reset_task(struct work_struct *work)
|
static void i40evf_reset_task(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct i40evf_adapter *adapter =
|
struct i40evf_adapter *adapter = container_of(work,
|
||||||
container_of(work, struct i40evf_adapter, reset_task);
|
struct i40evf_adapter,
|
||||||
|
reset_task);
|
||||||
struct i40e_hw *hw = &adapter->hw;
|
struct i40e_hw *hw = &adapter->hw;
|
||||||
int i = 0, err;
|
int i = 0, err;
|
||||||
uint32_t rstat_val;
|
uint32_t rstat_val;
|
||||||
|
@ -1430,22 +1466,56 @@ static void i40evf_reset_task(struct work_struct *work)
|
||||||
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||||
&adapter->crit_section))
|
&adapter->crit_section))
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
/* poll until we see the reset actually happen */
|
||||||
/* wait until the reset is complete */
|
for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
|
||||||
for (i = 0; i < 20; i++) {
|
|
||||||
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
|
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
|
||||||
I40E_VFGEN_RSTAT_VFR_STATE_MASK;
|
I40E_VFGEN_RSTAT_VFR_STATE_MASK;
|
||||||
if (rstat_val == I40E_VFR_COMPLETED)
|
if (rstat_val != I40E_VFR_VFACTIVE) {
|
||||||
|
dev_info(&adapter->pdev->dev, "Reset now occurring\n");
|
||||||
break;
|
break;
|
||||||
else
|
} else {
|
||||||
mdelay(100);
|
msleep(I40EVF_RESET_WAIT_MS);
|
||||||
}
|
}
|
||||||
if (i == 20) {
|
}
|
||||||
|
if (i == I40EVF_RESET_WAIT_COUNT) {
|
||||||
|
dev_err(&adapter->pdev->dev, "Reset was not detected\n");
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
|
||||||
|
goto continue_reset; /* act like the reset happened */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait until the reset is complete and the PF is responding to us */
|
||||||
|
for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
|
||||||
|
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
|
||||||
|
I40E_VFGEN_RSTAT_VFR_STATE_MASK;
|
||||||
|
if (rstat_val == I40E_VFR_VFACTIVE) {
|
||||||
|
dev_info(&adapter->pdev->dev, "Reset is complete. Reinitializing.\n");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
msleep(I40EVF_RESET_WAIT_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == I40EVF_RESET_WAIT_COUNT) {
|
||||||
/* reset never finished */
|
/* reset never finished */
|
||||||
dev_info(&adapter->pdev->dev, "%s: reset never finished: %x\n",
|
dev_err(&adapter->pdev->dev, "Reset never finished (%x). PF driver is dead, and so am I.\n",
|
||||||
__func__, rstat_val);
|
rstat_val);
|
||||||
/* carry on anyway */
|
adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED;
|
||||||
|
|
||||||
|
if (netif_running(adapter->netdev))
|
||||||
|
i40evf_close(adapter->netdev);
|
||||||
|
|
||||||
|
i40evf_free_misc_irq(adapter);
|
||||||
|
i40evf_reset_interrupt_capability(adapter);
|
||||||
|
i40evf_free_queues(adapter);
|
||||||
|
kfree(adapter->vf_res);
|
||||||
|
i40evf_shutdown_adminq(hw);
|
||||||
|
adapter->netdev->flags &= ~IFF_UP;
|
||||||
|
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
||||||
|
return; /* Do not attempt to reinit. It's dead, Jim. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue_reset:
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
|
||||||
|
|
||||||
i40evf_down(adapter);
|
i40evf_down(adapter);
|
||||||
adapter->state = __I40EVF_RESETTING;
|
adapter->state = __I40EVF_RESETTING;
|
||||||
|
|
||||||
|
@ -1505,6 +1575,9 @@ static void i40evf_adminq_task(struct work_struct *work)
|
||||||
i40e_status ret;
|
i40e_status ret;
|
||||||
u16 pending;
|
u16 pending;
|
||||||
|
|
||||||
|
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED)
|
||||||
|
return;
|
||||||
|
|
||||||
event.msg_size = I40EVF_MAX_AQ_BUF_SIZE;
|
event.msg_size = I40EVF_MAX_AQ_BUF_SIZE;
|
||||||
event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL);
|
event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL);
|
||||||
if (!event.msg_buf) {
|
if (!event.msg_buf) {
|
||||||
|
@ -1636,6 +1709,10 @@ static int i40evf_open(struct net_device *netdev)
|
||||||
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) {
|
||||||
|
dev_err(&adapter->pdev->dev, "Unable to open device due to PF driver failure.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
if (adapter->state != __I40EVF_DOWN)
|
if (adapter->state != __I40EVF_DOWN)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
@ -1690,8 +1767,12 @@ static int i40evf_close(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
|
if (adapter->state <= __I40EVF_DOWN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* signal that we are down to the interrupt handler */
|
/* signal that we are down to the interrupt handler */
|
||||||
adapter->state = __I40EVF_DOWN;
|
adapter->state = __I40EVF_DOWN;
|
||||||
|
|
||||||
set_bit(__I40E_DOWN, &adapter->vsi.state);
|
set_bit(__I40E_DOWN, &adapter->vsi.state);
|
||||||
|
|
||||||
i40evf_down(adapter);
|
i40evf_down(adapter);
|
||||||
|
@ -1842,6 +1923,8 @@ static void i40evf_init_task(struct work_struct *work)
|
||||||
switch (adapter->state) {
|
switch (adapter->state) {
|
||||||
case __I40EVF_STARTUP:
|
case __I40EVF_STARTUP:
|
||||||
/* driver loaded, probe complete */
|
/* driver loaded, probe complete */
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_PF_COMMS_FAILED;
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
|
||||||
err = i40e_set_mac_type(hw);
|
err = i40e_set_mac_type(hw);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_info(&pdev->dev, "%s: set_mac_type failed: %d\n",
|
dev_info(&pdev->dev, "%s: set_mac_type failed: %d\n",
|
||||||
|
@ -2005,9 +2088,11 @@ static void i40evf_init_task(struct work_struct *work)
|
||||||
adapter->vsi.tx_itr_setting = I40E_ITR_DYNAMIC;
|
adapter->vsi.tx_itr_setting = I40E_ITR_DYNAMIC;
|
||||||
adapter->vsi.netdev = adapter->netdev;
|
adapter->vsi.netdev = adapter->netdev;
|
||||||
|
|
||||||
|
if (!adapter->netdev_registered) {
|
||||||
err = register_netdev(netdev);
|
err = register_netdev(netdev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_register;
|
goto err_register;
|
||||||
|
}
|
||||||
|
|
||||||
adapter->netdev_registered = true;
|
adapter->netdev_registered = true;
|
||||||
|
|
||||||
|
@ -2031,17 +2116,16 @@ err_register:
|
||||||
i40evf_free_misc_irq(adapter);
|
i40evf_free_misc_irq(adapter);
|
||||||
err_sw_init:
|
err_sw_init:
|
||||||
i40evf_reset_interrupt_capability(adapter);
|
i40evf_reset_interrupt_capability(adapter);
|
||||||
adapter->state = __I40EVF_FAILED;
|
|
||||||
err_alloc:
|
err_alloc:
|
||||||
kfree(adapter->vf_res);
|
kfree(adapter->vf_res);
|
||||||
adapter->vf_res = NULL;
|
adapter->vf_res = NULL;
|
||||||
err:
|
err:
|
||||||
|
if (hw->aq.asq.count)
|
||||||
|
i40evf_shutdown_adminq(hw); /* ignore error */
|
||||||
/* Things went into the weeds, so try again later */
|
/* Things went into the weeds, so try again later */
|
||||||
if (++adapter->aq_wait_count > I40EVF_AQ_MAX_ERR) {
|
if (++adapter->aq_wait_count > I40EVF_AQ_MAX_ERR) {
|
||||||
dev_err(&pdev->dev, "Failed to communicate with PF; giving up.\n");
|
dev_err(&pdev->dev, "Failed to communicate with PF; giving up.\n");
|
||||||
if (hw->aq.asq.count)
|
adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED;
|
||||||
i40evf_shutdown_adminq(hw); /* ignore error */
|
|
||||||
adapter->state = __I40EVF_FAILED;
|
|
||||||
return; /* do not reschedule */
|
return; /* do not reschedule */
|
||||||
}
|
}
|
||||||
schedule_delayed_work(&adapter->init_task, HZ * 3);
|
schedule_delayed_work(&adapter->init_task, HZ * 3);
|
||||||
|
@ -2271,6 +2355,7 @@ static void i40evf_remove(struct pci_dev *pdev)
|
||||||
struct i40e_hw *hw = &adapter->hw;
|
struct i40e_hw *hw = &adapter->hw;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&adapter->init_task);
|
cancel_delayed_work_sync(&adapter->init_task);
|
||||||
|
cancel_work_sync(&adapter->reset_task);
|
||||||
|
|
||||||
if (adapter->netdev_registered) {
|
if (adapter->netdev_registered) {
|
||||||
unregister_netdev(netdev);
|
unregister_netdev(netdev);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
* Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
|
||||||
* Copyright(c) 2013 Intel Corporation.
|
* Copyright(c) 2013 - 2014 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -43,6 +43,9 @@ static int i40evf_send_pf_msg(struct i40evf_adapter *adapter,
|
||||||
struct i40e_hw *hw = &adapter->hw;
|
struct i40e_hw *hw = &adapter->hw;
|
||||||
i40e_status err;
|
i40e_status err;
|
||||||
|
|
||||||
|
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED)
|
||||||
|
return 0; /* nothing to see here, move along */
|
||||||
|
|
||||||
err = i40e_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
|
err = i40e_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
dev_err(&adapter->pdev->dev, "Unable to send opcode %d to PF, error %d, aq status %d\n",
|
dev_err(&adapter->pdev->dev, "Unable to send opcode %d to PF, error %d, aq status %d\n",
|
||||||
|
@ -689,10 +692,12 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
|
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
|
||||||
adapter->state = __I40EVF_RESETTING;
|
dev_info(&adapter->pdev->dev, "PF reset warning received\n");
|
||||||
|
if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) {
|
||||||
|
adapter->flags |= I40EVF_FLAG_RESET_PENDING;
|
||||||
|
dev_info(&adapter->pdev->dev, "Scheduling reset task\n");
|
||||||
schedule_work(&adapter->reset_task);
|
schedule_work(&adapter->reset_task);
|
||||||
dev_info(&adapter->pdev->dev,
|
}
|
||||||
"%s: hardware reset pending\n", __func__);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(&adapter->pdev->dev,
|
dev_err(&adapter->pdev->dev,
|
||||||
|
|
Loading…
Reference in a new issue