Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/net-next

Jeff Kirsher says:

====================
This series contains updates to ixgbe only.

v2- Dropped the following 2 patches from the series:
 ixgbe: Support using build_skb in the case that jumbo frames are disabled
 ixgbe: walk pci-e bus to find minimum width

Ben Hutchings found a bug with Alex's patch, so that patch was dropped
permanently.  Jacob's "walk PCIe bus" patch is being re-worked for
a more generic solution so that other drivers can benefit.

In the remaining patches...
Alex provides a fix where we were incorrectly checking the entire frag_off
field when we only wanted the fragment offset.  Alex also cleans up
the check for PAGE_SIZE, since the default configuration allocates 32K
for all buffers.

Emil provides a change to the calculation of eerd so that it is consistent
between the read and write functions by using | instead of +.

Jacob adds support for displaying PCIe Gen3 link speed, which was
previously missing from the ixgbe driver.  He also provides a patch
to clean up ixgbe_get_bus_info_generic to call some conversion
functions, which are used also in another patch provided by Jacob.
Jacob modifies the driver to enable certain devices (which have an
internal switch) to read from the physical slot rather than reading
data from the internal switch.

Don provides a couple of fixes (which are more appropriate for net-next),
one of which resolves an issue where ixgbe was only turning on the laser
when the adapter was up which caused issues for those who wanted to
access the MNG firmware while the port was in a down state.  The other
fix is for WoL when currently linked at 1G.  Lastly Don bumps the driver
version keep the in-kernel driver up to date with the current functionality.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 18, 2013
2 parents 0e280af + 8c5afd6 commit c1cb0d3
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 45 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.release_swfw_sync = &ixgbe_release_swfw_sync,
.get_thermal_sensor_data = NULL,
.init_thermal_sensor_thresh = NULL,
.mng_fw_enabled = NULL,
};

static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
Expand Down
51 changes: 46 additions & 5 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,34 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);

static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
{
u32 fwsm, manc, factps;

fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
return false;

manc = IXGBE_READ_REG(hw, IXGBE_MANC);
if (!(manc & IXGBE_MANC_RCV_TCO_EN))
return false;

factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
if (factps & IXGBE_FACTPS_MNGCG)
return false;

return true;
}

static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;

