Skip to content

Commit

Permalink
Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/jkirsher/next-queue

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2016-11-04

This series contains updates to ixgbe and ixgbevf only.

Don does cleanup and configuration for our X553 devices, related to LED,
auto-negotiation, flow control and SFP+ setup and config.  Adds the
(not secret) sauce for B0 hardware for X553 hardware.

Emil provides several fixes, first replaces the driver specific MDIO
defines for the more preferred equivalent kernel ones.  Provides a fix
for auto-negotiaion status, by reading a PHY register twice.  Introduces
ixgbe_link_operations structure to allow X550EM_a to override the
methods for MDIO access while X550EM_x provides methods to use I2C
combined access.

Mark fixes an issue where the driver was crashing when msix_entires
were not there because they were freed by a previous suspend or remove.

Sowmini Varadhan fixes an issue where an incorrect check for IPPROTO_UDP
in ixgbe_atr().  Then makes sure that the network and transport headers
in the paged data are available in the headlen bytes to calculate the
l4_proto.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 7, 2016
2 parents b6e4179 + eeffcee commit 9811d1e
Show file tree
Hide file tree
Showing 13 changed files with 819 additions and 374 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -1027,4 +1027,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
struct ixgbe_ring *tx_ring);
u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter);
void ixgbe_store_reta(struct ixgbe_adapter *adapter);
s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
#endif /* _IXGBE_H_ */
4 changes: 3 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
}

/* Negotiate the fc mode to use */
ixgbe_fc_autoneg(hw);
hw->mac.ops.fc_autoneg(hw);

/* Disable any previous flow control settings */
fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
Expand Down Expand Up @@ -1179,6 +1179,7 @@ static const struct ixgbe_mac_operations mac_ops_82598 = {
.get_link_capabilities = &ixgbe_get_link_capabilities_82598,
.led_on = &ixgbe_led_on_generic,
.led_off = &ixgbe_led_off_generic,
.init_led_link_act = ixgbe_init_led_link_act_generic,
.blink_led_start = &ixgbe_blink_led_start_generic,
.blink_led_stop = &ixgbe_blink_led_stop_generic,
.set_rar = &ixgbe_set_rar_generic,
Expand All @@ -1193,6 +1194,7 @@ static const struct ixgbe_mac_operations mac_ops_82598 = {
.set_vfta = &ixgbe_set_vfta_82598,
.fc_enable = &ixgbe_fc_enable_82598,
.setup_fc = ixgbe_setup_fc_generic,
.fc_autoneg = ixgbe_fc_autoneg,
.set_fw_drv_ver = NULL,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync,
.release_swfw_sync = &ixgbe_release_swfw_sync,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,7 @@ static const struct ixgbe_mac_operations mac_ops_82599 = {
.get_link_capabilities = &ixgbe_get_link_capabilities_82599,
.led_on = &ixgbe_led_on_generic,
.led_off = &ixgbe_led_off_generic,
.init_led_link_act = ixgbe_init_led_link_act_generic,
.blink_led_start = &ixgbe_blink_led_start_generic,
.blink_led_stop = &ixgbe_blink_led_stop_generic,
.set_rar = &ixgbe_set_rar_generic,
Expand All @@ -2219,6 +2220,7 @@ static const struct ixgbe_mac_operations mac_ops_82599 = {
.set_vfta = &ixgbe_set_vfta_generic,
.fc_enable = &ixgbe_fc_enable_generic,
.setup_fc = ixgbe_setup_fc_generic,
.fc_autoneg = ixgbe_fc_autoneg,
.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic,
.init_uta_tables = &ixgbe_init_uta_tables_generic,
.setup_sfp = &ixgbe_setup_sfp_modules_82599,
Expand Down
62 changes: 55 additions & 7 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,12 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
IXGBE_WRITE_FLUSH(hw);

/* Setup flow control */
ret_val = hw->mac.ops.setup_fc(hw);
if (ret_val)
return ret_val;
/* Setup flow control if method for doing so */
if (hw->mac.ops.setup_fc) {
ret_val = hw->mac.ops.setup_fc(hw);
if (ret_val)
return ret_val;
}

/* Cashe bit indicating need for crosstalk fix */
switch (hw->mac.type) {
Expand Down Expand Up @@ -390,6 +392,9 @@ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
status = hw->mac.ops.start_hw(hw);
}

/* Initialize the LED link active for LED blink support */
hw->mac.ops.init_led_link_act(hw);

return status;
}

Expand Down Expand Up @@ -772,6 +777,49 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
return ixgbe_disable_pcie_master(hw);
}

/**
* ixgbe_init_led_link_act_generic - Store the LED index link/activity.
* @hw: pointer to hardware structure
*
* Store the index for the link active LED. This will be used to support
* blinking the LED.
**/
s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
u32 led_reg, led_mode;
u16 i;

led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);

/* Get LED link active from the LEDCTL register */
for (i = 0; i < 4; i++) {
led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i);

if ((led_mode & IXGBE_LED_MODE_MASK_BASE) ==
IXGBE_LED_LINK_ACTIVE) {
mac->led_link_act = i;
return 0;
}
}

