Commit 89c64d75 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6

parents 4dc6ec26 4f6290cf
...@@ -144,7 +144,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) ...@@ -144,7 +144,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* @rar_count: receive address registers * @rar_count: receive address registers
* *
* Setups the receive address registers by setting the base receive address * Setup the receive address registers by setting the base receive address
* register to the devices MAC address and clearing all the other receive * register to the devices MAC address and clearing all the other receive
* address registers to 0. * address registers to 0.
**/ **/
...@@ -1181,7 +1181,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) ...@@ -1181,7 +1181,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
* of pause frames. In this case, we had to advertise * of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise Rx * FULL flow control because we could not advertise Rx
* ONLY. Hence, we must now check to see if we need to * ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames. * turn OFF the TRANSMISSION of PAUSE frames.
*/ */
if (hw->fc.requested_mode == e1000_fc_full) { if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full; hw->fc.current_mode = e1000_fc_full;
......
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
#define IXGBE_MAX_VF_FUNCTIONS 64 #define IXGBE_MAX_VF_FUNCTIONS 64
#define IXGBE_MAX_VFTA_ENTRIES 128 #define IXGBE_MAX_VFTA_ENTRIES 128
#define MAX_EMULATION_MAC_ADDRS 16 #define MAX_EMULATION_MAC_ADDRS 16
#define IXGBE_MAX_PF_MACVLANS 15
#define VMDQ_P(p) ((p) + adapter->num_vfs) #define VMDQ_P(p) ((p) + adapter->num_vfs)
struct vf_data_storage { struct vf_data_storage {
...@@ -121,6 +122,15 @@ struct vf_data_storage { ...@@ -121,6 +122,15 @@ struct vf_data_storage {
u16 tx_rate; u16 tx_rate;
}; };
struct vf_macvlans {
struct list_head l;
int vf;
int rar_entry;
bool free;
bool is_macvlan;
u8 vf_macvlan[ETH_ALEN];
};
/* wrapper around a pointer to a socket buffer, /* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */ * so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer { struct ixgbe_tx_buffer {
...@@ -331,10 +341,52 @@ struct ixgbe_q_vector { ...@@ -331,10 +341,52 @@ struct ixgbe_q_vector {
/* board specific private data structure */ /* board specific private data structure */
struct ixgbe_adapter { struct ixgbe_adapter {
struct timer_list watchdog_timer; unsigned long state;
/* Some features need tri-state capability,
* thus the additional *_CAPABLE flags.
*/
u32 flags;
#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
#define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 23)
#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 24)
#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 25)
#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 26)
#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 27)
#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 28)
#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 29)
u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
#define IXGBE_FLAG2_TEMP_SENSOR_EVENT (u32)(1 << 3)
#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4)
#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5)
#define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6)
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number; u16 bd_number;
struct work_struct reset_task;
struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
/* DCB parameters */ /* DCB parameters */
...@@ -377,43 +429,6 @@ struct ixgbe_adapter { ...@@ -377,43 +429,6 @@ struct ixgbe_adapter {
u32 alloc_rx_page_failed; u32 alloc_rx_page_failed;
u32 alloc_rx_buff_failed; u32 alloc_rx_buff_failed;
/* Some features need tri-state capability,
* thus the additional *_CAPABLE flags.
*/
u32 flags;
#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23)
#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24)
#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25)
#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26)
#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27)
#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28)
#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29)
#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30)
u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
/* default to trying for four seconds */ /* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
...@@ -434,7 +449,6 @@ struct ixgbe_adapter { ...@@ -434,7 +449,6 @@ struct ixgbe_adapter {
u32 rx_eitr_param; u32 rx_eitr_param;
u32 tx_eitr_param; u32 tx_eitr_param;
unsigned long state;
u64 tx_busy; u64 tx_busy;
unsigned int tx_ring_count; unsigned int tx_ring_count;
unsigned int rx_ring_count; unsigned int rx_ring_count;
...@@ -443,15 +457,12 @@ struct ixgbe_adapter { ...@@ -443,15 +457,12 @@ struct ixgbe_adapter {
bool link_up; bool link_up;
unsigned long link_check_timeout; unsigned long link_check_timeout;
struct work_struct watchdog_task; struct work_struct service_task;
struct work_struct sfp_task; struct timer_list service_timer;
struct timer_list sfp_timer;
struct work_struct multispeed_fiber_task;
struct work_struct sfp_config_module_task;
u32 fdir_pballoc; u32 fdir_pballoc;
u32 atr_sample_rate; u32 atr_sample_rate;
unsigned long fdir_overflow; /* number of times ATR was backed off */
spinlock_t fdir_perfect_lock; spinlock_t fdir_perfect_lock;
struct work_struct fdir_reinit_task;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
struct ixgbe_fcoe fcoe; struct ixgbe_fcoe fcoe;
#endif /* IXGBE_FCOE */ #endif /* IXGBE_FCOE */
...@@ -462,7 +473,6 @@ struct ixgbe_adapter { ...@@ -462,7 +473,6 @@ struct ixgbe_adapter {
int node; int node;
u32 led_reg; u32 led_reg;
struct work_struct check_overtemp_task;
u32 interrupt_event; u32 interrupt_event;
char lsc_int_name[IFNAMSIZ + 9]; char lsc_int_name[IFNAMSIZ + 9];
...@@ -471,13 +481,17 @@ struct ixgbe_adapter { ...@@ -471,13 +481,17 @@ struct ixgbe_adapter {
unsigned int num_vfs; unsigned int num_vfs;
struct vf_data_storage *vfinfo; struct vf_data_storage *vfinfo;
int vf_rate_link_speed; int vf_rate_link_speed;
struct vf_macvlans vf_mvs;
struct vf_macvlans *mv_list;
bool antispoofing_enabled;
}; };
enum ixbge_state_t { enum ixbge_state_t {
__IXGBE_TESTING, __IXGBE_TESTING,
__IXGBE_RESETTING, __IXGBE_RESETTING,
__IXGBE_DOWN, __IXGBE_DOWN,
__IXGBE_SFP_MODULE_NOT_FOUND __IXGBE_SERVICE_SCHED,
__IXGBE_IN_SFP_INIT,
}; };
struct ixgbe_rsc_cb { struct ixgbe_rsc_cb {
......
...@@ -368,6 +368,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) ...@@ -368,6 +368,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_T3_LOM: case IXGBE_DEV_ID_82599_T3_LOM:
media_type = ixgbe_media_type_copper; media_type = ixgbe_media_type_copper;
break; break;
case IXGBE_DEV_ID_82599_LS:
media_type = ixgbe_media_type_fiber_lco;
break;
default: default:
media_type = ixgbe_media_type_unknown; media_type = ixgbe_media_type_unknown;
break; break;
......
...@@ -1189,6 +1189,28 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) ...@@ -1189,6 +1189,28 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
udelay(50); udelay(50);
} }
if (i == timeout) {
hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
"not granted.\n");
/*
* this release is particularly important because our attempts
* above to get the semaphore may have succeeded, and if there
* was a timeout, we should unconditionally clear the semaphore
* bits to free the driver to make progress
*/
ixgbe_release_eeprom_semaphore(hw);
udelay(50);
/*
* one last try
* If the SMBI bit is 0 when we read it, then the bit will be
* set and we have the semaphore
*/
swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
if (!(swsm & IXGBE_SWSM_SMBI))
status = 0;
}
/* Now get the semaphore between SW/FW through the SWESMBI bit */ /* Now get the semaphore between SW/FW through the SWESMBI bit */
if (status == 0) { if (status == 0) {
for (i = 0; i < timeout; i++) { for (i = 0; i < timeout; i++) {
......
...@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { ...@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)}, {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
{"fdir_match", IXGBE_STAT(stats.fdirmatch)}, {"fdir_match", IXGBE_STAT(stats.fdirmatch)},
{"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, {"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
{"fdir_overflow", IXGBE_STAT(fdir_overflow)},
{"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)}, {"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)},
{"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)}, {"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)},
{"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)}, {"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
......
...@@ -126,6 +126,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { ...@@ -126,6 +126,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
board_X540 }, board_X540 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2),
board_82599 }, board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS),
board_82599 },
/* required last entry */ /* required last entry */
{0, } {0, }
...@@ -191,6 +193,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -191,6 +193,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
} }
static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
{
if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
!test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
schedule_work(&adapter->service_task);
}
static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
{
BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
/* flush memory to make sure state is correct before next watchog */
smp_mb__before_clear_bit();
clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
}
struct ixgbe_reg_info { struct ixgbe_reg_info {
u32 ofs; u32 ofs;
char *name; char *name;
...@@ -817,7 +835,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) ...@@ -817,7 +835,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
static void ixgbe_tx_timeout(struct net_device *netdev); /**
* ixgbe_tx_timeout_reset - initiate reset due to Tx timeout
* @adapter: driver private struct
**/
static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
{
/* Do the reset outside of interrupt context */
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
ixgbe_service_event_schedule(adapter);
}
}
/** /**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
...@@ -899,7 +929,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, ...@@ -899,7 +929,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
adapter->tx_timeout_count + 1, tx_ring->queue_index); adapter->tx_timeout_count + 1, tx_ring->queue_index);
/* schedule immediate reset if we believe we hung */ /* schedule immediate reset if we believe we hung */
ixgbe_tx_timeout(adapter->netdev); ixgbe_tx_timeout_reset(adapter);
/* the adapter is about to reset, no point in enabling stuff */ /* the adapter is about to reset, no point in enabling stuff */
return true; return true;
...@@ -1797,35 +1827,51 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) ...@@ -1797,35 +1827,51 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
} }
/** /**
* ixgbe_check_overtemp_task - worker thread to check over tempurature * ixgbe_check_overtemp_subtask - check for over tempurature
* @work: pointer to work_struct containing our data * @adapter: pointer to adapter
**/ **/
static void ixgbe_check_overtemp_task(struct work_struct *work) static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
check_overtemp_task);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = adapter->interrupt_event; u32 eicr = adapter->interrupt_event;
if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)) if (test_bit(__IXGBE_DOWN, &adapter->state))
return;
if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_EVENT))
return; return;
adapter->flags2 &= ~IXGBE_FLAG2_TEMP_SENSOR_EVENT;
switch (hw->device_id) { switch (hw->device_id) {
case IXGBE_DEV_ID_82599_T3_LOM: { case IXGBE_DEV_ID_82599_T3_LOM:
u32 autoneg; /*
bool link_up = false; * Since the warning interrupt is for both ports
* we don't have to check if:
* - This interrupt wasn't for our port.
* - We may have missed the interrupt so always have to
* check if we got a LSC
*/
if (!(eicr & IXGBE_EICR_GPI_SDP0) &&
!(eicr & IXGBE_EICR_LSC))
return;
if (!(eicr & IXGBE_EICR_LSC) && hw->mac.ops.check_link) {
u32 autoneg;
bool link_up = false;
if (hw->mac.ops.check_link)
hw->mac.ops.check_link(hw, &autoneg, &link_up, false); hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || if (link_up)
(eicr & IXGBE_EICR_LSC)) return;
/* Check if this is due to overtemp */ }
if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
break; /* Check if this is not due to overtemp */
return; if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP)
} return;
break;
default: default:
if (!(eicr & IXGBE_EICR_GPI_SDP0)) if (!(eicr & IXGBE_EICR_GPI_SDP0))
return; return;
...@@ -1835,8 +1881,8 @@ static void ixgbe_check_overtemp_task(struct work_struct *work) ...@@ -1835,8 +1881,8 @@ static void ixgbe_check_overtemp_task(struct work_struct *work)
"Network adapter has been stopped because it has over heated. " "Network adapter has been stopped because it has over heated. "
"Restart the computer. If the problem persists, " "Restart the computer. If the problem persists, "
"power off the system and replace the adapter\n"); "power off the system and replace the adapter\n");
/* write to clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); adapter->interrupt_event = 0;
} }
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
...@@ -1858,15 +1904,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) ...@@ -1858,15 +1904,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
if (eicr & IXGBE_EICR_GPI_SDP2) { if (eicr & IXGBE_EICR_GPI_SDP2) {
/* Clear the interrupt */ /* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
if (!test_bit(__IXGBE_DOWN, &adapter->state)) if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
schedule_work(&adapter->sfp_config_module_task); adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
ixgbe_service_event_schedule(adapter);
}
} }
if (eicr & IXGBE_EICR_GPI_SDP1) { if (eicr & IXGBE_EICR_GPI_SDP1) {
/* Clear the interrupt */ /* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
if (!test_bit(__IXGBE_DOWN, &adapter->state)) if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
schedule_work(&adapter->multispeed_fiber_task); adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
ixgbe_service_event_schedule(adapter);
}
} }
} }
...@@ -1880,7 +1930,7 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) ...@@ -1880,7 +1930,7 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
if (!test_bit(__IXGBE_DOWN, &adapter->state)) { if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
schedule_work(&adapter->watchdog_task); ixgbe_service_event_schedule(adapter);
} }
} }
...@@ -1908,26 +1958,32 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) ...@@ -1908,26 +1958,32 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
switch (hw->mac.type) { switch (hw->mac.type) {
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
ixgbe_check_sfp_event(adapter, eicr);
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
adapter->interrupt_event = eicr;
schedule_work(&adapter->check_overtemp_task);
}
/* now fallthrough to handle Flow Director */
case ixgbe_mac_X540: case ixgbe_mac_X540:
/* Handle Flow Director Full threshold interrupt */ /* Handle Flow Director Full threshold interrupt */
if (eicr & IXGBE_EICR_FLOW_DIR) { if (eicr & IXGBE_EICR_FLOW_DIR) {
int reinit_count = 0;
int i; int i;
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
/* Disable transmits before FDIR Re-initialization */
netif_tx_stop_all_queues(netdev);
for (i = 0; i < adapter->num_tx_queues; i++) { for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring = struct ixgbe_ring *ring = adapter->tx_ring[i];
adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE, if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
&tx_ring->state)) &ring->state))
schedule_work(&adapter->fdir_reinit_task); reinit_count++;
}
if (reinit_count) {
/* no more flow director interrupts until after init */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
eicr &= ~IXGBE_EICR_FLOW_DIR;
adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
ixgbe_service_event_schedule(adapter);
}
}
ixgbe_check_sfp_event(adapter, eicr);
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
adapter->interrupt_event = eicr;
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
ixgbe_service_event_schedule(adapter);
} }
} }
break; break;
...@@ -1937,8 +1993,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) ...@@ -1937,8 +1993,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr);
/* re-enable the original interrupt state, no lsc, no queues */
if (!test_bit(__IXGBE_DOWN, &adapter->state)) if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr &
~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE));
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -2523,8 +2581,11 @@ static irqreturn_t ixgbe_intr(int irq, void *data) ...@@ -2523,8 +2581,11 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_sfp_event(adapter, eicr); ixgbe_check_sfp_event(adapter, eicr);
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
adapter->interrupt_event = eicr; if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
schedule_work(&adapter->check_overtemp_task); adapter->interrupt_event = eicr;
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
ixgbe_service_event_schedule(adapter);
}
} }
break; break;
default: default:
...@@ -3188,7 +3249,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) ...@@ -3188,7 +3249,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* enable Tx loopback for VF/PF communication */ /* enable Tx loopback for VF/PF communication */
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Enable MAC Anti-Spoofing */ /* Enable MAC Anti-Spoofing */
hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), hw->mac.ops.set_mac_anti_spoofing(hw,
(adapter->antispoofing_enabled =
(adapter->num_vfs != 0)),
adapter->num_vfs); adapter->num_vfs);
} }
...@@ -3497,7 +3560,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev) ...@@ -3497,7 +3560,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
unsigned int vfn = adapter->num_vfs; unsigned int vfn = adapter->num_vfs;
unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1); unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
int count = 0; int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */ /* return ENOMEM indicating insufficient memory for addresses */
...@@ -3770,31 +3833,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw) ...@@ -3770,31 +3833,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
**/ **/
static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; /*
* We are assuming the worst case scenerio here, and that
* is that an SFP was inserted/removed after the reset
* but before SFP detection was enabled. As such the best
* solution is to just start searching as soon as we start
*/
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
if (hw->phy.multispeed_fiber) { adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
/*
* In multispeed fiber setups, the device may not have
* had a physical connection when the driver loaded.
* If that's the case, the initial link configuration
* couldn't get the MAC into 10G or 1G mode, so we'll
* never have a link status change interrupt fire.
* We need to try and force an autonegotiation
* session, then bring up link.
*/
if (hw->mac.ops.setup_sfp)
hw->mac.ops.setup_sfp(hw);
if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
schedule_work(&adapter->multispeed_fiber_task);
} else {
/*
* Direct Attach Cu and non-multispeed fiber modules
* still need to be configured properly prior to
* attempting link.
*/
if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
schedule_work(&adapter->sfp_config_module_task);
}
} }
/** /**
...@@ -3924,17 +3972,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -3924,17 +3972,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
e_crit(drv, "Fan has stopped, replace the adapter\n"); e_crit(drv, "Fan has stopped, replace the adapter\n");
} }
/*
* For hot-pluggable SFP+ devices, a new SFP+ module may have
* arrived before interrupts were enabled but after probe. Such
* devices wouldn't have their type identified yet. We need to
* kick off the SFP+ module setup first, then try to bring up link.
* If we're not hot-pluggable SFP+, we just need to configure link
* and bring it up.
*/
if (hw->phy.type == ixgbe_phy_none)
schedule_work(&adapter->sfp_config_module_task);
/* enable transmits */ /* enable transmits */
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
...@@ -3942,7 +3979,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -3942,7 +3979,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
* link up interrupt but shouldn't be a problem */ * link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies; adapter->link_check_timeout = jiffies;
mod_timer(&adapter->watchdog_timer, jiffies); mod_timer(&adapter->service_timer, jiffies);
/* Set PF Reset Done bit so PF/VF Mail Ops can work */ /* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
...@@ -3955,6 +3992,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -3955,6 +3992,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{ {
WARN_ON(in_interrupt()); WARN_ON(in_interrupt());
/* put off any impending NetWatchDogTimeout */
adapter->netdev->trans_start = jiffies;
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
usleep_range(1000, 2000); usleep_range(1000, 2000);
ixgbe_down(adapter); ixgbe_down(adapter);
...@@ -3983,10 +4023,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) ...@@ -3983,10 +4023,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int err; int err;
/* lock SFP init bit to prevent race conditions with the watchdog */
while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
usleep_range(1000, 2000);
/* clear all SFP and link config related flags while holding SFP_INIT */
adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
IXGBE_FLAG2_SFP_NEEDS_RESET);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
err = hw->mac.ops.init_hw(hw); err = hw->mac.ops.init_hw(hw);
switch (err) { switch (err) {
case 0: case 0:
case IXGBE_ERR_SFP_NOT_PRESENT: case IXGBE_ERR_SFP_NOT_PRESENT:
case IXGBE_ERR_SFP_NOT_SUPPORTED:
break; break;
case IXGBE_ERR_MASTER_REQUESTS_PENDING: case IXGBE_ERR_MASTER_REQUESTS_PENDING:
e_dev_err("master disable timed out\n"); e_dev_err("master disable timed out\n");
...@@ -4004,6 +4054,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) ...@@ -4004,6 +4054,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
e_dev_err("Hardware Error: %d\n", err); e_dev_err("Hardware Error: %d\n", err);
} }
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
/* reprogram the RAR[0] in case user changed it. */ /* reprogram the RAR[0] in case user changed it. */
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs, hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
IXGBE_RAH_AV); IXGBE_RAH_AV);
...@@ -4132,26 +4184,12 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4132,26 +4184,12 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl; u32 rxctrl;
u32 txdctl;
int i; int i;
int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
/* signal that we are down to the interrupt handler */ /* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state); set_bit(__IXGBE_DOWN, &adapter->state);
/* disable receive for all VFs and wait one second */
if (adapter->num_vfs) {
/* ping all the active vfs to let them know we are going down */
ixgbe_ping_all_vfs(adapter);
/* Disable all VFTE/VFRE TX/RX */
ixgbe_disable_tx_rx(adapter);
/* Mark all the VFs as inactive */
for (i = 0 ; i < adapter->num_vfs; i++)
adapter->vfinfo[i].clear_to_send = 0;
}
/* disable receives */ /* disable receives */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
...@@ -4165,11 +4203,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4165,11 +4203,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); /* call carrier off first to avoid false dev_watchdog timeouts */
del_timer_sync(&adapter->sfp_timer);
del_timer_sync(&adapter->watchdog_timer);
cancel_work_sync(&adapter->watchdog_task);
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_disable(netdev); netif_tx_disable(netdev);
...@@ -4177,6 +4211,25 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4177,6 +4211,25 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter); ixgbe_napi_disable_all(adapter);
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
del_timer_sync(&adapter->service_timer);
/* disable receive for all VFs and wait one second */
if (adapter->num_vfs) {
/* ping all the active vfs to let them know we are going down */
ixgbe_ping_all_vfs(adapter);
/* Disable all VFTE/VFRE TX/RX */
ixgbe_disable_tx_rx(adapter);
/* Mark all the VFs as inactive */
for (i = 0 ; i < adapter->num_vfs; i++)
adapter->vfinfo[i].clear_to_send = 0;
}
/* Cleanup the affinity_hint CPU mask memory and callback */ /* Cleanup the affinity_hint CPU mask memory and callback */
for (i = 0; i < num_q_vectors; i++) { for (i = 0; i < num_q_vectors; i++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
...@@ -4186,21 +4239,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4186,21 +4239,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
free_cpumask_var(q_vector->affinity_mask); free_cpumask_var(q_vector->affinity_mask);
} }
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
cancel_work_sync(&adapter->check_overtemp_task);
/* disable transmits in the hardware now that interrupts are off */ /* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) { for (i = 0; i < adapter->num_tx_queues; i++) {
u8 reg_idx = adapter->tx_ring[i]->reg_idx; u8 reg_idx = adapter->tx_ring[i]->reg_idx;
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
(txdctl & ~IXGBE_TXDCTL_ENABLE));
} }
/* Disable the Tx DMA engine on 82599 */
/* Disable the Tx DMA engine on 82599 and X540 */
switch (hw->mac.type) { switch (hw->mac.type) {
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
case ixgbe_mac_X540: case ixgbe_mac_X540:
...@@ -4275,25 +4320,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev) ...@@ -4275,25 +4320,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
adapter->tx_timeout_count++;
/* Do the reset outside of interrupt context */ /* Do the reset outside of interrupt context */
schedule_work(&adapter->reset_task); ixgbe_tx_timeout_reset(adapter);
}
static void ixgbe_reset_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter;
adapter = container_of(work, struct ixgbe_adapter, reset_task);
/* If we're already down or resetting, just bail */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
ixgbe_dump(adapter);
netdev_err(adapter->netdev, "Reset adapter\n");
ixgbe_reinit_locked(adapter);
} }
/** /**
...@@ -5145,57 +5173,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) ...@@ -5145,57 +5173,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
ixgbe_reset_interrupt_capability(adapter); ixgbe_reset_interrupt_capability(adapter);
} }
/**
* ixgbe_sfp_timer - worker thread to find a missing module
* @data: pointer to our adapter struct
**/
static void ixgbe_sfp_timer(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
/*
* Do the sfp_timer outside of interrupt context due to the
* delays that sfp+ detection requires
*/
schedule_work(&adapter->sfp_task);
}
/**
* ixgbe_sfp_task - worker thread to find a missing module
* @work: pointer to work_struct containing our data
**/
static void ixgbe_sfp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
sfp_task);
struct ixgbe_hw *hw = &adapter->hw;
if ((hw->phy.type == ixgbe_phy_nl) &&
(hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
s32 ret = hw->phy.ops.identify_sfp(hw);
if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
goto reschedule;
ret = hw->phy.ops.reset(hw);
if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
e_dev_err("failed to initialize because an unsupported "
"SFP+ module type was detected.\n");
e_dev_err("Reload the driver after installing a "
"supported module.\n");
unregister_netdev(adapter->netdev);
} else {
e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
}
/* don't need this routine any more */
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
}
return;
reschedule:
if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
mod_timer(&adapter->sfp_timer,
round_jiffies(jiffies + (2 * HZ)));
}
/** /**
* ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter) * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
* @adapter: board private structure to initialize * @adapter: board private structure to initialize
...@@ -5992,23 +5969,66 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) ...@@ -5992,23 +5969,66 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
} }
/** /**
* ixgbe_watchdog - Timer Call-back * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table
* @data: pointer to adapter cast into an unsigned long * @adapter - pointer to the device adapter structure
**/ **/
static void ixgbe_watchdog(unsigned long data) static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u64 eics = 0;
int i; int i;
/* if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
* Do the watchdog outside of interrupt context due to the lovely return;
* delays that some of the newer hardware requires
*/ adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
/* if interface is down do nothing */
if (test_bit(__IXGBE_DOWN, &adapter->state)) if (test_bit(__IXGBE_DOWN, &adapter->state))
goto watchdog_short_circuit; return;
/* do nothing if we are not using signature filters */
if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE))
return;
adapter->fdir_overflow++;
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++)
set_bit(__IXGBE_TX_FDIR_INIT_DONE,
&(adapter->tx_ring[i]->state));
/* re-enable flow director interrupts */
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR);
} else {
e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n");
}
}
/**
* ixgbe_check_hang_subtask - check for hung queues and dropped interrupts
* @adapter - pointer to the device adapter structure
*
* This function serves two purposes. First it strobes the interrupt lines
* in order to make certain interrupts are occuring. Secondly it sets the
* bits needed to check for TX hangs. As a result we should immediately
* determine if a hang has occured.
*/
static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u64 eics = 0;
int i;
/* If we're down or resetting, just bail */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
/* Force detection of hung controller */
if (netif_carrier_ok(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++)
set_check_for_tx_hang(adapter->tx_ring[i]);
}
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
/* /*
...@@ -6018,108 +6038,172 @@ static void ixgbe_watchdog(unsigned long data) ...@@ -6018,108 +6038,172 @@ static void ixgbe_watchdog(unsigned long data)
*/ */
IXGBE_WRITE_REG(hw, IXGBE_EICS, IXGBE_WRITE_REG(hw, IXGBE_EICS,
(IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
goto watchdog_reschedule; } else {
} /* get one bit for every active tx/rx interrupt vector */
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
/* get one bit for every active tx/rx interrupt vector */ struct ixgbe_q_vector *qv = adapter->q_vector[i];
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { if (qv->rxr_count || qv->txr_count)
struct ixgbe_q_vector *qv = adapter->q_vector[i]; eics |= ((u64)1 << i);
if (qv->rxr_count || qv->txr_count) }
eics |= ((u64)1 << i);
} }
/* Cause software interrupt to ensure rx rings are cleaned */ /* Cause software interrupt to ensure rings are cleaned */
ixgbe_irq_rearm_queues(adapter, eics); ixgbe_irq_rearm_queues(adapter, eics);
watchdog_reschedule:
/* Reset the timer */
mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
watchdog_short_circuit:
schedule_work(&adapter->watchdog_task);
} }
/** /**
* ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber * ixgbe_watchdog_update_link - update the link status
* @work: pointer to work_struct containing our data * @adapter - pointer to the device adapter structure
* @link_speed - pointer to a u32 to store the link_speed
**/ **/
static void ixgbe_multispeed_fiber_task(struct work_struct *work) static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
multispeed_fiber_task);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg; u32 link_speed = adapter->link_speed;
bool negotiation; bool link_up = adapter->link_up;
int i;
adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE))
autoneg = hw->phy.autoneg_advertised; return;
if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); if (hw->mac.ops.check_link) {
hw->mac.autotry_restart = false; hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (hw->mac.ops.setup_link) } else {
hw->mac.ops.setup_link(hw, autoneg, negotiation, true); /* always assume link is up, if no check link function */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; link_speed = IXGBE_LINK_SPEED_10GB_FULL;
adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK; link_up = true;
}
if (link_up) {
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
hw->mac.ops.fc_enable(hw, i);
} else {
hw->mac.ops.fc_enable(hw, 0);
}
}
if (link_up ||
time_after(jiffies, (adapter->link_check_timeout +
IXGBE_TRY_LINK_TIMEOUT))) {
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
IXGBE_WRITE_FLUSH(hw);
}
adapter->link_up = link_up;
adapter->link_speed = link_speed;
} }
/** /**
* ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module * ixgbe_watchdog_link_is_up - update netif_carrier status and
* @work: pointer to work_struct containing our data * print link up message
* @adapter - pointer to the device adapter structure
**/ **/
static void ixgbe_sfp_config_module_task(struct work_struct *work) static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work, struct net_device *netdev = adapter->netdev;
struct ixgbe_adapter,
sfp_config_module_task);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 err; u32 link_speed = adapter->link_speed;
bool flow_rx, flow_tx;
adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; /* only continue if link was previously down */
if (netif_carrier_ok(netdev))
return;
/* Time for electrical oscillations to settle down */ adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
msleep(100);
err = hw->phy.ops.identify_sfp(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { switch (hw->mac.type) {
e_dev_err("failed to initialize because an unsupported SFP+ " case ixgbe_mac_82598EB: {
"module type was detected.\n"); u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
e_dev_err("Reload the driver after installing a supported " u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
"module.\n"); flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
unregister_netdev(adapter->netdev); flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
return;
} }
if (hw->mac.ops.setup_sfp) break;
hw->mac.ops.setup_sfp(hw); case ixgbe_mac_X540:
case ixgbe_mac_82599EB: {
u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
}
break;
default:
flow_tx = false;
flow_rx = false;
break;
}
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
"10 Gbps" :
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
"1 Gbps" :
(link_speed == IXGBE_LINK_SPEED_100_FULL ?
"100 Mbps" :
"unknown speed"))),
((flow_rx && flow_tx) ? "RX/TX" :
(flow_rx ? "RX" :
(flow_tx ? "TX" : "None"))));
if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) netif_carrier_on(netdev);
/* This will also work for DA Twinax connections */ #ifdef HAVE_IPLINK_VF_CONFIG
schedule_work(&adapter->multispeed_fiber_task); ixgbe_check_vf_rate_limit(adapter);
adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; #endif /* HAVE_IPLINK_VF_CONFIG */
} }
/** /**
* ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table * ixgbe_watchdog_link_is_down - update netif_carrier status and
* @work: pointer to work_struct containing our data * print link down message
* @adapter - pointer to the adapter structure
**/ **/
static void ixgbe_fdir_reinit_task(struct work_struct *work) static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter* adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work, struct net_device *netdev = adapter->netdev;
struct ixgbe_adapter,
fdir_reinit_task);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
adapter->link_up = false;
adapter->link_speed = 0;
/* only continue if link was up previously */
if (!netif_carrier_ok(netdev))
return;
/* poll for SFP+ cable when link is down */
if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
e_info(drv, "NIC Link is Down\n");
netif_carrier_off(netdev);
}
/**
* ixgbe_watchdog_flush_tx - flush queues on link down
* @adapter - pointer to the device adapter structure
**/
static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
{
int i; int i;
int some_tx_pending = 0;
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { if (!netif_carrier_ok(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++) for (i = 0; i < adapter->num_tx_queues; i++) {
set_bit(__IXGBE_TX_FDIR_INIT_DONE, struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
&(adapter->tx_ring[i]->state)); if (tx_ring->next_to_use != tx_ring->next_to_clean) {
} else { some_tx_pending = 1;
e_err(probe, "failed to finish FDIR re-initialization, " break;
"ignored adding FDIR ATR filters\n"); }
}
if (some_tx_pending) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context).
*/
adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
}
} }
/* Done FDIR Re-initialization, enable transmits */
netif_tx_start_all_queues(adapter->netdev);
} }
static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
...@@ -6142,133 +6226,186 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) ...@@ -6142,133 +6226,186 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
e_warn(drv, "%d Spoofed packets detected\n", ssvpc); e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
} }
static DEFINE_MUTEX(ixgbe_watchdog_lock); /**
* ixgbe_watchdog_subtask - check and bring link up
* @adapter - pointer to the device adapter structure
**/
static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
{
/* if interface is down do nothing */
if (test_bit(__IXGBE_DOWN, &adapter->state))
return;
ixgbe_watchdog_update_link(adapter);
if (adapter->link_up)
ixgbe_watchdog_link_is_up(adapter);
else
ixgbe_watchdog_link_is_down(adapter);
ixgbe_spoof_check(adapter);
ixgbe_update_stats(adapter);
ixgbe_watchdog_flush_tx(adapter);
}
/** /**
* ixgbe_watchdog_task - worker thread to bring link up * ixgbe_sfp_detection_subtask - poll for SFP+ cable
* @work: pointer to work_struct containing our data * @adapter - the ixgbe adapter structure
**/ **/
static void ixgbe_watchdog_task(struct work_struct *work) static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
watchdog_task);
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed; s32 err;
bool link_up;
int i;
struct ixgbe_ring *tx_ring;
int some_tx_pending = 0;
mutex_lock(&ixgbe_watchdog_lock); /* not searching for SFP so there is nothing to do here */
if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
return;
link_up = adapter->link_up; /* someone else is in init, wait until next service event */
link_speed = adapter->link_speed; if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
return;
if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) { err = hw->phy.ops.identify_sfp(hw);
hw->mac.ops.check_link(hw, &link_speed, &link_up, false); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
if (link_up) { goto sfp_out;
#ifdef CONFIG_DCB
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
hw->mac.ops.fc_enable(hw, i);
} else {
hw->mac.ops.fc_enable(hw, 0);
}
#else
hw->mac.ops.fc_enable(hw, 0);
#endif
}
if (link_up || if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
time_after(jiffies, (adapter->link_check_timeout + /* If no cable is present, then we need to reset
IXGBE_TRY_LINK_TIMEOUT))) { * the next time we find a good cable. */
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
}
adapter->link_up = link_up;
adapter->link_speed = link_speed;
} }
if (link_up) { /* exit on error */
if (!netif_carrier_ok(netdev)) { if (err)
bool flow_rx, flow_tx; goto sfp_out;
switch (hw->mac.type) {
case ixgbe_mac_82598EB: {
u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
}
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540: {
u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
}
break;
default:
flow_tx = false;
flow_rx = false;
break;
}
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", /* exit if reset not needed */
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ? if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
"10 Gbps" : goto sfp_out;
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
"1 Gbps" :
(link_speed == IXGBE_LINK_SPEED_100_FULL ?
"100 Mbps" :
"unknown speed"))),
((flow_rx && flow_tx) ? "RX/TX" :
(flow_rx ? "RX" :
(flow_tx ? "TX" : "None"))));
netif_carrier_on(netdev);
ixgbe_check_vf_rate_limit(adapter);
} else {
/* Force detection of hung controller */
for (i = 0; i < adapter->num_tx_queues; i++) {
tx_ring = adapter->tx_ring[i];
set_check_for_tx_hang(tx_ring);
}
}
} else {
adapter->link_up = false;
adapter->link_speed = 0;
if (netif_carrier_ok(netdev)) {
e_info(drv, "NIC Link is Down\n");
netif_carrier_off(netdev);
}
}
if (!netif_carrier_ok(netdev)) { adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET;
for (i = 0; i < adapter->num_tx_queues; i++) {
tx_ring = adapter->tx_ring[i];
if (tx_ring->next_to_use != tx_ring->next_to_clean) {
some_tx_pending = 1;
break;
}
}
if (some_tx_pending) { /*
/* We've lost link, so the controller stops DMA, * A module may be identified correctly, but the EEPROM may not have
* but we've got queued Tx work that's never going * support for that module. setup_sfp() will fail in that case, so
* to get done, so reset controller to flush Tx. * we should not allow that module to load.
* (Do the reset outside of interrupt context). */
*/ if (hw->mac.type == ixgbe_mac_82598EB)
schedule_work(&adapter->reset_task); err = hw->phy.ops.reset(hw);
} else
err = hw->mac.ops.setup_sfp(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
goto sfp_out;
adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
sfp_out:
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) &&
(adapter->netdev->reg_state == NETREG_REGISTERED)) {
e_dev_err("failed to initialize because an unsupported "
"SFP+ module type was detected.\n");
e_dev_err("Reload the driver after installing a "
"supported module.\n");
unregister_netdev(adapter->netdev);
} }
}
ixgbe_spoof_check(adapter); /**
ixgbe_update_stats(adapter); * ixgbe_sfp_link_config_subtask - set up link SFP after module install
mutex_unlock(&ixgbe_watchdog_lock); * @adapter - the ixgbe adapter structure
**/
static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg;
bool negotiation;
if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG))
return;
/* someone else is in init, wait until next service event */
if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
return;
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
autoneg = hw->phy.autoneg_advertised;
if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
hw->mac.autotry_restart = false;
if (hw->mac.ops.setup_link)
hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies;
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
}
/**
* ixgbe_service_timer - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
static void ixgbe_service_timer(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
unsigned long next_event_offset;
/* poll faster when waiting for link */
if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)
next_event_offset = HZ / 10;
else
next_event_offset = HZ * 2;
/* Reset the timer */
mod_timer(&adapter->service_timer, next_event_offset + jiffies);
ixgbe_service_event_schedule(adapter);
}
static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
{
if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED))
return;
adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
/* If we're already down or resetting, just bail */
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
ixgbe_dump(adapter);
netdev_err(adapter->netdev, "Reset adapter\n");
adapter->tx_timeout_count++;
ixgbe_reinit_locked(adapter);
}
/**
* ixgbe_service_task - manages and runs subtasks
* @work: pointer to work_struct containing our data
**/
static void ixgbe_service_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
service_task);
ixgbe_reset_subtask(adapter);
ixgbe_sfp_detection_subtask(adapter);
ixgbe_sfp_link_config_subtask(adapter);
ixgbe_check_overtemp_subtask(adapter);
ixgbe_watchdog_subtask(adapter);
ixgbe_fdir_reinit_subtask(adapter);
ixgbe_check_hang_subtask(adapter);
ixgbe_service_event_complete(adapter);
} }
static int ixgbe_tso(struct ixgbe_adapter *adapter, static int ixgbe_tso(struct ixgbe_adapter *adapter,
...@@ -7107,6 +7244,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, ...@@ -7107,6 +7244,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int err; int err;
int num_vf_macvlans, i;
struct vf_macvlans *mv_list;
if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs) if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
return; return;
...@@ -7123,6 +7262,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, ...@@ -7123,6 +7262,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
e_err(probe, "Failed to enable PCI sriov: %d\n", err); e_err(probe, "Failed to enable PCI sriov: %d\n", err);
goto err_novfs; goto err_novfs;
} }
num_vf_macvlans = hw->mac.num_rar_entries -
(IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
sizeof(struct vf_macvlans),
GFP_KERNEL);
if (mv_list) {
/* Initialize list of VF macvlans */
INIT_LIST_HEAD(&adapter->vf_mvs.l);
for (i = 0; i < num_vf_macvlans; i++) {
mv_list->vf = -1;
mv_list->free = true;
mv_list->rar_entry = hw->mac.num_rar_entries -
(i + adapter->num_vfs + 1);
list_add(&mv_list->l, &adapter->vf_mvs.l);
mv_list++;
}
}
/* If call to enable VFs succeeded then allocate memory /* If call to enable VFs succeeded then allocate memory
* for per VF control structures. * for per VF control structures.
*/ */
...@@ -7293,22 +7452,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7293,22 +7452,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.mdio.mdio_read = ixgbe_mdio_read; hw->phy.mdio.mdio_read = ixgbe_mdio_read;
hw->phy.mdio.mdio_write = ixgbe_mdio_write; hw->phy.mdio.mdio_write = ixgbe_mdio_write;
/* set up this timer and work struct before calling get_invariants
* which might start the timer
*/
init_timer(&adapter->sfp_timer);
adapter->sfp_timer.function = ixgbe_sfp_timer;
adapter->sfp_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
/* multispeed fiber has its own tasklet, called from GPI SDP1 context */
INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
/* a new SFP+ module arrival, called from GPI SDP2 context */
INIT_WORK(&adapter->sfp_config_module_task,
ixgbe_sfp_config_module_task);
ii->get_invariants(hw); ii->get_invariants(hw);
/* setup the private structure */ /* setup the private structure */
...@@ -7342,17 +7485,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7342,17 +7485,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.reset_if_overtemp = false; hw->phy.reset_if_overtemp = false;
if (err == IXGBE_ERR_SFP_NOT_PRESENT && if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
hw->mac.type == ixgbe_mac_82598EB) { hw->mac.type == ixgbe_mac_82598EB) {
/*
* Start a kernel thread to watch for a module to arrive.
* Only do this for 82598, since 82599 will generate
* interrupts on module arrival.
*/
set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
mod_timer(&adapter->sfp_timer,
round_jiffies(jiffies + (2 * HZ)));
err = 0; err = 0;
} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
e_dev_err("failed to initialize because an unsupported SFP+ " e_dev_err("failed to load because an unsupported SFP+ "
"module type was detected.\n"); "module type was detected.\n");
e_dev_err("Reload the driver after installing a supported " e_dev_err("Reload the driver after installing a supported "
"module.\n"); "module.\n");
...@@ -7444,12 +7579,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7444,12 +7579,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
(hw->mac.type == ixgbe_mac_82599EB)))) (hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw); hw->mac.ops.disable_tx_laser(hw);
init_timer(&adapter->watchdog_timer); setup_timer(&adapter->service_timer, &ixgbe_service_timer,
adapter->watchdog_timer.function = ixgbe_watchdog; (unsigned long) adapter);
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbe_reset_task); INIT_WORK(&adapter->service_task, ixgbe_service_task);
INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
err = ixgbe_init_interrupt_scheme(adapter); err = ixgbe_init_interrupt_scheme(adapter);
if (err) if (err)
...@@ -7536,13 +7670,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7536,13 +7670,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* carrier off reporting is important to ethtool even BEFORE open */ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
INIT_WORK(&adapter->check_overtemp_task,
ixgbe_check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA #ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) { if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED; adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
...@@ -7569,11 +7696,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7569,11 +7696,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
err_eeprom: err_eeprom:
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter); ixgbe_disable_sriov(adapter);
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->sfp_task);
cancel_work_sync(&adapter->multispeed_fiber_task);
cancel_work_sync(&adapter->sfp_config_module_task);
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
err_ioremap: err_ioremap:
free_netdev(netdev); free_netdev(netdev);
...@@ -7601,24 +7724,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ...@@ -7601,24 +7724,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
set_bit(__IXGBE_DOWN, &adapter->state); set_bit(__IXGBE_DOWN, &adapter->state);
cancel_work_sync(&adapter->service_task);
/*
* The timers may be rescheduled, so explicitly disable them
* from being rescheduled.
*/
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->sfp_task);
cancel_work_sync(&adapter->multispeed_fiber_task);
cancel_work_sync(&adapter->sfp_config_module_task);
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
cancel_work_sync(&adapter->check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA #ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */ /* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4 #define IXGBE_VF_PERMADDR_MSG_LEN 4
......
...@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, ...@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
return 0; return 0;
} }
static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
struct list_head *pos;
struct vf_macvlans *entry;
list_for_each(pos, &adapter->vf_mvs.l) {
entry = list_entry(pos, struct vf_macvlans, l);
if (entry->free == false)
hw->mac.ops.set_rar(hw, entry->rar_entry,
entry->vf_macvlan,
entry->vf, IXGBE_RAH_AV);
}
}
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
...@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) ...@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
} }
} }
/* Restore any VF macvlans */
ixgbe_restore_vf_macvlans(adapter);
} }
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
...@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, ...@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
return 0; return 0;
} }
static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
int vf, int index, unsigned char *mac_addr)
{
struct ixgbe_hw *hw = &adapter->hw;
struct list_head *pos;
struct vf_macvlans *entry;
if (index <= 1) {
list_for_each(pos, &adapter->vf_mvs.l) {
entry = list_entry(pos, struct vf_macvlans, l);
if (entry->vf == vf) {
entry->vf = -1;
entry->free = true;
entry->is_macvlan = false;
hw->mac.ops.clear_rar(hw, entry->rar_entry);
}
}
}
/*
* If index was zero then we were asked to clear the uc list
* for the VF. We're done.
*/
if (!index)
return 0;
entry = NULL;
list_for_each(pos, &adapter->vf_mvs.l) {
entry = list_entry(pos, struct vf_macvlans, l);
if (entry->free)
break;
}
/*
* If we traversed the entire list and didn't find a free entry
* then we're out of space on the RAR table. Also entry may
* be NULL because the original memory allocation for the list
* failed, which is not fatal but does mean we can't support
* VF requests for MACVLAN because we couldn't allocate
* memory for the list management required.
*/
if (!entry || !entry->free)
return -ENOSPC;
entry->free = false;
entry->is_macvlan = true;
entry->vf = vf;
memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
return 0;
}
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
{ {
unsigned char vf_mac_addr[6]; unsigned char vf_mac_addr[6];
...@@ -251,12 +324,12 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) ...@@ -251,12 +324,12 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{ {
u32 mbx_size = IXGBE_VFMAILBOX_SIZE; u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
u32 msgbuf[mbx_size]; u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
s32 retval; s32 retval;
int entries; int entries;
u16 *hash_list; u16 *hash_list;
int add, vid; int add, vid, index;
u8 *new_mac; u8 *new_mac;
retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
...@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) ...@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
} }
break; break;
case IXGBE_VF_SET_MACVLAN:
index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
IXGBE_VT_MSGINFO_SHIFT;
/*
* If the VF is allowed to set MAC filters then turn off
* anti-spoofing to avoid false positives. An index
* greater than 0 will indicate the VF is setting a
* macvlan MAC filter.
*/
if (index > 0 && adapter->antispoofing_enabled) {
hw->mac.ops.set_mac_anti_spoofing(hw, false,
adapter->num_vfs);
hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
adapter->antispoofing_enabled = false;
}
retval = ixgbe_set_vf_macvlan(adapter, vf, index,
(unsigned char *)(&msgbuf[1]));
break;
default: default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX; retval = IXGBE_ERR_MBX;
...@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) ...@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
goto out; goto out;
ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
ixgbe_set_vmolr(hw, vf, false); ixgbe_set_vmolr(hw, vf, false);
hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); if (adapter->antispoofing_enabled)
hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
adapter->vfinfo[vf].pf_vlan = vlan; adapter->vfinfo[vf].pf_vlan = vlan;
adapter->vfinfo[vf].pf_qos = qos; adapter->vfinfo[vf].pf_qos = qos;
dev_info(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
#define IXGBE_DEV_ID_82599_LS 0x154F
#define IXGBE_DEV_ID_X540T 0x1528 #define IXGBE_DEV_ID_X540T 0x1528
/* General Registers */ /* General Registers */
...@@ -2395,6 +2396,7 @@ enum ixgbe_sfp_type { ...@@ -2395,6 +2396,7 @@ enum ixgbe_sfp_type {
enum ixgbe_media_type { enum ixgbe_media_type {
ixgbe_media_type_unknown = 0, ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber, ixgbe_media_type_fiber,
ixgbe_media_type_fiber_lco,
ixgbe_media_type_copper, ixgbe_media_type_copper,
ixgbe_media_type_backplane, ixgbe_media_type_backplane,
ixgbe_media_type_cx4, ixgbe_media_type_cx4,
......
...@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) ...@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
} }
} }
static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
int count = 0;
if ((netdev_uc_count(netdev)) > 10) {
printk(KERN_ERR "Too many unicast filters - No Space\n");
return -ENOSPC;
}
if (!netdev_uc_empty(netdev)) {
struct netdev_hw_addr *ha;
netdev_for_each_uc_addr(ha, netdev) {
hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
udelay(200);
}
} else {
/*
* If the list is empty then send message to PF driver to
* clear all macvlans on this VF.
*/
hw->mac.ops.set_uc_addr(hw, 0, NULL);
}
return count;
}
/** /**
* ixgbevf_set_rx_mode - Multicast set * ixgbevf_set_rx_mode - Multicast set
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) ...@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
/* reprogram multicast list */ /* reprogram multicast list */
if (hw->mac.ops.update_mc_addr_list) if (hw->mac.ops.update_mc_addr_list)
hw->mac.ops.update_mc_addr_list(hw, netdev); hw->mac.ops.update_mc_addr_list(hw, netdev);
ixgbevf_write_uc_addr_list(netdev);
} }
static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */ /* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4 #define IXGBE_VF_PERMADDR_MSG_LEN 4
......
...@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) ...@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
return 0; return 0;
} }
static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 msgbuf[3];
u8 *msg_addr = (u8 *)(&msgbuf[1]);
s32 ret_val;
memset(msgbuf, 0, sizeof(msgbuf));
/*
* If index is one then this is the start of a new list and needs
* indication to the PF so it can do it's own list management.
* If it is zero then that tells the PF to just clear all of
* this VF's macvlans and there is no new list.
*/
msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
if (addr)
memcpy(msg_addr, addr, 6);
ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
if (!ret_val)
ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
if (!ret_val)
if (msgbuf[0] ==
(IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
ret_val = -ENOMEM;
return ret_val;
}
/** /**
* ixgbevf_set_rar_vf - set device MAC address * ixgbevf_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = { ...@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.check_link = ixgbevf_check_mac_link_vf, .check_link = ixgbevf_check_mac_link_vf,
.set_rar = ixgbevf_set_rar_vf, .set_rar = ixgbevf_set_rar_vf,
.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
.set_uc_addr = ixgbevf_set_uc_addr_vf,
.set_vfta = ixgbevf_set_vfta_vf, .set_vfta = ixgbevf_set_vfta_vf,
}; };
......
...@@ -62,6 +62,7 @@ struct ixgbe_mac_operations { ...@@ -62,6 +62,7 @@ struct ixgbe_mac_operations {
/* RAR, Multicast, VLAN */ /* RAR, Multicast, VLAN */
s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32); s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
s32 (*init_rx_addrs)(struct ixgbe_hw *); s32 (*init_rx_addrs)(struct ixgbe_hw *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
s32 (*enable_mc)(struct ixgbe_hw *); s32 (*enable_mc)(struct ixgbe_hw *);
......
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