/* enable the laser control functions for SFP+ fiber */
if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
/* enable the laser control functions for SFP+ fiber
* and MNG not enabled
*/
if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
!hw->mng_fw_enabled) {
mac->ops.disable_tx_laser =
&ixgbe_disable_tx_laser_multispeed_fiber;
mac->ops.enable_tx_laser =
Expand Down Expand Up @@ -563,7 +585,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
return status;

/* Flap the tx laser if it has not already been done */
hw->mac.ops.flap_tx_laser(hw);
if (hw->mac.ops.flap_tx_laser)
hw->mac.ops.flap_tx_laser(hw);

/*
* Wait for the controller to acquire link. Per IEEE 802.3ap,
Expand Down Expand Up @@ -615,7 +638,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
return status;

/* Flap the tx laser if it has not already been done */
hw->mac.ops.flap_tx_laser(hw);
if (hw->mac.ops.flap_tx_laser)
hw->mac.ops.flap_tx_laser(hw);

/* Wait for the link partner to also set speed */
msleep(100);
Expand Down Expand Up @@ -933,6 +957,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
ixgbe_link_speed link_speed;
s32 status;
u32 ctrl, i, autoc, autoc2;
u32 curr_lms;
bool link_up = false;

/* Call adapter stop to disable tx/rx and clear interrupts */
Expand Down Expand Up @@ -964,6 +989,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
hw->phy.ops.reset(hw);

/* remember AUTOC LMS from before we reset */
curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;

mac_reset_top:
/*
* Issue global reset to the MAC. Needs to be SW reset if link is up.
Expand Down Expand Up @@ -1019,6 +1047,19 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
hw->mac.orig_autoc2 = autoc2;
hw->mac.orig_link_settings_stored = true;
} else {

/* If MNG FW is running on a multi-speed device that
* doesn't autoneg with out driver support we need to
* leave LMS in the state it was before we MAC reset.
* Likewise if we support WoL we don't want change the
* LMS state either.
*/
if ((hw->phy.multispeed_fiber && hw->mng_fw_enabled) ||
hw->wol_supported)
hw->mac.orig_autoc =
(hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
curr_lms;

if (autoc != hw->mac.orig_autoc) {
/* Need SW/FW semaphore around AUTOC writes if LESM is
* on, likewise reset_pipeline requires us to hold
Expand Down Expand Up @@ -2216,7 +2257,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.release_swfw_sync = &ixgbe_release_swfw_sync,
.get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic,
.init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,

.mng_fw_enabled = &ixgbe_mng_enabled,
};

static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
Expand Down
63 changes: 33 additions & 30 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,36 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
return 0;
}

enum ixgbe_bus_width ixgbe_convert_bus_width(u16 link_status)
{
switch (link_status & IXGBE_PCI_LINK_WIDTH) {
case IXGBE_PCI_LINK_WIDTH_1:
return ixgbe_bus_width_pcie_x1;
case IXGBE_PCI_LINK_WIDTH_2:
return ixgbe_bus_width_pcie_x2;
case IXGBE_PCI_LINK_WIDTH_4:
return ixgbe_bus_width_pcie_x4;
case IXGBE_PCI_LINK_WIDTH_8:
return ixgbe_bus_width_pcie_x8;
default:
return ixgbe_bus_width_unknown;
}
}

enum ixgbe_bus_speed ixgbe_convert_bus_speed(u16 link_status)
{
switch (link_status & IXGBE_PCI_LINK_SPEED) {
case IXGBE_PCI_LINK_SPEED_2500:
return ixgbe_bus_speed_2500;
case IXGBE_PCI_LINK_SPEED_5000:
return ixgbe_bus_speed_5000;
case IXGBE_PCI_LINK_SPEED_8000:
return ixgbe_bus_speed_8000;
default:
return ixgbe_bus_speed_unknown;
}
}

/**
* ixgbe_get_bus_info_generic - Generic set PCI bus info
* @hw: pointer to hardware structure
Expand All @@ -610,35 +640,8 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
pci_read_config_word(adapter->pdev, IXGBE_PCI_LINK_STATUS,
&link_status);

switch (link_status & IXGBE_PCI_LINK_WIDTH) {
case IXGBE_PCI_LINK_WIDTH_1:
hw->bus.width = ixgbe_bus_width_pcie_x1;
break;
case IXGBE_PCI_LINK_WIDTH_2:
hw->bus.width = ixgbe_bus_width_pcie_x2;
break;
case IXGBE_PCI_LINK_WIDTH_4:
hw->bus.width = ixgbe_bus_width_pcie_x4;
break;
case IXGBE_PCI_LINK_WIDTH_8:
hw->bus.width = ixgbe_bus_width_pcie_x8;
break;
default:
hw->bus.width = ixgbe_bus_width_unknown;
break;
}

switch (link_status & IXGBE_PCI_LINK_SPEED) {
case IXGBE_PCI_LINK_SPEED_2500:
hw->bus.speed = ixgbe_bus_speed_2500;
break;
case IXGBE_PCI_LINK_SPEED_5000:
hw->bus.speed = ixgbe_bus_speed_5000;
break;
default:
hw->bus.speed = ixgbe_bus_speed_unknown;
break;
}
hw->bus.width = ixgbe_convert_bus_width(link_status);
hw->bus.speed = ixgbe_convert_bus_speed(link_status);

mac->ops.set_lan_id(hw);

Expand Down Expand Up @@ -1125,7 +1128,7 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
}

for (i = 0; i < words; i++) {
eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
IXGBE_EEPROM_RW_REG_START;

IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
u32 pba_num_size);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
enum ixgbe_bus_width ixgbe_convert_bus_width(u16 link_status);
enum ixgbe_bus_speed ixgbe_convert_bus_speed(u16 link_status);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
Expand Down
76 changes: 66 additions & 10 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ char ixgbe_default_device_descr[] =
static char ixgbe_default_device_descr[] =
"Intel(R) 10 Gigabit Network Connection";
#endif
#define DRV_VERSION "3.11.33-k"
#define DRV_VERSION "3.13.10-k"
const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2013 Intel Corporation.";
Expand Down Expand Up @@ -149,6 +149,52 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
u32 reg, u16 *value)
{
int pos = 0;
struct pci_dev *parent_dev;
struct pci_bus *parent_bus;

parent_bus = adapter->pdev->bus->parent;
if (!parent_bus)
return -1;

parent_dev = parent_bus->self;
if (!parent_dev)
return -1;

pos = pci_find_capability(parent_dev, PCI_CAP_ID_EXP);
if (!pos)
return -1;

pci_read_config_word(parent_dev, pos + reg, value);
return 0;
}

static s32 ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u16 link_status = 0;
int err;

hw->bus.type = ixgbe_bus_type_pci_express;

/* Get the negotiated link width and speed from PCI config space of the
* parent, as this device is behind a switch
*/
err = ixgbe_read_pci_cfg_word_parent(adapter, 18, &link_status);

/* assume caller will handle error case */
if (err)
return err;

hw->bus.width = ixgbe_convert_bus_width(link_status);
hw->bus.speed = ixgbe_convert_bus_speed(link_status);

return 0;
}

static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
{
if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
Expand Down Expand Up @@ -1337,7 +1383,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,
return hdr.network - data;

/* record next protocol if header is present */
if (!hdr.ipv4->frag_off)
if (!(hdr.ipv4->frag_off & htons(IP_OFFSET)))
nexthdr = hdr.ipv4->protocol;
} else if (protocol == __constant_htons(ETH_P_IPV6)) {
if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
Expand Down Expand Up @@ -6425,9 +6471,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
struct ixgbe_tx_buffer *first;
int tso;
u32 tx_flags = 0;
#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
unsigned short f;
#endif
u16 count = TXD_USE_COUNT(skb_headlen(skb));
__be16 protocol = skb->protocol;
u8 hdr_len = 0;
Expand All @@ -6439,12 +6483,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
* + 1 desc for context descriptor,
* otherwise try next time
*/
#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
#else
count += skb_shinfo(skb)->nr_frags;
#endif

if (ixgbe_maybe_stop_tx(tx_ring, count + 3)) {
tx_ring->tx_stats.tx_busy++;
return NETDEV_TX_BUSY;
Expand Down Expand Up @@ -7329,6 +7370,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_sw_init;

/* Cache if MNG FW is up so we don't have to read the REG later */
if (hw->mac.ops.mng_fw_enabled)
hw->mng_fw_enabled = hw->mac.ops.mng_fw_enabled(hw);

/* Make it possible the adapter to be woken up via WOL */
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
Expand Down Expand Up @@ -7481,7 +7526,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* WOL not supported for all devices */
adapter->wol = 0;
hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap);
if (ixgbe_wol_supported(adapter, pdev->device, pdev->subsystem_device))
hw->wol_supported = ixgbe_wol_supported(adapter, pdev->device,
pdev->subsystem_device);
if (hw->wol_supported)
adapter->wol = IXGBE_WUFC_MAG;

device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
Expand All @@ -7492,10 +7539,13 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

/* pick up the PCI bus settings for reporting later */
hw->mac.ops.get_bus_info(hw);
if (hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP)
ixgbe_get_parent_bus_info(adapter);

/* print bus type/speed/width info */
e_dev_info("(PCI Express:%s:%s) %pM\n",
(hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
(hw->bus.speed == ixgbe_bus_speed_8000 ? "8.0GT/s" :
hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
"Unknown"),
(hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
Expand Down Expand Up @@ -7579,6 +7629,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ixgbe_dbg_adapter_init(adapter);
#endif /* CONFIG_DEBUG_FS */

/* Need link setup for MNG FW, else wait for IXGBE_UP */
if (hw->mng_fw_enabled && hw->mac.ops.setup_link)
hw->mac.ops.setup_link(hw,
IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL,
true);

return 0;

err_register:
Expand Down
Loading

0 comments on commit c1cb0d3

Please sign in to comment.