/* If LEDCTL register does not have the LED link active set, then use
* known MAC defaults.
*/
switch (hw->mac.type) {
case ixgbe_mac_x550em_a:
mac->led_link_act = 0;
break;
case ixgbe_mac_X550EM_x:
mac->led_link_act = 1;
break;
default:
mac->led_link_act = 2;
}

return 0;
}

/**
* ixgbe_led_on_generic - Turns on the software controllable LEDs.
* @hw: pointer to hardware structure
Expand Down Expand Up @@ -2127,7 +2175,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
}

/* Negotiate the fc mode to use */
ixgbe_fc_autoneg(hw);
hw->mac.ops.fc_autoneg(hw);

/* Disable any previous flow control settings */
mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
Expand Down Expand Up @@ -2231,8 +2279,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
* Find the intersection between advertised settings and link partner's
* advertised settings
**/
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
{
if ((!(adv_reg)) || (!(lp_reg)))
return IXGBE_ERR_FC_NOT_NEGOTIATED;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);

s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw);

s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2225,11 +2225,11 @@ static int ixgbe_set_phys_id(struct net_device *netdev,
return 2;

case ETHTOOL_ID_ON:
hw->mac.ops.led_on(hw, hw->bus.func);
hw->mac.ops.led_on(hw, hw->mac.led_link_act);
break;

case ETHTOOL_ID_OFF:
hw->mac.ops.led_off(hw, hw->bus.func);
hw->mac.ops.led_off(hw, hw->mac.led_link_act);
break;

case ETHTOOL_ID_INACTIVE:
Expand Down
34 changes: 29 additions & 5 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h>
#include <net/tc_act/tc_mirred.h>
#include <net/vxlan.h>

#include "ixgbe.h"
#include "ixgbe_common.h"
Expand Down Expand Up @@ -3070,6 +3071,9 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
return;
}

if (!adapter->msix_entries)
return;

for (vector = 0; vector < adapter->num_q_vectors; vector++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[vector];
struct msix_entry *entry = &adapter->msix_entries[vector];
Expand Down Expand Up @@ -5621,7 +5625,8 @@ static void ixgbe_init_dcb(struct ixgbe_adapter *adapter)
* Fields are initialized based on PCI device information and
* OS network device settings (MTU size).
**/
static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
const struct ixgbe_info *ii)
{
struct ixgbe_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
Expand All @@ -5637,6 +5642,9 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
hw->subsystem_vendor_id = pdev->subsystem_vendor;
hw->subsystem_device_id = pdev->subsystem_device;

/* get_invariants needs the device IDs */
ii->get_invariants(hw);

/* Set common capability flags and settings */
rss = min_t(int, ixgbe_max_rss_indices(adapter), num_online_cpus());
adapter->ring_feature[RING_F_RSS].limit = rss;
Expand Down Expand Up @@ -7653,11 +7661,17 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
/* snag network header to get L4 type and address */
skb = first->skb;
hdr.network = skb_network_header(skb);
if (unlikely(hdr.network <= skb->data))
return;
if (skb->encapsulation &&
first->protocol == htons(ETH_P_IP) &&
hdr.ipv4->protocol != IPPROTO_UDP) {
hdr.ipv4->protocol == IPPROTO_UDP) {
struct ixgbe_adapter *adapter = q_vector->adapter;

if (unlikely(skb_tail_pointer(skb) < hdr.network +
VXLAN_HEADROOM))
return;

/* verify the port is recognized as VXLAN */
if (adapter->vxlan_port &&
udp_hdr(skb)->dest == adapter->vxlan_port)
Expand All @@ -7668,6 +7682,12 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
hdr.network = skb_inner_network_header(skb);
}

/* Make sure we have at least [minimum IPv4 header + TCP]
* or [IPv6 header] bytes
*/
if (unlikely(skb_tail_pointer(skb) < hdr.network + 40))
return;

/* Currently only IPv4/IPv6 with TCP is supported */
switch (hdr.ipv4->version) {
case IPVERSION:
Expand All @@ -7687,6 +7707,10 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
if (l4_proto != IPPROTO_TCP)
return;

if (unlikely(skb_tail_pointer(skb) < hdr.network +
hlen + sizeof(struct tcphdr)))
return;

th = (struct tcphdr *)(hdr.network + hlen);

/* skip this packet since the socket is closing */
Expand Down Expand Up @@ -9504,6 +9528,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->mac.ops = *ii->mac_ops;
hw->mac.type = ii->mac;
hw->mvals = ii->mvals;
if (ii->link_ops)
hw->link.ops = *ii->link_ops;

/* EEPROM */
hw->eeprom.ops = *ii->eeprom_ops;
Expand All @@ -9527,10 +9553,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->phy.mdio.mdio_read = ixgbe_mdio_read;
hw->phy.mdio.mdio_write = ixgbe_mdio_write;

ii->get_invariants(hw);

/* setup the private structure */
err = ixgbe_sw_init(adapter);
err = ixgbe_sw_init(adapter, ii);
if (err)
goto err_sw_init;

Expand Down
Loading

0 comments on commit 9811d1e

Please sign in to comment.