netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next 00/15][pull request] Intel Wired LAN Driver Updates
@ 2013-07-29 12:51 Jeff Kirsher
  2013-07-29 12:51 ` [net-next 01/15] ixgbe: Retain VLAN filtering in promiscuous + VT mode Jeff Kirsher
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:51 UTC (permalink / raw)
  To: davem, bhelgaas; +Cc: Jeff Kirsher, netdev, gospo, sassmann, linux-pci

This series contains updates to ixgbe and pci.

The first patch for ixgbe from Greg Rose is the second submission.  The
first submission of "ixgbe: Retain VLAN filtering in promiscuous + VT
mode" had a typo, which Joe Perches pointed out and is fixed in this
submission.

Alex updates the ixgbe driver to use the generic helper pci_vfs_assigned
instead of the driver specific function ixgbe_vfs_are_assigned.

Don Skidmore provides 4 patches for ixgbe, the first being a fix for
flow control ethtool reporting.  Originally ixgbe_device_supports_autoneg_fc()
was expected to be called by only copper devices, which lead to false
information being displayed via ethtool.  Two other patches add support
for fixed fiber for SFP+ devices and the addition of a quad-port x520
adapter.  The last patch simply bumps the driver version.

Emil Tantilov provides 3 fixes for ixgbe, two of which resolve
semaphore lock issues.  The third fix resolves several issues in the
previous implementation of the SFF data dumps of SFP+ modules.

The remaining ixgbe and pci patches are from Jacob Keller.  The pci
patches exposes bus speed, link speed and bus width so that drivers
can take advantage of this information.  In addition, adds a pci function
which obtains minimum link width and speed.  Jacob also provides the
ixgbe patch to incorporate the pci function. He provides a patch that
fixes a lockdep issue created due to ixgbe_ptp_stop always running
cancel_work_sync even if the work item had not been created properly with
INIT_WORK. This issue was found and reported by Stephen Hemminger.

The following are changes since commit fe6f700d6cbb7e8a61711e325f53d9c9e0a42a4c:
  net/mlx4_core: Respond to operation request by firmware
and are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master

Alexander Duyck (1):
  ixgbe: Use pci_vfs_assigned instead of ixgbe_vfs_are_assigned

Don Skidmore (4):
  ixgbe: fix fc autoneg ethtool reporting.
  ixgbe: add new media type
  ixgbe: bump version number
  ixgbe: add support for quad-port x520 adapter

Emil Tantilov (3):
  ixgbe: fix semaphore lock for I2C read/writes on 82598
  ixgbe: fix SFF data dumps of SFP+ modules
  ixgbe: clear semaphore bits on timeouts

Greg Rose (1):
  ixgbe: Retain VLAN filtering in promiscuous + VT mode

Jacob Keller (6):
  pci: expose pcie_link_speed and pcix_bus_speed arrays
  pci: move enum pcie_link_width into pci.h
  pci: Add function to obtain minimum link width and speed
  ixgbe: call pcie_get_mimimum_link to check if device has enough
    bandwidth
  ixgbe: fix lockdep annotation issue for ptp's work item
  ixgbe: rename LL_EXTENDED_STATS to use queue instead of q

 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   7 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c   |  34 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c   | 231 ++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c  |  88 +++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |  94 ++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    | 158 +++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c     | 470 ++++++++++++++++-------
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h     |  41 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c     |  12 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c   | 101 +++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  12 +
 drivers/pci/pci.c                                |  43 +++
 drivers/pci/probe.c                              |   4 +-
 include/linux/pci.h                              |  18 +
 include/linux/pci_hotplug.h                      |  13 -
 15 files changed, 983 insertions(+), 343 deletions(-)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [net-next 01/15] ixgbe: Retain VLAN filtering in promiscuous + VT mode
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
@ 2013-07-29 12:51 ` Jeff Kirsher
  2013-07-29 12:51 ` [net-next 02/15] ixgbe: Use pci_vfs_assigned instead of ixgbe_vfs_are_assigned Jeff Kirsher
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:51 UTC (permalink / raw)
  To: davem; +Cc: Greg Rose, netdev, gospo, sassmann, Jeff Kirsher

From: Greg Rose <gregory.v.rose@intel.com>

When using the new bridge FDB interface to allow SR-IOV virtual function
network devices to communicate with SW bridged network devices the
physical function is placed into promiscuous mode and hardware VLAN
filtering is disabled.  This defeats the ability to use VLAN tagging
to isolate user networks.  When the device is in promiscuous mode and
VT mode simultaneously ensure that VLAN hardware filtering remains
enabled.

Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 11 ++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 66 ++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index bad8f14..d837f81 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3724,8 +3724,15 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 		hw->addr_ctrl.user_set_promisc = true;
 		fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 		vmolr |= (IXGBE_VMOLR_ROPE | IXGBE_VMOLR_MPE);
-		/* don't hardware filter vlans in promisc mode */
-		ixgbe_vlan_filter_disable(adapter);
+		/* Only disable hardware filter vlans in promiscuous mode
+		 * if SR-IOV and VMDQ are disabled - otherwise ensure
+		 * that hardware VLAN filters remain enabled.
+		 */
+		if (!(adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
+					IXGBE_FLAG_SRIOV_ENABLED)))
+			ixgbe_vlan_filter_disable(adapter);
+		else
+			ixgbe_vlan_filter_enable(adapter);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			fctrl |= IXGBE_FCTRL_MPE;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 1e7d587..6c624c9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -768,6 +768,29 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
 	return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
 }
 
+static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
+{
+	u32 vlvf;
+	s32 regindex;
+
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* Search for the vlan id in the VLVF entries */
+	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
+		if ((vlvf & VLAN_VID_MASK) == vlan)
+			break;
+	}
+
+	/* Return a negative value if not found */
+	if (regindex >= IXGBE_VLVF_ENTRIES)
+		regindex = -1;
+
+	return regindex;
+}
+
 static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 				 u32 *msgbuf, u32 vf)
 {
@@ -775,6 +798,9 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 	int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
 	int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
 	int err;
+	s32 reg_ndx;
+	u32 vlvf;
+	u32 bits;
 	u8 tcs = netdev_get_num_tc(adapter->netdev);
 
 	if (adapter->vfinfo[vf].pf_vlan || tcs) {
@@ -790,10 +816,50 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 	else if (adapter->vfinfo[vf].vlan_count)
 		adapter->vfinfo[vf].vlan_count--;
 
+	/* in case of promiscuous mode any VLAN filter set for a VF must
+	 * also have the PF pool added to it.
+	 */
+	if (add && adapter->netdev->flags & IFF_PROMISC)
+		err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
+
 	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
 	if (!err && adapter->vfinfo[vf].spoofchk_enabled)
 		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
 
+	/* Go through all the checks to see if the VLAN filter should
+	 * be wiped completely.
+	 */
+	if (!add && adapter->netdev->flags & IFF_PROMISC) {
+		reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
+		if (reg_ndx < 0)
+			goto out;
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
+		/* See if any other pools are set for this VLAN filter
+		 * entry other than the PF.
+		 */
+		if (VMDQ_P(0) < 32) {
+			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
+			bits &= ~(1 << VMDQ_P(0));
+			bits |= IXGBE_READ_REG(hw,
+					       IXGBE_VLVFB(reg_ndx * 2) + 1);
+		} else {
+			bits = IXGBE_READ_REG(hw,
+					      IXGBE_VLVFB(reg_ndx * 2) + 1);
+			bits &= ~(1 << (VMDQ_P(0) - 32));
+			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
+		}
+
+		/* If the filter was removed then ensure PF pool bit
+		 * is cleared if the PF only added itself to the pool
+		 * because the PF is in promiscuous mode.
+		 */
+		if ((vlvf & VLAN_VID_MASK) == vid &&
+		    !test_bit(vid, adapter->active_vlans) && !bits)
+			ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
+	}
+
+out:
+
 	return err;
 }
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 02/15] ixgbe: Use pci_vfs_assigned instead of ixgbe_vfs_are_assigned
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
  2013-07-29 12:51 ` [net-next 01/15] ixgbe: Retain VLAN filtering in promiscuous + VT mode Jeff Kirsher
@ 2013-07-29 12:51 ` Jeff Kirsher
  2013-07-29 12:51 ` [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting Jeff Kirsher
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:51 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher

From: Alexander Duyck <alexander.h.duyck@intel.com>

This change makes it so that the ixgbe driver uses the generic helper
pci_vfs_assigned instead of the ixgbe specific function
ixgbe_vfs_are_assigned.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 35 +-------------------------
 1 file changed, 1 insertion(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 6c624c9..73c8e73 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -173,39 +173,6 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
 	ixgbe_disable_sriov(adapter);
 }
 
-static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter)
-{
-	struct pci_dev *pdev = adapter->pdev;
-	struct pci_dev *vfdev;
-	int dev_id;
-
-	switch (adapter->hw.mac.type) {
-	case ixgbe_mac_82599EB:
-		dev_id = IXGBE_DEV_ID_82599_VF;
-		break;
-	case ixgbe_mac_X540:
-		dev_id = IXGBE_DEV_ID_X540_VF;
-		break;
-	default:
-		return false;
-	}
-
-	/* loop through all the VFs to see if we own any that are assigned */
-	vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
-	while (vfdev) {
-		/* if we don't own it we don't care */
-		if (vfdev->is_virtfn && vfdev->physfn == pdev) {
-			/* if it is assigned we cannot release it */
-			if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
-				return true;
-		}
-
-		vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev);
-	}
-
-	return false;
-}
-
 #endif /* #ifdef CONFIG_PCI_IOV */
 int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
 {
@@ -235,7 +202,7 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
 	 * without causing issues, so just leave the hardware
 	 * available but disabled
 	 */
-	if (ixgbe_vfs_are_assigned(adapter)) {
+	if (pci_vfs_assigned(adapter->pdev)) {
 		e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
 		return -EPERM;
 	}
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting.
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
  2013-07-29 12:51 ` [net-next 01/15] ixgbe: Retain VLAN filtering in promiscuous + VT mode Jeff Kirsher
  2013-07-29 12:51 ` [net-next 02/15] ixgbe: Use pci_vfs_assigned instead of ixgbe_vfs_are_assigned Jeff Kirsher
@ 2013-07-29 12:51 ` Jeff Kirsher
  2013-07-30  5:18   ` David Miller
  2013-07-29 12:52 ` [net-next 04/15] ixgbe: add new media type Jeff Kirsher
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:51 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, sassmann, Jeff Kirsher

From: Don Skidmore <donald.c.skidmore@intel.com>

Originally ixgbe_device_supports_autoneg_fc() was only expected to
be called by copper devices.  This would lead to false information
to be displayed via ethtool.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c  | 40 +++++++++++++++++++-----
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |  9 +++---
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 9bcdeb8..3c6859f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -67,15 +67,39 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
  **/
 s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
 {
+	bool supported = false;
+	ixgbe_link_speed speed;
+	bool link_up;
 
-	switch (hw->device_id) {
-	case IXGBE_DEV_ID_X540T:
-	case IXGBE_DEV_ID_X540T1:
-	case IXGBE_DEV_ID_82599_T3_LOM:
-		return 0;
+	switch (hw->phy.media_type) {
+	case ixgbe_media_type_fiber:
+		hw->mac.ops.check_link(hw, &speed, &link_up, false);
+		/* if link is down, assume supported */
+		if (link_up)
+			supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
+				true : false;
+		else
+			supported = true;
+		break;
+	case ixgbe_media_type_backplane:
+		supported = true;
+		break;
+	case ixgbe_media_type_copper:
+		/* only some copper devices support flow control autoneg */
+		switch (hw->device_id) {
+		case IXGBE_DEV_ID_82599_T3_LOM:
+		case IXGBE_DEV_ID_X540T:
+		case IXGBE_DEV_ID_X540T1:
+			supported = true;
+			break;
+		default:
+			break;
+		}
 	default:
-		return IXGBE_ERR_FC_NOT_SUPPORTED;
+		break;
 	}
+
+	return supported;
 }
 
 /**
@@ -234,7 +258,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
 						      IXGBE_GSSR_MAC_CSR_SM);
 
 	} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
-		    (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
+		    (ixgbe_device_supports_autoneg_fc(hw))) {
 		hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
 				      MDIO_MMD_AN, reg_cu);
 	}
@@ -2392,7 +2416,7 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 
 	/* Autoneg flow control on copper adapters */
 	case ixgbe_media_type_copper:
-		if (ixgbe_device_supports_autoneg_fc(hw) == 0)
+		if (ixgbe_device_supports_autoneg_fc(hw))
 			ret_val = ixgbe_fc_autoneg_copper(hw);
 		break;
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 24e2e7a..ae58a92 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -355,10 +355,11 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	if (hw->fc.disable_fc_autoneg)
-		pause->autoneg = 0;
-	else
+	if (ixgbe_device_supports_autoneg_fc(hw) &&
+	    !hw->fc.disable_fc_autoneg)
 		pause->autoneg = 1;
+	else
+		pause->autoneg = 0;
 
 	if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
 		pause->rx_pause = 1;
@@ -384,7 +385,7 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
 
 	/* some devices do not support autoneg of link flow control */
 	if ((pause->autoneg == AUTONEG_ENABLE) &&
-	    (ixgbe_device_supports_autoneg_fc(hw) != 0))
+	    !ixgbe_device_supports_autoneg_fc(hw))
 		return -EINVAL;
 
 	fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 04/15] ixgbe: add new media type
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (2 preceding siblings ...)
  2013-07-29 12:51 ` [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-30  5:20   ` David Miller
  2013-07-29 12:52 ` [net-next 05/15] ixgbe: bump version number Jeff Kirsher
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, sassmann, Jeff Kirsher

From: Don Skidmore <donald.c.skidmore@intel.com>

This patch adds support for a new media type fiber_fixed.  This is useful
to avoid all the SFP+ hot plug support path on devices who's fix fiber need
not worry about such things.  This patch is needed for a following patch
that adds support for "fiber_fixed" devices.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c  | 84 ++++++++++++++++++++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |  3 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h    |  5 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |  1 +
 4 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index 0b82d38..b92765b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -527,6 +527,66 @@ static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 }
 
 /**
+ *  ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
+ *  @hw: pointer to hardware structure
+ *  @speed: link speed to set
+ *
+ *  We set the module speed differently for fixed fiber.  For other
+ *  multi-speed devices we don't have an error value so here if we
+ *  detect an error we just log it and exit.
+ */
+static void ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw,
+					ixgbe_link_speed speed)
+{
+	s32 status;
+	u8 rs, eeprom_data;
+
+	switch (speed) {
+	case IXGBE_LINK_SPEED_10GB_FULL:
+		/* one bit mask same as setting on */
+		rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
+		break;
+	case IXGBE_LINK_SPEED_1GB_FULL:
+		rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
+		break;
+	default:
+		hw_dbg(hw, "Invalid fixed module speed\n");
+		return;
+	}
+
+	/* Set RS0 */
+	status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+					   IXGBE_I2C_EEPROM_DEV_ADDR2,
+					   &eeprom_data);
+	if (status) {
+		hw_dbg(hw, "Failed to read Rx Rate Select RS0\n");
+		goto out;
+	}
+
+	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+					    IXGBE_I2C_EEPROM_DEV_ADDR2,
+					    eeprom_data);
+	if (status) {
+		hw_dbg(hw, "Failed to read Rx Rate Select RS1\n");
+		goto out;
+	}
+
+	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+					    IXGBE_I2C_EEPROM_DEV_ADDR2,
+					    eeprom_data);
+	if (status) {
+		hw_dbg(hw, "Failed to write Rx Rate Select RS1\n");
+		goto out;
+	}
+out:
+	return;
+}
+
+/**
  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
@@ -573,9 +633,14 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 			goto out;
 
 		/* Set the module link speed */
-		esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
-		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-		IXGBE_WRITE_FLUSH(hw);
+		if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+			ixgbe_set_fiber_fixed_speed(hw,
+					IXGBE_LINK_SPEED_10GB_FULL);
+		} else {
+			esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+			IXGBE_WRITE_FLUSH(hw);
+		}
 
 		/* Allow module to change analog characteristics (1G->10G) */
 		msleep(40);
@@ -625,10 +690,15 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 			goto out;
 
 		/* Set the module link speed */
-		esdp_reg &= ~IXGBE_ESDP_SDP5;
-		esdp_reg |= IXGBE_ESDP_SDP5_DIR;
-		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-		IXGBE_WRITE_FLUSH(hw);
+		if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+			ixgbe_set_fiber_fixed_speed(hw,
+						IXGBE_LINK_SPEED_1GB_FULL);
+		} else {
+			esdp_reg &= ~IXGBE_ESDP_SDP5;
+			esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+			IXGBE_WRITE_FLUSH(hw);
+		}
 
 		/* Allow module to change analog characteristics (10G->1G) */
 		msleep(40);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 3c6859f..6e5d4bc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -72,6 +72,7 @@ s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
 	bool link_up;
 
 	switch (hw->phy.media_type) {
+	case ixgbe_media_type_fiber_fixed:
 	case ixgbe_media_type_fiber:
 		hw->mac.ops.check_link(hw, &speed, &link_up, false);
 		/* if link is down, assume supported */
@@ -138,6 +139,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
 	 * we link at 10G, the 1G advertisement is harmless and vice versa.
 	 */
 	switch (hw->phy.media_type) {
+	case ixgbe_media_type_fiber_fixed:
 	case ixgbe_media_type_fiber:
 	case ixgbe_media_type_backplane:
 		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
@@ -2404,6 +2406,7 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 
 	switch (hw->phy.media_type) {
 	/* Autoneg flow control on fiber adapters */
+	case ixgbe_media_type_fiber_fixed:
 	case ixgbe_media_type_fiber:
 		if (speed == IXGBE_LINK_SPEED_1GB_FULL)
 			ret_val = ixgbe_fc_autoneg_fiber(hw);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index 886a343..046a01e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -44,6 +44,8 @@
 #define IXGBE_SFF_CABLE_SPEC_COMP    0x3C
 #define IXGBE_SFF_SFF_8472_SWAP      0x5C
 #define IXGBE_SFF_SFF_8472_COMP      0x5E
+#define IXGBE_SFF_SFF_8472_OSCB         0x6E
+#define IXGBE_SFF_SFF_8472_ESCB         0x76
 
 /* Bitmasks */
 #define IXGBE_SFF_DA_PASSIVE_CABLE           0x4
@@ -54,6 +56,9 @@
 #define IXGBE_SFF_1GBASET_CAPABLE            0x8
 #define IXGBE_SFF_10GBASESR_CAPABLE          0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE          0x20
+#define IXGBE_SFF_SOFT_RS_SELECT_MASK   0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_10G    0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_1G     0x0
 #define IXGBE_SFF_ADDRESSING_MODE	     0x4
 #define IXGBE_I2C_EEPROM_READ_MASK           0x100
 #define IXGBE_I2C_EEPROM_STATUS_MASK         0x3
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 70c6aa3..8968ea0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2622,6 +2622,7 @@ enum ixgbe_sfp_type {
 enum ixgbe_media_type {
 	ixgbe_media_type_unknown = 0,
 	ixgbe_media_type_fiber,
+	ixgbe_media_type_fiber_fixed,
 	ixgbe_media_type_fiber_lco,
 	ixgbe_media_type_copper,
 	ixgbe_media_type_backplane,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 05/15] ixgbe: bump version number
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (3 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 04/15] ixgbe: add new media type Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 12:52 ` [net-next 06/15] ixgbe: fix semaphore lock for I2C read/writes on 82598 Jeff Kirsher
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, sassmann, Jeff Kirsher

From: Don Skidmore <donald.c.skidmore@intel.com>

Bump the version number to better match with a similar version of the
out of tree driver.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index d837f81..6a2b7a0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -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.13.10-k"
+#define DRV_VERSION "3.15.1-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
 				"Copyright (c) 1999-2013 Intel Corporation.";
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 06/15] ixgbe: fix semaphore lock for I2C read/writes on 82598
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (4 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 05/15] ixgbe: bump version number Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 12:52 ` [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules Jeff Kirsher
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher

From: Emil Tantilov <emil.s.tantilov@intel.com>

ixgbe_read/write_i2c_phy_82598() does not hold the SWFW_SYNC
semaphore for the entire function. Instead the lock is held only
during the phy.ops.read/write_reg operations. As result when the
function is being called simultaneously the I2C read/writes can
be corrupted.

The following patch introduces the SWFW_SYNC semaphore for the
entire ixgbe_read/write_i2c_phy_82598() function. To accomplish
this I had to create 2 separate functions:

ixgbe_read_phy_reg_mdi()
ixgbe_write_phy_reg_mdi()

Those functions are identical to ixgbe_read/write_phy_reg_generic()
sans the locking, and can be used in ixgbe_read/write_i2c_phy_82598()
with the SWFW_SYNC semaphore being held.

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c |  32 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c   | 292 +++++++++++++------------
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h   |   4 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |   2 +
 4 files changed, 182 insertions(+), 148 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 4a5bfb6..d011d5c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1018,8 +1018,17 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
 	u16 sfp_addr = 0;
 	u16 sfp_data = 0;
 	u16 sfp_stat = 0;
+	u16 gssr;
 	u32 i;
 
+	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
+		gssr = IXGBE_GSSR_PHY1_SM;
+	else
+		gssr = IXGBE_GSSR_PHY0_SM;
+
+	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
+		return IXGBE_ERR_SWFW_SYNC;
+
 	if (hw->phy.type == ixgbe_phy_nl) {
 		/*
 		 * phy SDA/SCL registers are at addresses 0xC30A to
@@ -1028,17 +1037,17 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
 		 */
 		sfp_addr = (dev_addr << 8) + byte_offset;
 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
-		hw->phy.ops.write_reg(hw,
-		                      IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
-		                      MDIO_MMD_PMAPMD,
-		                      sfp_addr);
+		hw->phy.ops.write_reg_mdi(hw,
+					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
+					  MDIO_MMD_PMAPMD,
+					  sfp_addr);
 
 		/* Poll status */
 		for (i = 0; i < 100; i++) {
-			hw->phy.ops.read_reg(hw,
-			                     IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
-			                     MDIO_MMD_PMAPMD,
-			                     &sfp_stat);
+			hw->phy.ops.read_reg_mdi(hw,
+						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
+						MDIO_MMD_PMAPMD,
+						&sfp_stat);
 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
 				break;
@@ -1052,8 +1061,8 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
 		}
 
 		/* Read data */
-		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
-		                     MDIO_MMD_PMAPMD, &sfp_data);
+		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
+					MDIO_MMD_PMAPMD, &sfp_data);
 
 		*eeprom_data = (u8)(sfp_data >> 8);
 	} else {
@@ -1061,6 +1070,7 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
 	}
 
 out:
+	hw->mac.ops.release_swfw_sync(hw, gssr);
 	return status;
 }
 
@@ -1326,6 +1336,8 @@ static struct ixgbe_phy_operations phy_ops_82598 = {
 	.reset			= &ixgbe_reset_phy_generic,
 	.read_reg		= &ixgbe_read_phy_reg_generic,
 	.write_reg		= &ixgbe_write_phy_reg_generic,
+	.read_reg_mdi		= &ixgbe_read_phy_reg_mdi,
+	.write_reg_mdi		= &ixgbe_write_phy_reg_mdi,
 	.setup_link		= &ixgbe_setup_phy_link_generic,
 	.setup_link_speed	= &ixgbe_setup_phy_link_speed_generic,
 	.read_i2c_sff8472	= &ixgbe_read_i2c_sff8472_82598,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index e5691cc..71f554a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -204,7 +204,83 @@ out:
 }
 
 /**
+ *  ixgbe_read_phy_mdi - Reads a value from a specified PHY register without
+ *  the SWFW lock
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit address of PHY register to read
+ *  @phy_data: Pointer to read data from PHY register
+ **/
+s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
+		       u16 *phy_data)
+{
+	u32 i, data, command;
+
+	/* Setup and write the address cycle command */
+	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
+		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+
+	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
+
+	/* Check every 10 usec to see if the address cycle completed.
+	 * The MDI Command bit will clear when the operation is
+	 * complete
+	 */
+	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+		udelay(10);
+
+		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
+		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
+				break;
+	}
+
+
+	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+		hw_dbg(hw, "PHY address command did not complete.\n");
+		return IXGBE_ERR_PHY;
+	}
+
+	/* Address cycle complete, setup and write the read
+	 * command
+	 */
+	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
+		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+		   (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
+
+	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
+
+	/* Check every 10 usec to see if the address cycle
+	 * completed. The MDI Command bit will clear when the
+	 * operation is complete
+	 */
+	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+		udelay(10);
+
+		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
+		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
+			break;
+	}
+
+	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+		hw_dbg(hw, "PHY read command didn't complete\n");
+		return IXGBE_ERR_PHY;
+	}
+
+	/* Read operation is complete.  Get the data
+	 * from MSRWD
+	 */
+	data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
+	data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
+	*phy_data = (u16)(data);
+
+	return 0;
+}
+
+/**
  *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
+ *  using the SWFW lock - this function is needed in most cases
  *  @hw: pointer to hardware structure
  *  @reg_addr: 32 bit address of PHY register to read
  *  @phy_data: Pointer to read data from PHY register
@@ -212,10 +288,7 @@ out:
 s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                                u32 device_type, u16 *phy_data)
 {
-	u32 command;
-	u32 i;
-	u32 data;
-	s32 status = 0;
+	s32 status;
 	u16 gssr;
 
 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
@@ -223,86 +296,93 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
 	else
 		gssr = IXGBE_GSSR_PHY0_SM;
 
-	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
+	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) {
+		status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type,
+						phy_data);
+		hw->mac.ops.release_swfw_sync(hw, gssr);
+	} else {
 		status = IXGBE_ERR_SWFW_SYNC;
+	}
 
-	if (status == 0) {
-		/* Setup and write the address cycle command */
-		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-		           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-		           (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-		           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+	return status;
+}
 
-		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
+/**
+ *  ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register
+ *  without SWFW lock
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 5 bit device type
+ *  @phy_data: Data to write to the PHY register
+ **/
+s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
+				u32 device_type, u16 phy_data)
+{
+	u32 i, command;
 
-		/*
-		 * Check every 10 usec to see if the address cycle completed.
-		 * The MDI Command bit will clear when the operation is
-		 * complete
-		 */
-		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
-			udelay(10);
+	/* Put the data in the MDI single read and write data register*/
+	IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
 
-			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
+	/* Setup and write the address cycle command */
+	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
+		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+		   (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
 
-			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
-				break;
-		}
+	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
 
-		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
-			hw_dbg(hw, "PHY address command did not complete.\n");
-			status = IXGBE_ERR_PHY;
-		}
+	/*
+	 * Check every 10 usec to see if the address cycle completed.
+	 * The MDI Command bit will clear when the operation is
+	 * complete
+	 */
+	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+		udelay(10);
 
-		if (status == 0) {
-			/*
-			 * Address cycle complete, setup and write the read
-			 * command
-			 */
-			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-			           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-			           (hw->phy.mdio.prtad <<
-				    IXGBE_MSCA_PHY_ADDR_SHIFT) |
-			           (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
-
-			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
-			/*
-			 * Check every 10 usec to see if the address cycle
-			 * completed. The MDI Command bit will clear when the
-			 * operation is complete
-			 */
-			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
-				udelay(10);
-
-				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
-				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
-					break;
-			}
+		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
+		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
+			break;
+	}
 
-			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
-				hw_dbg(hw, "PHY read command didn't complete\n");
-				status = IXGBE_ERR_PHY;
-			} else {
-				/*
-				 * Read operation is complete.  Get the data
-				 * from MSRWD
-				 */
-				data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
-				data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
-				*phy_data = (u16)(data);
-			}
-		}
+	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+		hw_dbg(hw, "PHY address cmd didn't complete\n");
+		return IXGBE_ERR_PHY;
+	}
 
-		hw->mac.ops.release_swfw_sync(hw, gssr);
+	/*
+	 * Address cycle complete, setup and write the write
+	 * command
+	 */
+	command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
+		   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+		   (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+		   (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
+
+	IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
+
+	/* Check every 10 usec to see if the address cycle
+	 * completed. The MDI Command bit will clear when the
+	 * operation is complete
+	 */
+	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+		udelay(10);
+
+		command = IXGBE_READ_REG(hw, IXGBE_MSCA);
+		if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
+			break;
 	}
 
-	return status;
+	if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+		hw_dbg(hw, "PHY write cmd didn't complete\n");
+		return IXGBE_ERR_PHY;
+	}
+
+	return 0;
 }
 
 /**
  *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
+ *  using SWFW lock- this function is needed in most cases
  *  @hw: pointer to hardware structure
  *  @reg_addr: 32 bit PHY register to write
  *  @device_type: 5 bit device type
@@ -311,9 +391,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
 s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                                 u32 device_type, u16 phy_data)
 {
-	u32 command;
-	u32 i;
-	s32 status = 0;
+	s32 status;
 	u16 gssr;
 
 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
@@ -321,74 +399,12 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
 	else
 		gssr = IXGBE_GSSR_PHY0_SM;
 
-	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
-		status = IXGBE_ERR_SWFW_SYNC;
-
-	if (status == 0) {
-		/* Put the data in the MDI single read and write data register*/
-		IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
-
-		/* Setup and write the address cycle command */
-		command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-		           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-		           (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-		           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
-
-		IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
-		/*
-		 * Check every 10 usec to see if the address cycle completed.
-		 * The MDI Command bit will clear when the operation is
-		 * complete
-		 */
-		for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
-			udelay(10);
-
-			command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
-			if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
-				break;
-		}
-
-		if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
-			hw_dbg(hw, "PHY address cmd didn't complete\n");
-			status = IXGBE_ERR_PHY;
-		}
-
-		if (status == 0) {
-			/*
-			 * Address cycle complete, setup and write the write
-			 * command
-			 */
-			command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-			           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-			           (hw->phy.mdio.prtad <<
-				    IXGBE_MSCA_PHY_ADDR_SHIFT) |
-			           (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
-
-			IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
-			/*
-			 * Check every 10 usec to see if the address cycle
-			 * completed. The MDI Command bit will clear when the
-			 * operation is complete
-			 */
-			for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
-				udelay(10);
-
-				command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
-				if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
-					break;
-			}
-
-			if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
-				hw_dbg(hw, "PHY address cmd didn't complete\n");
-				status = IXGBE_ERR_PHY;
-			}
-		}
-
+	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) {
+		status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type,
+						 phy_data);
 		hw->mac.ops.release_swfw_sync(hw, gssr);
+	} else {
+		status = IXGBE_ERR_SWFW_SYNC;
 	}
 
 	return status;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index 046a01e..fe64e723 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -107,6 +107,10 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                                u32 device_type, u16 *phy_data);
 s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                                 u32 device_type, u16 phy_data);
+s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
+			   u32 device_type, u16 *phy_data);
+s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr,
+			    u32 device_type, u16 phy_data);
 s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
 s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
                                        ixgbe_link_speed speed,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 8968ea0..4c91ea6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2886,6 +2886,8 @@ struct ixgbe_phy_operations {
 	s32 (*reset)(struct ixgbe_hw *);
 	s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
 	s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
+	s32 (*read_reg_mdi)(struct ixgbe_hw *, u32, u32, u16 *);
+	s32 (*write_reg_mdi)(struct ixgbe_hw *, u32, u32, u16);
 	s32 (*setup_link)(struct ixgbe_hw *);
 	s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool);
 	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (5 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 06/15] ixgbe: fix semaphore lock for I2C read/writes on 82598 Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-08-02  9:08   ` Ben Hutchings
  2013-07-29 12:52 ` [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays Jeff Kirsher
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher

From: Emil Tantilov <emil.s.tantilov@intel.com>

This patch fixes several issues with the previous implementation of the
SFF data dump of SFP+ modules:

- removed the __IXGBE_READ_I2C flag - I2C access locking is handled in the
  HW specific routines

- fixed the read loop to read data from ee->offset to ee->len

- the reads fail if __IXGBE_IN_SFP_INIT is set in the process - this is
  needed because on some HW I2C operations can take long time and disrupt
  the SFP and link detection process

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reported-by: Ben Hutchings <bhutchings@solarflare.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 73 ++++++------------------
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  4 --
 3 files changed, 18 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 7be725c..d882278 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -754,7 +754,6 @@ enum ixgbe_state_t {
 	__IXGBE_DOWN,
 	__IXGBE_SERVICE_SCHED,
 	__IXGBE_IN_SFP_INIT,
-	__IXGBE_READ_I2C,
 };
 
 struct ixgbe_cb {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index ae58a92..da1ea28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2910,33 +2910,21 @@ static int ixgbe_get_module_info(struct net_device *dev,
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 status;
 	u8 sff8472_rev, addr_mode;
-	int ret_val = 0;
 	bool page_swap = false;
 
-	/* avoid concurent i2c reads */
-	while (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
-		msleep(100);
-
-	/* used by the service task */
-	set_bit(__IXGBE_READ_I2C, &adapter->state);
-
 	/* Check whether we support SFF-8472 or not */
 	status = hw->phy.ops.read_i2c_eeprom(hw,
 					     IXGBE_SFF_SFF_8472_COMP,
 					     &sff8472_rev);
-	if (status != 0) {
-		ret_val = -EIO;
-		goto err_out;
-	}
+	if (status != 0)
+		return -EIO;
 
 	/* addressing mode is not supported */
 	status = hw->phy.ops.read_i2c_eeprom(hw,
 					     IXGBE_SFF_SFF_8472_SWAP,
 					     &addr_mode);
-	if (status != 0) {
-		ret_val = -EIO;
-		goto err_out;
-	}
+	if (status != 0)
+		return -EIO;
 
 	if (addr_mode & IXGBE_SFF_ADDRESSING_MODE) {
 		e_err(drv, "Address change required to access page 0xA2, but not supported. Please report the module type to the driver maintainers.\n");
@@ -2953,9 +2941,7 @@ static int ixgbe_get_module_info(struct net_device *dev,
 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
 	}
 
-err_out:
-	clear_bit(__IXGBE_READ_I2C, &adapter->state);
-	return ret_val;
+	return 0;
 }
 
 static int ixgbe_get_module_eeprom(struct net_device *dev,
@@ -2969,48 +2955,25 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
 	int i = 0;
 	int ret_val = 0;
 
-	/* ixgbe_get_module_info is called before this function in all
-	 * cases, so we do not need any checks we already do above,
-	 * and can trust ee->len to be a known value.
-	 */
+	if (ee->len == 0)
+		return -EINVAL;
 
-	while (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
-		msleep(100);
-	set_bit(__IXGBE_READ_I2C, &adapter->state);
+	for (i = ee->offset; i < ee->len; i++) {
+		/* I2C reads can take long time */
+		if (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+			return -EBUSY;
 
-	/* Read the first block, SFF-8079 */
-	for (i = 0; i < ETH_MODULE_SFF_8079_LEN; i++) {
-		status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
-		if (status != 0) {
-			/* Error occured while reading module */
+		if (i < ETH_MODULE_SFF_8079_LEN)
+			status  = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
+		else
+			status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);
+
+		if (status != 0)
 			ret_val = -EIO;
-			goto err_out;
-		}
-		data[i] = databyte;
-	}
 
-	/* If the second block is requested, check if SFF-8472 is supported. */
-	if (ee->len == ETH_MODULE_SFF_8472_LEN) {
-		if (data[IXGBE_SFF_SFF_8472_COMP] == IXGBE_SFF_SFF_8472_UNSUP)
-			return -EOPNOTSUPP;
-
-		/* Read the second block, SFF-8472 */
-		for (i = ETH_MODULE_SFF_8079_LEN;
-		     i < ETH_MODULE_SFF_8472_LEN; i++) {
-			status = hw->phy.ops.read_i2c_sff8472(hw,
-				i - ETH_MODULE_SFF_8079_LEN, &databyte);
-			if (status != 0) {
-				/* Error occured while reading module */
-				ret_val = -EIO;
-				goto err_out;
-			}
-			data[i] = databyte;
-		}
+		data[i - ee->offset] = databyte;
 	}
 
-err_out:
-	clear_bit(__IXGBE_READ_I2C, &adapter->state);
-
 	return ret_val;
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6a2b7a0..3aff87e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5833,10 +5833,6 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
 	    !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
 		return;
 
-	/* concurent i2c reads are not supported */
-	if (test_bit(__IXGBE_READ_I2C, &adapter->state))
-		return;
-
 	/* someone else is in init, wait until next service event */
 	if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
 		return;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (6 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 18:44   ` Bjorn Helgaas
  2013-07-29 12:52 ` [net-next 09/15] pci: move enum pcie_link_width into pci.h Jeff Kirsher
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem, bhelgaas
  Cc: Jacob Keller, netdev, gospo, sassmann, linux-pci, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

pcie_link_speed and pcix_bus_speed are arrays used by probe.c to correctly
convert lnksta register values into the pci_bus_speed enum. These static arrays
are useful outside probe for this purpose. This patch makes these defines into
const arrays and exposes them with an extern header in linux/include/pci.h

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/pci/probe.c | 4 ++--
 include/linux/pci.h | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 46ada5c..496c5b0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -513,7 +513,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
 	return bridge;
 }
 
-static unsigned char pcix_bus_speed[] = {
+const unsigned char pcix_bus_speed[] = {
 	PCI_SPEED_UNKNOWN,		/* 0 */
 	PCI_SPEED_66MHz_PCIX,		/* 1 */
 	PCI_SPEED_100MHz_PCIX,		/* 2 */
@@ -532,7 +532,7 @@ static unsigned char pcix_bus_speed[] = {
 	PCI_SPEED_133MHz_PCIX_533	/* F */
 };
 
-static unsigned char pcie_link_speed[] = {
+const unsigned char pcie_link_speed[] = {
 	PCI_SPEED_UNKNOWN,		/* 0 */
 	PCIE_SPEED_2_5GT,		/* 1 */
 	PCIE_SPEED_5_0GT,		/* 2 */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0fd1f15..95ff993 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -120,6 +120,9 @@ typedef int __bitwise pci_power_t;
 /* Remember to update this when the list above changes! */
 extern const char *pci_power_names[];
 
+extern const unsigned char pcix_bus_speed[];
+extern const unsigned char pcie_link_speed[];
+
 static inline const char *pci_power_name(pci_power_t state)
 {
 	return pci_power_names[1 + (int) state];
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 09/15] pci: move enum pcie_link_width into pci.h
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (7 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 18:39   ` Bjorn Helgaas
  2013-07-29 12:52 ` [net-next 10/15] pci: Add function to obtain minimum link width and speed Jeff Kirsher
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem, bhelgaas
  Cc: Jacob Keller, netdev, gospo, sassmann, linux-pci, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

pcie_link_width is the enum used to define the link width values for a pcie
device. This enum should not be contained solely in pci_hotplug.h, and this
patch moves it next to pci_bus_speed in pci.h

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 include/linux/pci.h         | 13 +++++++++++++
 include/linux/pci_hotplug.h | 13 -------------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 95ff993..fc2d1fb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -186,6 +186,19 @@ enum pci_bus_flags {
 	PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
 };
 
+/* These values come from the PCI Express Spec */
+enum pcie_link_width {
+	PCIE_LNK_WIDTH_RESRV	= 0x00,
+	PCIE_LNK_X1		= 0x01,
+	PCIE_LNK_X2		= 0x02,
+	PCIE_LNK_X4		= 0x04,
+	PCIE_LNK_X8		= 0x08,
+	PCIE_LNK_X12		= 0x0C,
+	PCIE_LNK_X16		= 0x10,
+	PCIE_LNK_X32		= 0x20,
+	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
+};
+
 /* Based on the PCI Hotplug Spec, but some values are made up by us */
 enum pci_bus_speed {
 	PCI_SPEED_33MHz			= 0x00,
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 8db71dc..64e61e0 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -28,19 +28,6 @@
 #ifndef _PCI_HOTPLUG_H
 #define _PCI_HOTPLUG_H
 
-/* These values come from the PCI Express Spec */
-enum pcie_link_width {
-	PCIE_LNK_WIDTH_RESRV	= 0x00,
-	PCIE_LNK_X1		= 0x01,
-	PCIE_LNK_X2		= 0x02,
-	PCIE_LNK_X4		= 0x04,
-	PCIE_LNK_X8		= 0x08,
-	PCIE_LNK_X12		= 0x0C,
-	PCIE_LNK_X16		= 0x10,
-	PCIE_LNK_X32		= 0x20,
-	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
-};
-
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 10/15] pci: Add function to obtain minimum link width and speed
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (8 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 09/15] pci: move enum pcie_link_width into pci.h Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 18:45   ` Bjorn Helgaas
  2013-07-29 12:52 ` [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth Jeff Kirsher
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem, bhelgaas
  Cc: Jacob Keller, netdev, gospo, sassmann, linux-pci, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

A PCI Express device can potentially report a link width and speed which it will
not properly fulfill due to being plugged into a slower link higher in the
chain. This function walks up the PCI bus chain and calculates the minimum link
width and speed of this entire chain. This can be useful to enable a device to
determine if it has enough bandwidth for optimum functionality.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/pci/pci.c   | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci.h |  2 ++
 2 files changed, 45 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e37fea6..c71e78c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3579,6 +3579,49 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
 }
 
 /**
+ * pcie_get_minimum_link - determine minimum link settings of a PCI device
+ * @dev: PCI device to query
+ * @speed: storage for minimum speed
+ * @width: storage for minimum width
+ *
+ * This function will walk up the PCI device chain and determine the minimum
+ * link width and speed of the device.
+ */
+int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
+			  enum pcie_link_width *width)
+{
+	int ret;
+
+	*speed = PCI_SPEED_UNKNOWN;
+	*width = PCIE_LNK_WIDTH_UNKNOWN;
+
+	while (dev) {
+		u16 lnksta;
+		enum pci_bus_speed next_speed;
+		enum pcie_link_width next_width;
+
+		ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
+		if (ret)
+			return ret;
+
+		next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
+		next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
+			PCI_EXP_LNKSTA_NLW_SHIFT;
+
+		if (next_speed < *speed)
+			*speed = next_speed;
+
+		if (next_width < *width)
+			*width = next_width;
+
+		dev = dev->bus->self;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(pcie_get_minimum_link);
+
+/**
  * pci_select_bars - Make BAR mask from the type of resource
  * @dev: the PCI device for which BAR mask is made
  * @flags: resource type mask to be selected
diff --git a/include/linux/pci.h b/include/linux/pci.h
index fc2d1fb..38994de 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -937,6 +937,8 @@ int pcie_get_readrq(struct pci_dev *dev);
 int pcie_set_readrq(struct pci_dev *dev, int rq);
 int pcie_get_mps(struct pci_dev *dev);
 int pcie_set_mps(struct pci_dev *dev, int mps);
+int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
+			  enum pcie_link_width *width);
 int __pci_reset_function(struct pci_dev *dev);
 int __pci_reset_function_locked(struct pci_dev *dev);
 int pci_reset_function(struct pci_dev *dev);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (9 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 10/15] pci: Add function to obtain minimum link width and speed Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 21:46   ` Keller, Jacob E
  2013-07-29 12:52 ` [net-next 12/15] ixgbe: fix lockdep annotation issue for ptp's work item Jeff Kirsher
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Jacob Keller, netdev, gospo, sassmann, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

This patch uses the new pcie_get_minimum_link function to perform a check to
ensure that the adapter is hooked into a slot which is capable of providing the
necessary bandwidth. This check supersedes the original method which only
checked the current pci device. The new method is capable of determining the
minimum speed and link of an entire PCI chain.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 130 ++++++++++++++++++++++++--
 1 file changed, 123 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3aff87e..5ec2b74 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -195,6 +195,79 @@ static s32 ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter)
 	return 0;
 }
 
+/**
+ * ixgbe_check_from_parent - Determine whether PCIe info should come from parent
+ * @hw: hw specific details
+ *
+ * This function is used by probe to determine whether a device's PCI-Express
+ * bandwidth details should be gathered from the parent bus instead of from the
+ * device. Used to ensure that various locations all have the correct device ID
+ * checks.
+ */
+static inline bool ixgbe_pcie_from_parent(struct ixgbe_hw *hw)
+{
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82599_SFP_SF_QP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void ixgbe_check_minimum_link(struct ixgbe_adapter *adapter,
+				     int expected_gts)
+{
+	int max_gts = 0;
+	enum pci_bus_speed speed = PCI_SPEED_UNKNOWN;
+	enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
+	struct pci_dev *pdev;
+
+	/* determine whether to use the the parent device
+	 */
+	if (ixgbe_pcie_from_parent(&adapter->hw))
+		pdev = adapter->pdev->bus->parent->self;
+	else
+		pdev = adapter->pdev;
+
+	if (pcie_get_minimum_link(pdev, &speed, &width) ||
+	    speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN) {
+		e_dev_warn("Unable to determine PCI-Express slot throughput.\n");
+		return;
+	}
+
+	switch (speed) {
+	case PCIE_SPEED_2_5GT:
+		/* 8b/10b encoding reduces max throughput */
+		max_gts = 2 * width;
+		break;
+	case PCIE_SPEED_5_0GT:
+		/* 8b/10b encoding reduces max throughput */
+		max_gts = 4 * width;
+		break;
+	case PCIE_SPEED_8_0GT:
+		/* 128b/130b encoding has less impact on throughput */
+		max_gts = 8 * width;
+		break;
+	default:
+		e_dev_warn("Unable to determine PCI-Express throughput.\n");
+		return;
+	}
+
+	if (max_gts < expected_gts) {
+		e_dev_warn("PCI-Express bandwidth of %dGT/s available (PCI Express:%s:Width x%d)\n",
+			   max_gts,
+			   (speed == PCIE_SPEED_8_0GT ? "8.0GT/s" :
+			    speed == PCIE_SPEED_5_0GT ? "5.0GT/s" :
+			    speed == PCIE_SPEED_2_5GT ? "2.5GT/s" :
+			    "Unknown"),
+			   width);
+		e_dev_warn("This is not sufficient for optimal performance of this card.\n");
+		e_dev_warn("For optimal performance, at least %dGT/s of bandwidth is required.\n",
+			expected_gts);
+		e_dev_warn("A slot with more lanes and/or higher speed is suggested.\n");
+	}
+}
+
 static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
 {
 	if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
@@ -7250,6 +7323,41 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 };
 
 /**
+ * ixgbe_enumerate_functions - Get the number of ports this device has
+ * @adapter: adapter structure
+ *
+ * This function enumerates the phsyical functions co-located on a single slot,
+ * in order to determine how many ports a device has. This is most useful in
+ * determining the required GT/s of PCIe bandwidth necessary for optimal
+ * performance.
+ **/
+static inline int ixgbe_enumerate_functions(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct list_head *entry;
+	int physfns = 0;
+
+	/* Some cards can not use the generic count PCIe functions method, and
+	 * so must be hardcoded to the correct value.
+	 */
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82599_SFP_SF_QP:
+		physfns = 4;
+		break;
+	default:
+		list_for_each(entry, &adapter->pdev->bus_list) {
+			struct pci_dev *pdev =
+				list_entry(entry, struct pci_dev, bus_list);
+			/* don't count virtual functions */
+			if (!pdev->is_virtfn)
+				physfns++;
+		}
+	}
+
+	return physfns;
+}
+
+/**
  * ixgbe_wol_supported - Check whether device supports WoL
  * @hw: hw specific details
  * @device_id: the device ID
@@ -7331,7 +7439,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct ixgbe_hw *hw;
 	const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
 	static int cards_found;
-	int i, err, pci_using_dac;
+	int i, err, pci_using_dac, expected_gts;
 	unsigned int indices = MAX_TX_QUEUES;
 	u8 part_str[IXGBE_PBANUM_LENGTH];
 #ifdef IXGBE_FCOE
@@ -7620,7 +7728,7 @@ skip_sriov:
 
 	/* 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)
+	if (ixgbe_pcie_from_parent(hw))
 		ixgbe_get_parent_bus_info(adapter);
 
 	/* print bus type/speed/width info */
@@ -7646,12 +7754,20 @@ skip_sriov:
 		e_dev_info("MAC: %d, PHY: %d, PBA No: %s\n",
 			   hw->mac.type, hw->phy.type, part_str);
 
-	if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
-		e_dev_warn("PCI-Express bandwidth available for this card is "
-			   "not sufficient for optimal performance.\n");
-		e_dev_warn("For optimal performance a x8 PCI-Express slot "
-			   "is required.\n");
+	/* calculate the expected PCIe bandwidth required for optimal
+	 * performance. Note that some older parts will never have enough
+	 * bandwidth due to being older generation PCIe parts. We clamp these
+	 * parts to ensure no warning is displayed if it can't be fixed.
+	 */
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		expected_gts = min(ixgbe_enumerate_functions(adapter) * 10, 16);
+		break;
+	default:
+		expected_gts = ixgbe_enumerate_functions(adapter) * 10;
+		break;
 	}
+	ixgbe_check_minimum_link(adapter, expected_gts);
 
 	/* reset the hardware with the new settings */
 	err = hw->mac.ops.start_hw(hw);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 12/15] ixgbe: fix lockdep annotation issue for ptp's work item
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (10 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 12:52 ` [net-next 13/15] ixgbe: rename LL_EXTENDED_STATS to use queue instead of q Jeff Kirsher
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Jacob Keller, netdev, gospo, sassmann, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

This patch fixes a lockdep issue created due to ixgbe_ptp_stop always running
cancel_work_sync even if the work item had not been created properly with
INIT_WORK. This is caused because ixgbe_ptp_stop did not check to actually
ensure PTP was running first. The new implementation introduces a state in the
&adapter->state field which is used to indicate that PTP is running. (This
replaces the IXGBE_FLAG2_PTP_ENABLED field). This state will use the atomic
set_bit, test_bit, and test_and_clear_bit functions. ixgbe_ptp_stop will check
to ensure that PTP was enabled, (and if not, it will not attempt to do any
cleanup work from ixgbe_ptp_init). This resolves the lockdep annotation warning
found by Stephen Hemminger

Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Acked-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |  6 +++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  8 ++++----
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c  | 12 +++++++-----
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index d882278..6844f39 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -618,9 +618,8 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT        (u32)(1 << 7)
 #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP		(u32)(1 << 8)
 #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP		(u32)(1 << 9)
-#define IXGBE_FLAG2_PTP_ENABLED			(u32)(1 << 10)
-#define IXGBE_FLAG2_PTP_PPS_ENABLED		(u32)(1 << 11)
-#define IXGBE_FLAG2_BRIDGE_MODE_VEB		(u32)(1 << 12)
+#define IXGBE_FLAG2_PTP_PPS_ENABLED		(u32)(1 << 10)
+#define IXGBE_FLAG2_BRIDGE_MODE_VEB		(u32)(1 << 11)
 
 	/* Tx fast path data */
 	int num_tx_queues;
@@ -754,6 +753,7 @@ enum ixgbe_state_t {
 	__IXGBE_DOWN,
 	__IXGBE_SERVICE_SCHED,
 	__IXGBE_IN_SFP_INIT,
+	__IXGBE_PTP_RUNNING,
 };
 
 struct ixgbe_cb {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 5ec2b74..65c36f7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -4432,7 +4432,7 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
 	if (hw->mac.san_mac_rar_index)
 		hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0));
 
-	if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+	if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
 		ixgbe_ptp_reset(adapter);
 }
 
@@ -5761,7 +5761,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
 
 	adapter->last_rx_ptp_check = jiffies;
 
-	if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+	if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
 		ixgbe_ptp_start_cyclecounter(adapter);
 
 	e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
@@ -5807,7 +5807,7 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter)
 	if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
 		adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-	if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+	if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
 		ixgbe_ptp_start_cyclecounter(adapter);
 
 	e_info(drv, "NIC Link is Down\n");
@@ -6114,7 +6114,7 @@ static void ixgbe_service_task(struct work_struct *work)
 	ixgbe_fdir_reinit_subtask(adapter);
 	ixgbe_check_hang_subtask(adapter);
 
-	if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) {
+	if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) {
 		ixgbe_ptp_overflow_check(adapter);
 		ixgbe_ptp_rx_hang(adapter);
 	}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 331987d..5184e2a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -885,8 +885,8 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
 
 	ixgbe_ptp_reset(adapter);
 
-	/* set the flag that PTP has been enabled */
-	adapter->flags2 |= IXGBE_FLAG2_PTP_ENABLED;
+	/* enter the IXGBE_PTP_RUNNING state */
+	set_bit(__IXGBE_PTP_RUNNING, &adapter->state);
 
 	return;
 }
@@ -899,10 +899,12 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
  */
 void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
 {
-	/* stop the overflow check task */
-	adapter->flags2 &= ~(IXGBE_FLAG2_PTP_ENABLED |
-			     IXGBE_FLAG2_PTP_PPS_ENABLED);
+	/* Leave the IXGBE_PTP_RUNNING state. */
+	if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state))
+		return;
 
+	/* stop the PPS signal */
+	adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
 	ixgbe_ptp_setup_sdp(adapter);
 
 	cancel_work_sync(&adapter->ptp_tx_work);
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 13/15] ixgbe: rename LL_EXTENDED_STATS to use queue instead of q
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (11 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 12/15] ixgbe: fix lockdep annotation issue for ptp's work item Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 12:52 ` [net-next 14/15] ixgbe: clear semaphore bits on timeouts Jeff Kirsher
  2013-07-29 12:52 ` [net-next 15/15] ixgbe: add support for quad-port x520 adapter Jeff Kirsher
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Jacob Keller, netdev, gospo, sassmann, Jeff Kirsher

From: Jacob Keller <jacob.e.keller@intel.com>

This patch renames the stats introduced by the busy poll feature so that they
are more inline with the current statistics naming schemes.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index da1ea28..50c1e9b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1141,11 +1141,11 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
 			sprintf(p, "tx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
 #ifdef LL_EXTENDED_STATS
-			sprintf(p, "tx_q_%u_napi_yield", i);
+			sprintf(p, "tx_queue_%u_ll_napi_yield", i);
 			p += ETH_GSTRING_LEN;
-			sprintf(p, "tx_q_%u_misses", i);
+			sprintf(p, "tx_queue_%u_ll_misses", i);
 			p += ETH_GSTRING_LEN;
-			sprintf(p, "tx_q_%u_cleaned", i);
+			sprintf(p, "tx_queue_%u_ll_cleaned", i);
 			p += ETH_GSTRING_LEN;
 #endif /* LL_EXTENDED_STATS */
 		}
@@ -1155,11 +1155,11 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
 			sprintf(p, "rx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
 #ifdef LL_EXTENDED_STATS
-			sprintf(p, "rx_q_%u_ll_poll_yield", i);
+			sprintf(p, "rx_queue_%u_ll_poll_yield", i);
 			p += ETH_GSTRING_LEN;
-			sprintf(p, "rx_q_%u_misses", i);
+			sprintf(p, "rx_queue_%u_ll_misses", i);
 			p += ETH_GSTRING_LEN;
-			sprintf(p, "rx_q_%u_cleaned", i);
+			sprintf(p, "rx_queue_%u_ll_cleaned", i);
 			p += ETH_GSTRING_LEN;
 #endif /* LL_EXTENDED_STATS */
 		}
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 14/15] ixgbe: clear semaphore bits on timeouts
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (12 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 13/15] ixgbe: rename LL_EXTENDED_STATS to use queue instead of q Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  2013-07-29 12:52 ` [net-next 15/15] ixgbe: add support for quad-port x520 adapter Jeff Kirsher
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher

From: Emil Tantilov <emil.s.tantilov@intel.com>

This patch changes the error code path in ixgbe_acquire_swfw_sync() to deal
with cases where acquiring SW semaphore times out.

In cases where the SW/FW semaphore bits were set (i.e. due to a crash) the
driver will hang on load. With this patch the driver will clear
the stuck bits if the semaphore was not acquired in the allotted time.

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 45 ++++++++++++-------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 6e5d4bc..5f05f8d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2506,42 +2506,39 @@ out:
  **/
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
 {
-	u32 gssr;
+	u32 gssr = 0;
 	u32 swmask = mask;
 	u32 fwmask = mask << 5;
-	s32 timeout = 200;
+	u32 timeout = 200;
+	u32 i;
 
-	while (timeout) {
+	for (i = 0; i < timeout; i++) {
 		/*
-		 * SW EEPROM semaphore bit is used for access to all
-		 * SW_FW_SYNC/GSSR bits (not just EEPROM)
+		 * SW NVM semaphore bit is used for access to all
+		 * SW_FW_SYNC bits (not just NVM)
 		 */
 		if (ixgbe_get_eeprom_semaphore(hw))
 			return IXGBE_ERR_SWFW_SYNC;
 
 		gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
-		if (!(gssr & (fwmask | swmask)))
-			break;
-
-		/*
-		 * Firmware currently using resource (fwmask) or other software
-		 * thread currently using resource (swmask)
-		 */
-		ixgbe_release_eeprom_semaphore(hw);
-		usleep_range(5000, 10000);
-		timeout--;
-	}
-
-	if (!timeout) {
-		hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
-		return IXGBE_ERR_SWFW_SYNC;
+		if (!(gssr & (fwmask | swmask))) {
+			gssr |= swmask;
+			IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+			ixgbe_release_eeprom_semaphore(hw);
+			return 0;
+		} else {
+			/* Resource is currently in use by FW or SW */
+			ixgbe_release_eeprom_semaphore(hw);
+			usleep_range(5000, 10000);
+		}
 	}
 
-	gssr |= swmask;
-	IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
+	/* If time expired clear the bits holding the lock and retry */
+	if (gssr & (fwmask | swmask))
+		ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
 
-	ixgbe_release_eeprom_semaphore(hw);
-	return 0;
+	usleep_range(5000, 10000);
+	return IXGBE_ERR_SWFW_SYNC;
 }
 
 /**
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [net-next 15/15] ixgbe: add support for quad-port x520 adapter
  2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
                   ` (13 preceding siblings ...)
  2013-07-29 12:52 ` [net-next 14/15] ixgbe: clear semaphore bits on timeouts Jeff Kirsher
@ 2013-07-29 12:52 ` Jeff Kirsher
  14 siblings, 0 replies; 27+ messages in thread
From: Jeff Kirsher @ 2013-07-29 12:52 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, sassmann, Jeff Kirsher

From: Don Skidmore <donald.c.skidmore@intel.com>

This is a x520 based quad-port (4x10Gbps) NIC with a single QSFP+
connector.  Changes were required to our identify functions due to
different eeprom address which is also included here.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c |   2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | 147 +++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   3 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c   | 178 ++++++++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h   |  36 +++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |   9 ++
 6 files changed, 358 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index d011d5c..a26f3fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1331,7 +1331,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
 
 static struct ixgbe_phy_operations phy_ops_82598 = {
 	.identify		= &ixgbe_identify_phy_generic,
-	.identify_sfp		= &ixgbe_identify_sfp_module_generic,
+	.identify_sfp		= &ixgbe_identify_module_generic,
 	.init			= &ixgbe_init_phy_ops_82598,
 	.reset			= &ixgbe_reset_phy_generic,
 	.read_reg		= &ixgbe_read_phy_reg_generic,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index b92765b..555d7c7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -58,6 +58,10 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                          ixgbe_link_speed speed,
                                          bool autoneg_wait_to_complete);
 static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
+				     u8 dev_addr, u8 *data);
+static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
+				      u8 dev_addr, u8 data);
 
 static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
 {
@@ -219,6 +223,25 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
 	struct ixgbe_mac_info *mac = &hw->mac;
 	struct ixgbe_phy_info *phy = &hw->phy;
 	s32 ret_val = 0;
+	u32 esdp;
+
+	if (hw->device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) {
+		/* Store flag indicating I2C bus access control unit. */
+		hw->phy.qsfp_shared_i2c_bus = true;
+
+		/* Initialize access to QSFP+ I2C bus */
+		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+		esdp |= IXGBE_ESDP_SDP0_DIR;
+		esdp &= ~IXGBE_ESDP_SDP1_DIR;
+		esdp &= ~IXGBE_ESDP_SDP0;
+		esdp &= ~IXGBE_ESDP_SDP0_NATIVE;
+		esdp &= ~IXGBE_ESDP_SDP1_NATIVE;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+		IXGBE_WRITE_FLUSH(hw);
+
+		phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_82599;
+		phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_82599;
+	}
 
 	/* Identify the PHY or SFP module */
 	ret_val = phy->ops.identify(hw);
@@ -397,6 +420,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
 	case IXGBE_DEV_ID_82599_LS:
 		media_type = ixgbe_media_type_fiber_lco;
 		break;
+	case IXGBE_DEV_ID_82599_QSFP_SF_QP:
+		media_type = ixgbe_media_type_fiber_qsfp;
+		break;
 	default:
 		media_type = ixgbe_media_type_unknown;
 		break;
@@ -1942,7 +1968,7 @@ static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
 		if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
 			goto out;
 		else
-			status = ixgbe_identify_sfp_module_generic(hw);
+			status = ixgbe_identify_module_generic(hw);
 	}
 
 	/* Set PHY type none if no PHY detected */
@@ -2048,10 +2074,12 @@ sfp_check:
 	switch (hw->phy.type) {
 	case ixgbe_phy_sfp_passive_tyco:
 	case ixgbe_phy_sfp_passive_unknown:
+	case ixgbe_phy_qsfp_passive_unknown:
 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
 		break;
 	case ixgbe_phy_sfp_ftl_active:
 	case ixgbe_phy_sfp_active_unknown:
+	case ixgbe_phy_qsfp_active_unknown:
 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
 		break;
 	case ixgbe_phy_sfp_avago:
@@ -2069,6 +2097,15 @@ sfp_check:
 		else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
 		break;
+	case ixgbe_phy_qsfp_intel:
+	case ixgbe_phy_qsfp_unknown:
+		hw->phy.ops.read_i2c_eeprom(hw,
+			IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g);
+		if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+		break;
 	default:
 		break;
 	}
@@ -2306,6 +2343,112 @@ reset_pipeline_out:
 	return ret_val;
 }
 
+/**
+ *  ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to read
+ *  @data: value read
+ *
+ *  Performs byte read operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ **/
+static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
+				     u8 dev_addr, u8 *data)
+{
+	u32 esdp;
+	s32 status;
+	s32 timeout = 200;
+
+	if (hw->phy.qsfp_shared_i2c_bus == true) {
+		/* Acquire I2C bus ownership. */
+		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+		esdp |= IXGBE_ESDP_SDP0;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+		IXGBE_WRITE_FLUSH(hw);
+
+		while (timeout) {
+			esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+			if (esdp & IXGBE_ESDP_SDP1)
+				break;
+
+			usleep_range(5000, 10000);
+			timeout--;
+		}
+
+		if (!timeout) {
+			hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n");
+			status = IXGBE_ERR_I2C;
+			goto release_i2c_access;
+		}
+	}
+
+	status = ixgbe_read_i2c_byte_generic(hw, byte_offset, dev_addr, data);
+
+release_i2c_access:
+	if (hw->phy.qsfp_shared_i2c_bus == true) {
+		/* Release I2C bus ownership. */
+		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+		esdp &= ~IXGBE_ESDP_SDP0;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to write
+ *  @data: value to write
+ *
+ *  Performs byte write operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ **/
+static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
+				      u8 dev_addr, u8 data)
+{
+	u32 esdp;
+	s32 status;
+	s32 timeout = 200;
+
+	if (hw->phy.qsfp_shared_i2c_bus == true) {
+		/* Acquire I2C bus ownership. */
+		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+		esdp |= IXGBE_ESDP_SDP0;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+		IXGBE_WRITE_FLUSH(hw);
+
+		while (timeout) {
+			esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+			if (esdp & IXGBE_ESDP_SDP1)
+				break;
+
+			usleep_range(5000, 10000);
+			timeout--;
+		}
+
+		if (!timeout) {
+			hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n");
+			status = IXGBE_ERR_I2C;
+			goto release_i2c_access;
+		}
+	}
+
+	status = ixgbe_write_i2c_byte_generic(hw, byte_offset, dev_addr, data);
+
+release_i2c_access:
+	if (hw->phy.qsfp_shared_i2c_bus == true) {
+		/* Release I2C bus ownership. */
+		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+		esdp &= ~IXGBE_ESDP_SDP0;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+
+	return status;
+}
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
 	.init_hw                = &ixgbe_init_hw_generic,
 	.reset_hw               = &ixgbe_reset_hw_82599,
@@ -2370,7 +2513,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
 
 static struct ixgbe_phy_operations phy_ops_82599 = {
 	.identify		= &ixgbe_identify_phy_82599,
-	.identify_sfp		= &ixgbe_identify_sfp_module_generic,
+	.identify_sfp		= &ixgbe_identify_module_generic,
 	.init			= &ixgbe_init_phy_ops_82599,
 	.reset			= &ixgbe_reset_phy_generic,
 	.read_reg		= &ixgbe_read_phy_reg_generic,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 65c36f7..e606aae 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -109,6 +109,7 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), board_X540 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_QSFP_SF_QP), board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), board_X540 },
@@ -208,6 +209,7 @@ static inline bool ixgbe_pcie_from_parent(struct ixgbe_hw *hw)
 {
 	switch (hw->device_id) {
 	case IXGBE_DEV_ID_82599_SFP_SF_QP:
+	case IXGBE_DEV_ID_82599_QSFP_SF_QP:
 		return true;
 	default:
 		return false;
@@ -7342,6 +7344,7 @@ static inline int ixgbe_enumerate_functions(struct ixgbe_adapter *adapter)
 	 */
 	switch (hw->device_id) {
 	case IXGBE_DEV_ID_82599_SFP_SF_QP:
+	case IXGBE_DEV_ID_82599_QSFP_SF_QP:
 		physfns = 4;
 		break;
 	default:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index 71f554a..369eef5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -841,9 +841,35 @@ out:
 }
 
 /**
- *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
+ *  ixgbe_identify_module_generic - Identifies module type
  *  @hw: pointer to hardware structure
  *
+ *  Determines HW type and calls appropriate function.
+ **/
+s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
+{
+	s32 status = IXGBE_ERR_SFP_NOT_PRESENT;
+
+	switch (hw->mac.ops.get_media_type(hw)) {
+	case ixgbe_media_type_fiber:
+		status = ixgbe_identify_sfp_module_generic(hw);
+		break;
+	case ixgbe_media_type_fiber_qsfp:
+		status = ixgbe_identify_qsfp_module_generic(hw);
+		break;
+	default:
+		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+		status = IXGBE_ERR_SFP_NOT_PRESENT;
+		break;
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_identify_sfp_module_generic - Identifies SFP modules
+ *  @hw: pointer to hardware structure
+*
  *  Searches for and identifies the SFP module and assigns appropriate PHY type.
  **/
 s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
@@ -1122,6 +1148,156 @@ err_read_i2c_eeprom:
 }
 
 /**
+ * ixgbe_identify_qsfp_module_generic - Identifies QSFP modules
+ * @hw: pointer to hardware structure
+ *
+ * Searches for and identifies the QSFP module and assigns appropriate PHY type
+ **/
+s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
+{
+	struct ixgbe_adapter *adapter = hw->back;
+	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+	u32 vendor_oui = 0;
+	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
+	u8 identifier = 0;
+	u8 comp_codes_1g = 0;
+	u8 comp_codes_10g = 0;
+	u8 oui_bytes[3] = {0, 0, 0};
+	u16 enforce_sfp = 0;
+
+	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
+		hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+		status = IXGBE_ERR_SFP_NOT_PRESENT;
+		goto out;
+	}
+
+	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
+					     &identifier);
+
+	if (status != 0)
+		goto err_read_i2c_eeprom;
+
+	if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
+		hw->phy.type = ixgbe_phy_sfp_unsupported;
+		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+		goto out;
+	}
+
+	hw->phy.id = identifier;
+
+	/* LAN ID is needed for sfp_type determination */
+	hw->mac.ops.set_lan_id(hw);
+
+	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
+					     &comp_codes_10g);
+
+	if (status != 0)
+		goto err_read_i2c_eeprom;
+
+	if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
+		hw->phy.type = ixgbe_phy_qsfp_passive_unknown;
+		if (hw->bus.lan_id == 0)
+			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0;
+		else
+			hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1;
+	} else if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE) {
+		hw->phy.type = ixgbe_phy_qsfp_active_unknown;
+		if (hw->bus.lan_id == 0)
+			hw->phy.sfp_type = ixgbe_sfp_type_da_act_lmt_core0;
+		else
+			hw->phy.sfp_type = ixgbe_sfp_type_da_act_lmt_core1;
+	} else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
+				     IXGBE_SFF_10GBASELR_CAPABLE)) {
+		if (hw->bus.lan_id == 0)
+			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0;
+		else
+			hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1;
+	} else {
+		/* unsupported module type */
+		hw->phy.type = ixgbe_phy_sfp_unsupported;
+		status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+		goto out;
+	}
+
+	if (hw->phy.sfp_type != stored_sfp_type)
+		hw->phy.sfp_setup_needed = true;
+
+	/* Determine if the QSFP+ PHY is dual speed or not. */
+	hw->phy.multispeed_fiber = false;
+	if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+	     (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+	    ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+	     (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+		hw->phy.multispeed_fiber = true;
+
+	/* Determine PHY vendor for optical modules */
+	if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE |
+			      IXGBE_SFF_10GBASELR_CAPABLE)) {
+		status = hw->phy.ops.read_i2c_eeprom(hw,
+					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
+					&oui_bytes[0]);
+
+		if (status != 0)
+			goto err_read_i2c_eeprom;
+
+		status = hw->phy.ops.read_i2c_eeprom(hw,
+					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
+					&oui_bytes[1]);
+
+		if (status != 0)
+			goto err_read_i2c_eeprom;
+
+		status = hw->phy.ops.read_i2c_eeprom(hw,
+					IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
+					&oui_bytes[2]);
+
+		if (status != 0)
+			goto err_read_i2c_eeprom;
+
+		vendor_oui =
+			((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
+			 (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
+			 (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
+
+		if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL)
+			hw->phy.type = ixgbe_phy_qsfp_intel;
+		else
+			hw->phy.type = ixgbe_phy_qsfp_unknown;
+
+		hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
+			/* Make sure we're a supported PHY type */
+			if (hw->phy.type == ixgbe_phy_qsfp_intel) {
+				status = 0;
+			} else {
+				if (hw->allow_unsupported_sfp == true) {
+					e_warn(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
+					status = 0;
+				} else {
+					hw_dbg(hw,
+					       "QSFP module not supported\n");
+					hw->phy.type =
+						ixgbe_phy_sfp_unsupported;
+					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+				}
+			}
+		} else {
+			status = 0;
+		}
+	}
+
+out:
+	return status;
+
+err_read_i2c_eeprom:
+	hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+	hw->phy.id = 0;
+	hw->phy.type = ixgbe_phy_unknown;
+
+	return IXGBE_ERR_SFP_NOT_PRESENT;
+}
+
+/**
  *  ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
  *  @hw: pointer to hardware structure
  *  @list_offset: offset to the SFP ID list
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index fe64e723..9ec13b3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -33,19 +33,25 @@
 #define IXGBE_I2C_EEPROM_DEV_ADDR2   0xA2
 
 /* EEPROM byte offsets */
-#define IXGBE_SFF_IDENTIFIER         0x0
-#define IXGBE_SFF_IDENTIFIER_SFP     0x3
-#define IXGBE_SFF_VENDOR_OUI_BYTE0   0x25
-#define IXGBE_SFF_VENDOR_OUI_BYTE1   0x26
-#define IXGBE_SFF_VENDOR_OUI_BYTE2   0x27
-#define IXGBE_SFF_1GBE_COMP_CODES    0x6
-#define IXGBE_SFF_10GBE_COMP_CODES   0x3
-#define IXGBE_SFF_CABLE_TECHNOLOGY   0x8
-#define IXGBE_SFF_CABLE_SPEC_COMP    0x3C
-#define IXGBE_SFF_SFF_8472_SWAP      0x5C
-#define IXGBE_SFF_SFF_8472_COMP      0x5E
-#define IXGBE_SFF_SFF_8472_OSCB         0x6E
-#define IXGBE_SFF_SFF_8472_ESCB         0x76
+#define IXGBE_SFF_IDENTIFIER		0x0
+#define IXGBE_SFF_IDENTIFIER_SFP	0x3
+#define IXGBE_SFF_VENDOR_OUI_BYTE0	0x25
+#define IXGBE_SFF_VENDOR_OUI_BYTE1	0x26
+#define IXGBE_SFF_VENDOR_OUI_BYTE2	0x27
+#define IXGBE_SFF_1GBE_COMP_CODES	0x6
+#define IXGBE_SFF_10GBE_COMP_CODES	0x3
+#define IXGBE_SFF_CABLE_TECHNOLOGY	0x8
+#define IXGBE_SFF_CABLE_SPEC_COMP	0x3C
+#define IXGBE_SFF_SFF_8472_SWAP		0x5C
+#define IXGBE_SFF_SFF_8472_COMP		0x5E
+#define IXGBE_SFF_SFF_8472_OSCB		0x6E
+#define IXGBE_SFF_SFF_8472_ESCB		0x76
+#define IXGBE_SFF_IDENTIFIER_QSFP_PLUS	0xD
+#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0	0xA5
+#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1	0xA6
+#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2	0xA7
+#define IXGBE_SFF_QSFP_10GBE_COMP	0x83
+#define IXGBE_SFF_QSFP_1GBE_COMP	0x86
 
 /* Bitmasks */
 #define IXGBE_SFF_DA_PASSIVE_CABLE           0x4
@@ -60,6 +66,8 @@
 #define IXGBE_SFF_SOFT_RS_SELECT_10G    0x8
 #define IXGBE_SFF_SOFT_RS_SELECT_1G     0x0
 #define IXGBE_SFF_ADDRESSING_MODE	     0x4
+#define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE       0x1
+#define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE      0x8
 #define IXGBE_I2C_EEPROM_READ_MASK           0x100
 #define IXGBE_I2C_EEPROM_STATUS_MASK         0x3
 #define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
@@ -130,7 +138,9 @@ s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
                                            u16 *firmware_version);
 
 s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
+s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
+s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
                                         u16 *list_offset,
                                         u16 *data_offset);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 4c91ea6..161ff18 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -69,6 +69,7 @@
 #define IXGBE_DEV_ID_82599_LS            0x154F
 #define IXGBE_DEV_ID_X540T               0x1528
 #define IXGBE_DEV_ID_82599_SFP_SF_QP     0x154A
+#define IXGBE_DEV_ID_82599_QSFP_SF_QP    0x1558
 #define IXGBE_DEV_ID_X540T1              0x1560
 
 /* VF Device IDs */
@@ -1520,9 +1521,11 @@ enum {
 #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
 #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
 #define IXGBE_ESDP_SDP0_DIR     0x00000100 /* SDP0 IO direction */
+#define IXGBE_ESDP_SDP1_DIR     0x00000200 /* SDP1 IO direction */
 #define IXGBE_ESDP_SDP4_DIR     0x00000004 /* SDP4 IO direction */
 #define IXGBE_ESDP_SDP5_DIR     0x00002000 /* SDP5 IO direction */
 #define IXGBE_ESDP_SDP0_NATIVE  0x00010000 /* SDP0 Native Function */
+#define IXGBE_ESDP_SDP1_NATIVE  0x00020000 /* SDP1 IO mode */
 
 /* LEDCTL Bit Masks */
 #define IXGBE_LED_IVRT_BASE      0x00000040
@@ -2582,6 +2585,10 @@ enum ixgbe_phy_type {
 	ixgbe_phy_sfp_ftl_active,
 	ixgbe_phy_sfp_unknown,
 	ixgbe_phy_sfp_intel,
+	ixgbe_phy_qsfp_passive_unknown,
+	ixgbe_phy_qsfp_active_unknown,
+	ixgbe_phy_qsfp_intel,
+	ixgbe_phy_qsfp_unknown,
 	ixgbe_phy_sfp_unsupported,
 	ixgbe_phy_generic
 };
@@ -2623,6 +2630,7 @@ enum ixgbe_media_type {
 	ixgbe_media_type_unknown = 0,
 	ixgbe_media_type_fiber,
 	ixgbe_media_type_fiber_fixed,
+	ixgbe_media_type_fiber_qsfp,
 	ixgbe_media_type_fiber_lco,
 	ixgbe_media_type_copper,
 	ixgbe_media_type_backplane,
@@ -2956,6 +2964,7 @@ struct ixgbe_phy_info {
 	bool                            smart_speed_active;
 	bool                            multispeed_fiber;
 	bool                            reset_if_overtemp;
+	bool                            qsfp_shared_i2c_bus;
 };
 
 #include "ixgbe_mbx.h"
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [net-next 09/15] pci: move enum pcie_link_width into pci.h
  2013-07-29 12:52 ` [net-next 09/15] pci: move enum pcie_link_width into pci.h Jeff Kirsher
@ 2013-07-29 18:39   ` Bjorn Helgaas
  0 siblings, 0 replies; 27+ messages in thread
From: Bjorn Helgaas @ 2013-07-29 18:39 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: David Miller, Jacob Keller, netdev, gospo, sassmann, linux-pci

On Mon, Jul 29, 2013 at 6:52 AM, Jeff Kirsher
<jeffrey.t.kirsher@intel.com> wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
>
> pcie_link_width is the enum used to define the link width values for a pcie
> device. This enum should not be contained solely in pci_hotplug.h, and this
> patch moves it next to pci_bus_speed in pci.h
>
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  include/linux/pci.h         | 13 +++++++++++++
>  include/linux/pci_hotplug.h | 13 -------------
>  2 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 95ff993..fc2d1fb 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -186,6 +186,19 @@ enum pci_bus_flags {
>         PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
>  };
>
> +/* These values come from the PCI Express Spec */
> +enum pcie_link_width {
> +       PCIE_LNK_WIDTH_RESRV    = 0x00,
> +       PCIE_LNK_X1             = 0x01,
> +       PCIE_LNK_X2             = 0x02,
> +       PCIE_LNK_X4             = 0x04,
> +       PCIE_LNK_X8             = 0x08,
> +       PCIE_LNK_X12            = 0x0C,
> +       PCIE_LNK_X16            = 0x10,
> +       PCIE_LNK_X32            = 0x20,
> +       PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
> +};
> +
>  /* Based on the PCI Hotplug Spec, but some values are made up by us */
>  enum pci_bus_speed {
>         PCI_SPEED_33MHz                 = 0x00,
> diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
> index 8db71dc..64e61e0 100644
> --- a/include/linux/pci_hotplug.h
> +++ b/include/linux/pci_hotplug.h
> @@ -28,19 +28,6 @@
>  #ifndef _PCI_HOTPLUG_H
>  #define _PCI_HOTPLUG_H
>
> -/* These values come from the PCI Express Spec */
> -enum pcie_link_width {
> -       PCIE_LNK_WIDTH_RESRV    = 0x00,
> -       PCIE_LNK_X1             = 0x01,
> -       PCIE_LNK_X2             = 0x02,
> -       PCIE_LNK_X4             = 0x04,
> -       PCIE_LNK_X8             = 0x08,
> -       PCIE_LNK_X12            = 0x0C,
> -       PCIE_LNK_X16            = 0x10,
> -       PCIE_LNK_X32            = 0x20,
> -       PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
> -};
> -
>  /**
>   * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
>   * @owner: The module owner of this structure
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays
  2013-07-29 12:52 ` [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays Jeff Kirsher
@ 2013-07-29 18:44   ` Bjorn Helgaas
  2013-07-29 21:03     ` Keller, Jacob E
  0 siblings, 1 reply; 27+ messages in thread
From: Bjorn Helgaas @ 2013-07-29 18:44 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: David Miller, Jacob Keller, netdev, gospo, sassmann, linux-pci

On Mon, Jul 29, 2013 at 6:52 AM, Jeff Kirsher
<jeffrey.t.kirsher@intel.com> wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
>
> pcie_link_speed and pcix_bus_speed are arrays used by probe.c to correctly
> convert lnksta register values into the pci_bus_speed enum. These static arrays
> are useful outside probe for this purpose. This patch makes these defines into
> const arrays and exposes them with an extern header in linux/include/pci.h
>
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  drivers/pci/probe.c | 4 ++--
>  include/linux/pci.h | 3 +++
>  2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 46ada5c..496c5b0 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -513,7 +513,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>         return bridge;
>  }
>
> -static unsigned char pcix_bus_speed[] = {
> +const unsigned char pcix_bus_speed[] = {
>         PCI_SPEED_UNKNOWN,              /* 0 */
>         PCI_SPEED_66MHz_PCIX,           /* 1 */
>         PCI_SPEED_100MHz_PCIX,          /* 2 */
> @@ -532,7 +532,7 @@ static unsigned char pcix_bus_speed[] = {
>         PCI_SPEED_133MHz_PCIX_533       /* F */
>  };
>
> -static unsigned char pcie_link_speed[] = {
> +const unsigned char pcie_link_speed[] = {
>         PCI_SPEED_UNKNOWN,              /* 0 */
>         PCIE_SPEED_2_5GT,               /* 1 */
>         PCIE_SPEED_5_0GT,               /* 2 */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 0fd1f15..95ff993 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -120,6 +120,9 @@ typedef int __bitwise pci_power_t;
>  /* Remember to update this when the list above changes! */
>  extern const char *pci_power_names[];
>
> +extern const unsigned char pcix_bus_speed[];
> +extern const unsigned char pcie_link_speed[];

As far as I can tell, you didn't actually add anything that uses
pcix_bus_speed[].

You added a pcie_link_speed[] use only in drivers/pci/pci.c; maybe
this extern declaration could go in drivers/pci/pci.h to limit its
visibility?

If you update this patch, note that we conventionally capitalize "PCI:
Expose ..." in the changelog summary, e.g., "git log --oneline
drivers/pci".

>  static inline const char *pci_power_name(pci_power_t state)
>  {
>         return pci_power_names[1 + (int) state];
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 10/15] pci: Add function to obtain minimum link width and speed
  2013-07-29 12:52 ` [net-next 10/15] pci: Add function to obtain minimum link width and speed Jeff Kirsher
@ 2013-07-29 18:45   ` Bjorn Helgaas
  0 siblings, 0 replies; 27+ messages in thread
From: Bjorn Helgaas @ 2013-07-29 18:45 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: David Miller, Jacob Keller, netdev, gospo, sassmann, linux-pci

On Mon, Jul 29, 2013 at 6:52 AM, Jeff Kirsher
<jeffrey.t.kirsher@intel.com> wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
>
> A PCI Express device can potentially report a link width and speed which it will
> not properly fulfill due to being plugged into a slower link higher in the
> chain. This function walks up the PCI bus chain and calculates the minimum link
> width and speed of this entire chain. This can be useful to enable a device to
> determine if it has enough bandwidth for optimum functionality.
>
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/pci.c   | 43 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pci.h |  2 ++
>  2 files changed, 45 insertions(+)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index e37fea6..c71e78c 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3579,6 +3579,49 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
>  }
>
>  /**
> + * pcie_get_minimum_link - determine minimum link settings of a PCI device
> + * @dev: PCI device to query
> + * @speed: storage for minimum speed
> + * @width: storage for minimum width
> + *
> + * This function will walk up the PCI device chain and determine the minimum
> + * link width and speed of the device.
> + */
> +int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> +                         enum pcie_link_width *width)
> +{
> +       int ret;
> +
> +       *speed = PCI_SPEED_UNKNOWN;
> +       *width = PCIE_LNK_WIDTH_UNKNOWN;
> +
> +       while (dev) {
> +               u16 lnksta;
> +               enum pci_bus_speed next_speed;
> +               enum pcie_link_width next_width;
> +
> +               ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
> +               if (ret)
> +                       return ret;
> +
> +               next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
> +               next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
> +                       PCI_EXP_LNKSTA_NLW_SHIFT;
> +
> +               if (next_speed < *speed)
> +                       *speed = next_speed;
> +
> +               if (next_width < *width)
> +                       *width = next_width;
> +
> +               dev = dev->bus->self;
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(pcie_get_minimum_link);
> +
> +/**
>   * pci_select_bars - Make BAR mask from the type of resource
>   * @dev: the PCI device for which BAR mask is made
>   * @flags: resource type mask to be selected
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index fc2d1fb..38994de 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -937,6 +937,8 @@ int pcie_get_readrq(struct pci_dev *dev);
>  int pcie_set_readrq(struct pci_dev *dev, int rq);
>  int pcie_get_mps(struct pci_dev *dev);
>  int pcie_set_mps(struct pci_dev *dev, int mps);
> +int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> +                         enum pcie_link_width *width);
>  int __pci_reset_function(struct pci_dev *dev);
>  int __pci_reset_function_locked(struct pci_dev *dev);
>  int pci_reset_function(struct pci_dev *dev);
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays
  2013-07-29 18:44   ` Bjorn Helgaas
@ 2013-07-29 21:03     ` Keller, Jacob E
  2013-07-29 21:19       ` Bjorn Helgaas
  0 siblings, 1 reply; 27+ messages in thread
From: Keller, Jacob E @ 2013-07-29 21:03 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Kirsher, Jeffrey T, David Miller, netdev, gospo, sassmann, linux-pci

On Mon, 2013-07-29 at 12:44 -0600, Bjorn Helgaas wrote:
> On Mon, Jul 29, 2013 at 6:52 AM, Jeff Kirsher
> <jeffrey.t.kirsher@intel.com> wrote:
> > From: Jacob Keller <jacob.e.keller@intel.com>
> >
> > pcie_link_speed and pcix_bus_speed are arrays used by probe.c to correctly
> > convert lnksta register values into the pci_bus_speed enum. These static arrays
> > are useful outside probe for this purpose. This patch makes these defines into
> > const arrays and exposes them with an extern header in linux/include/pci.h
> >
> > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> > Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> >  drivers/pci/probe.c | 4 ++--
> >  include/linux/pci.h | 3 +++
> >  2 files changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 46ada5c..496c5b0 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -513,7 +513,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> >         return bridge;
> >  }
> >
> > -static unsigned char pcix_bus_speed[] = {
> > +const unsigned char pcix_bus_speed[] = {
> >         PCI_SPEED_UNKNOWN,              /* 0 */
> >         PCI_SPEED_66MHz_PCIX,           /* 1 */
> >         PCI_SPEED_100MHz_PCIX,          /* 2 */
> > @@ -532,7 +532,7 @@ static unsigned char pcix_bus_speed[] = {
> >         PCI_SPEED_133MHz_PCIX_533       /* F */
> >  };
> >
> > -static unsigned char pcie_link_speed[] = {
> > +const unsigned char pcie_link_speed[] = {
> >         PCI_SPEED_UNKNOWN,              /* 0 */
> >         PCIE_SPEED_2_5GT,               /* 1 */
> >         PCIE_SPEED_5_0GT,               /* 2 */
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index 0fd1f15..95ff993 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -120,6 +120,9 @@ typedef int __bitwise pci_power_t;
> >  /* Remember to update this when the list above changes! */
> >  extern const char *pci_power_names[];
> >
> > +extern const unsigned char pcix_bus_speed[];
> > +extern const unsigned char pcie_link_speed[];
> 
> As far as I can tell, you didn't actually add anything that uses
> pcix_bus_speed[].
> 

I mostly added this for consistency...

> You added a pcie_link_speed[] use only in drivers/pci/pci.c; maybe
> this extern declaration could go in drivers/pci/pci.h to limit its
> visibility?

Pretty sure I use the pcie_link_speed in the ixgbe driver by including
the linux/pci.h header...  Check patch 11/15 of this series where I
actually use the values, so it would need to be in the linux/pci.h
header.

> 
> If you update this patch, note that we conventionally capitalize "PCI:
> Expose ..." in the changelog summary, e.g., "git log --oneline
> drivers/pci".

Oh. good to know, I will keep that in mind for future.
> 
> >  static inline const char *pci_power_name(pci_power_t state)
> >  {
> >         return pci_power_names[1 + (int) state];
> > --
> > 1.7.11.7
> >

Thanks,
Jake

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays
  2013-07-29 21:03     ` Keller, Jacob E
@ 2013-07-29 21:19       ` Bjorn Helgaas
  0 siblings, 0 replies; 27+ messages in thread
From: Bjorn Helgaas @ 2013-07-29 21:19 UTC (permalink / raw)
  To: Keller, Jacob E
  Cc: Kirsher, Jeffrey T, David Miller, netdev, gospo, sassmann, linux-pci

On Mon, Jul 29, 2013 at 3:03 PM, Keller, Jacob E
<jacob.e.keller@intel.com> wrote:
> On Mon, 2013-07-29 at 12:44 -0600, Bjorn Helgaas wrote:
>> On Mon, Jul 29, 2013 at 6:52 AM, Jeff Kirsher
>> <jeffrey.t.kirsher@intel.com> wrote:
>> > From: Jacob Keller <jacob.e.keller@intel.com>
>> >
>> > pcie_link_speed and pcix_bus_speed are arrays used by probe.c to correctly
>> > convert lnksta register values into the pci_bus_speed enum. These static arrays
>> > are useful outside probe for this purpose. This patch makes these defines into
>> > const arrays and exposes them with an extern header in linux/include/pci.h
>> >
>> > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> > Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
>> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>> > ---
>> >  drivers/pci/probe.c | 4 ++--
>> >  include/linux/pci.h | 3 +++
>> >  2 files changed, 5 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> > index 46ada5c..496c5b0 100644
>> > --- a/drivers/pci/probe.c
>> > +++ b/drivers/pci/probe.c
>> > @@ -513,7 +513,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> >         return bridge;
>> >  }
>> >
>> > -static unsigned char pcix_bus_speed[] = {
>> > +const unsigned char pcix_bus_speed[] = {
>> >         PCI_SPEED_UNKNOWN,              /* 0 */
>> >         PCI_SPEED_66MHz_PCIX,           /* 1 */
>> >         PCI_SPEED_100MHz_PCIX,          /* 2 */
>> > @@ -532,7 +532,7 @@ static unsigned char pcix_bus_speed[] = {
>> >         PCI_SPEED_133MHz_PCIX_533       /* F */
>> >  };
>> >
>> > -static unsigned char pcie_link_speed[] = {
>> > +const unsigned char pcie_link_speed[] = {
>> >         PCI_SPEED_UNKNOWN,              /* 0 */
>> >         PCIE_SPEED_2_5GT,               /* 1 */
>> >         PCIE_SPEED_5_0GT,               /* 2 */
>> > diff --git a/include/linux/pci.h b/include/linux/pci.h
>> > index 0fd1f15..95ff993 100644
>> > --- a/include/linux/pci.h
>> > +++ b/include/linux/pci.h
>> > @@ -120,6 +120,9 @@ typedef int __bitwise pci_power_t;
>> >  /* Remember to update this when the list above changes! */
>> >  extern const char *pci_power_names[];
>> >
>> > +extern const unsigned char pcix_bus_speed[];
>> > +extern const unsigned char pcie_link_speed[];
>>
>> As far as I can tell, you didn't actually add anything that uses
>> pcix_bus_speed[].
>>
>
> I mostly added this for consistency...
>
>> You added a pcie_link_speed[] use only in drivers/pci/pci.c; maybe
>> this extern declaration could go in drivers/pci/pci.h to limit its
>> visibility?
>
> Pretty sure I use the pcie_link_speed in the ixgbe driver by including
> the linux/pci.h header...  Check patch 11/15 of this series where I
> actually use the values, so it would need to be in the linux/pci.h
> header.

I'm not sure I was copied on patch 11/15.  I assume it might be
"ixgbe: call pcie_get_mimimum_link to check if device has enough
bandwidth", and I see that patch uses the pci_bus_speed enum, so the
enum definitely needs to be in include/linux/pci.h.  But I don't see
the pcie_link_speed[] reference.

I did fetch your git tree and searched the diffs themselves but the
only use I saw was in pcie_get_minimum_link() in drivers/pci/pci.c.

Bjorn

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth
  2013-07-29 12:52 ` [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth Jeff Kirsher
@ 2013-07-29 21:46   ` Keller, Jacob E
  0 siblings, 0 replies; 27+ messages in thread
From: Keller, Jacob E @ 2013-07-29 21:46 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: netdev

Hi Bjorn,

Here is the patch I was referring to, I think I see what you mean now...

On Mon, 2013-07-29 at 05:52 -0700, Jeff Kirsher wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
> 
> This patch uses the new pcie_get_minimum_link function to perform a check to
> ensure that the adapter is hooked into a slot which is capable of providing the
> necessary bandwidth. This check supersedes the original method which only
> checked the current pci device. The new method is capable of determining the
> minimum speed and link of an entire PCI chain.
> 
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 130 ++++++++++++++++++++++++--
>  1 file changed, 123 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 3aff87e..5ec2b74 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -195,6 +195,79 @@ static s32 ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter)
>  	return 0;
>  }
>  
> +/**
> + * ixgbe_check_from_parent - Determine whether PCIe info should come from parent
> + * @hw: hw specific details
> + *
> + * This function is used by probe to determine whether a device's PCI-Express
> + * bandwidth details should be gathered from the parent bus instead of from the
> + * device. Used to ensure that various locations all have the correct device ID
> + * checks.
> + */
> +static inline bool ixgbe_pcie_from_parent(struct ixgbe_hw *hw)
> +{
> +	switch (hw->device_id) {
> +	case IXGBE_DEV_ID_82599_SFP_SF_QP:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static void ixgbe_check_minimum_link(struct ixgbe_adapter *adapter,
> +				     int expected_gts)
> +{
> +	int max_gts = 0;
> +	enum pci_bus_speed speed = PCI_SPEED_UNKNOWN;
> +	enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
> +	struct pci_dev *pdev;
> +
> +	/* determine whether to use the the parent device
> +	 */
> +	if (ixgbe_pcie_from_parent(&adapter->hw))
> +		pdev = adapter->pdev->bus->parent->self;
> +	else
> +		pdev = adapter->pdev;
> +
> +	if (pcie_get_minimum_link(pdev, &speed, &width) ||
> +	    speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN) {
> +		e_dev_warn("Unable to determine PCI-Express slot throughput.\n");
> +		return;
> +	}
> +
> +	switch (speed) {
> +	case PCIE_SPEED_2_5GT:
> +		/* 8b/10b encoding reduces max throughput */
> +		max_gts = 2 * width;

I use the speed enums here, but I think you're right I don't use the
arrays, those are only used in the pci function directly, and I could
re-spin the patch to remove the addition of those.

Thanks,
Jake

> +		break;
> +	case PCIE_SPEED_5_0GT:
> +		/* 8b/10b encoding reduces max throughput */
> +		max_gts = 4 * width;
> +		break;
> +	case PCIE_SPEED_8_0GT:
> +		/* 128b/130b encoding has less impact on throughput */
> +		max_gts = 8 * width;
> +		break;
> +	default:
> +		e_dev_warn("Unable to determine PCI-Express throughput.\n");
> +		return;
> +	}
> +
> +	if (max_gts < expected_gts) {
> +		e_dev_warn("PCI-Express bandwidth of %dGT/s available (PCI Express:%s:Width x%d)\n",
> +			   max_gts,
> +			   (speed == PCIE_SPEED_8_0GT ? "8.0GT/s" :
> +			    speed == PCIE_SPEED_5_0GT ? "5.0GT/s" :
> +			    speed == PCIE_SPEED_2_5GT ? "2.5GT/s" :
> +			    "Unknown"),
> +			   width);
> +		e_dev_warn("This is not sufficient for optimal performance of this card.\n");
> +		e_dev_warn("For optimal performance, at least %dGT/s of bandwidth is required.\n",
> +			expected_gts);
> +		e_dev_warn("A slot with more lanes and/or higher speed is suggested.\n");
> +	}
> +}
> +
>  static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
>  {
>  	if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
> @@ -7250,6 +7323,41 @@ static const struct net_device_ops ixgbe_netdev_ops = {
>  };
>  
>  /**
> + * ixgbe_enumerate_functions - Get the number of ports this device has
> + * @adapter: adapter structure
> + *
> + * This function enumerates the phsyical functions co-located on a single slot,
> + * in order to determine how many ports a device has. This is most useful in
> + * determining the required GT/s of PCIe bandwidth necessary for optimal
> + * performance.
> + **/
> +static inline int ixgbe_enumerate_functions(struct ixgbe_adapter *adapter)
> +{
> +	struct ixgbe_hw *hw = &adapter->hw;
> +	struct list_head *entry;
> +	int physfns = 0;
> +
> +	/* Some cards can not use the generic count PCIe functions method, and
> +	 * so must be hardcoded to the correct value.
> +	 */
> +	switch (hw->device_id) {
> +	case IXGBE_DEV_ID_82599_SFP_SF_QP:
> +		physfns = 4;
> +		break;
> +	default:
> +		list_for_each(entry, &adapter->pdev->bus_list) {
> +			struct pci_dev *pdev =
> +				list_entry(entry, struct pci_dev, bus_list);
> +			/* don't count virtual functions */
> +			if (!pdev->is_virtfn)
> +				physfns++;
> +		}
> +	}
> +
> +	return physfns;
> +}
> +
> +/**
>   * ixgbe_wol_supported - Check whether device supports WoL
>   * @hw: hw specific details
>   * @device_id: the device ID
> @@ -7331,7 +7439,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	struct ixgbe_hw *hw;
>  	const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
>  	static int cards_found;
> -	int i, err, pci_using_dac;
> +	int i, err, pci_using_dac, expected_gts;
>  	unsigned int indices = MAX_TX_QUEUES;
>  	u8 part_str[IXGBE_PBANUM_LENGTH];
>  #ifdef IXGBE_FCOE
> @@ -7620,7 +7728,7 @@ skip_sriov:
>  
>  	/* 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)
> +	if (ixgbe_pcie_from_parent(hw))
>  		ixgbe_get_parent_bus_info(adapter);
>  
>  	/* print bus type/speed/width info */
> @@ -7646,12 +7754,20 @@ skip_sriov:
>  		e_dev_info("MAC: %d, PHY: %d, PBA No: %s\n",
>  			   hw->mac.type, hw->phy.type, part_str);
>  
> -	if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
> -		e_dev_warn("PCI-Express bandwidth available for this card is "
> -			   "not sufficient for optimal performance.\n");
> -		e_dev_warn("For optimal performance a x8 PCI-Express slot "
> -			   "is required.\n");
> +	/* calculate the expected PCIe bandwidth required for optimal
> +	 * performance. Note that some older parts will never have enough
> +	 * bandwidth due to being older generation PCIe parts. We clamp these
> +	 * parts to ensure no warning is displayed if it can't be fixed.
> +	 */
> +	switch (hw->mac.type) {
> +	case ixgbe_mac_82598EB:
> +		expected_gts = min(ixgbe_enumerate_functions(adapter) * 10, 16);
> +		break;
> +	default:
> +		expected_gts = ixgbe_enumerate_functions(adapter) * 10;
> +		break;
>  	}
> +	ixgbe_check_minimum_link(adapter, expected_gts);
>  
>  	/* reset the hardware with the new settings */
>  	err = hw->mac.ops.start_hw(hw);



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting.
  2013-07-29 12:51 ` [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting Jeff Kirsher
@ 2013-07-30  5:18   ` David Miller
  2013-07-30 16:17     ` Skidmore, Donald C
  0 siblings, 1 reply; 27+ messages in thread
From: David Miller @ 2013-07-30  5:18 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: donald.c.skidmore, netdev, gospo, sassmann

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Mon, 29 Jul 2013 05:51:59 -0700
> @@ -67,15 +67,39 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
>   **/
>  s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
>  {
> +	bool supported = false;
 ...
> +	return supported;

If the function is returning bool, fix the function's return type from
's32' to 'bool'.


> -		    (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
> +		    (ixgbe_device_supports_autoneg_fc(hw))) {

I think the outermost parenthesis in "(ixgbe_device_supports_autoneg_fc(hw))"
should be removed.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 04/15] ixgbe: add new media type
  2013-07-29 12:52 ` [net-next 04/15] ixgbe: add new media type Jeff Kirsher
@ 2013-07-30  5:20   ` David Miller
  0 siblings, 0 replies; 27+ messages in thread
From: David Miller @ 2013-07-30  5:20 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: donald.c.skidmore, netdev, gospo, sassmann

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Mon, 29 Jul 2013 05:52:00 -0700

> +	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
> +					    IXGBE_I2C_EEPROM_DEV_ADDR2,
> +					    eeprom_data);
> +	if (status) {
> +		hw_dbg(hw, "Failed to read Rx Rate Select RS1\n");
> +		goto out;
> +	}

Either the call, or the debugging message, is wrong.

They don't agree on whether this is a read or a write.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting.
  2013-07-30  5:18   ` David Miller
@ 2013-07-30 16:17     ` Skidmore, Donald C
  0 siblings, 0 replies; 27+ messages in thread
From: Skidmore, Donald C @ 2013-07-30 16:17 UTC (permalink / raw)
  To: David Miller, Kirsher, Jeffrey T; +Cc: netdev, gospo, sassmann

> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Monday, July 29, 2013 10:19 PM
> To: Kirsher, Jeffrey T
> Cc: Skidmore, Donald C; netdev@vger.kernel.org; gospo@redhat.com;
> sassmann@redhat.com
> Subject: Re: [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting.
> 
> From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon, 29 Jul 2013 05:51:59 -0700
> > @@ -67,15 +67,39 @@ static s32 ixgbe_disable_pcie_master(struct
> ixgbe_hw *hw);
> >   **/
> >  s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)  {
> > +	bool supported = false;
>  ...
> > +	return supported;
> 
> If the function is returning bool, fix the function's return type from 's32' to
> 'bool'.
> 
> 
> > -		    (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
> > +		    (ixgbe_device_supports_autoneg_fc(hw))) {
> 
> I think the outermost parenthesis in
> "(ixgbe_device_supports_autoneg_fc(hw))"
> should be removed.

Thanks Dave, I'll clean this up and send the new patches to Jeff.

-Don Skidmore <donald.c.skidmore>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules
  2013-07-29 12:52 ` [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules Jeff Kirsher
@ 2013-08-02  9:08   ` Ben Hutchings
  2013-08-06  0:56     ` Tantilov, Emil S
  0 siblings, 1 reply; 27+ messages in thread
From: Ben Hutchings @ 2013-08-02  9:08 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, Emil Tantilov, netdev, gospo, sassmann

On Mon, 2013-07-29 at 05:52 -0700, Jeff Kirsher wrote:
> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> This patch fixes several issues with the previous implementation of the
> SFF data dump of SFP+ modules:
> 
> - removed the __IXGBE_READ_I2C flag - I2C access locking is handled in the
>   HW specific routines
> 
> - fixed the read loop to read data from ee->offset to ee->len
> 
> - the reads fail if __IXGBE_IN_SFP_INIT is set in the process - this is
>   needed because on some HW I2C operations can take long time and disrupt
>   the SFP and link detection process
> 
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Reported-by: Ben Hutchings <bhutchings@solarflare.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
[...]
> @@ -2969,48 +2955,25 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
>  	int i = 0;
>  	int ret_val = 0;
>  
> -	/* ixgbe_get_module_info is called before this function in all
> -	 * cases, so we do not need any checks we already do above,
> -	 * and can trust ee->len to be a known value.
> -	 */
> +	if (ee->len == 0)
> +		return -EINVAL;
>  
> -	while (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
> -		msleep(100);
> -	set_bit(__IXGBE_READ_I2C, &adapter->state);
> +	for (i = ee->offset; i < ee->len; i++) {

                               i < ee->offset + ee->len

> +		/* I2C reads can take long time */
> +		if (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
> +			return -EBUSY;
>  
> -	/* Read the first block, SFF-8079 */
> -	for (i = 0; i < ETH_MODULE_SFF_8079_LEN; i++) {
> -		status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
> -		if (status != 0) {
> -			/* Error occured while reading module */
> +		if (i < ETH_MODULE_SFF_8079_LEN)
> +			status  = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
> +		else
> +			status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);
[...]
                                                     i - ETH_MODULE_SFF_8079_LEN ?

But this works anyway because the address is truncated to u8.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules
  2013-08-02  9:08   ` Ben Hutchings
@ 2013-08-06  0:56     ` Tantilov, Emil S
  0 siblings, 0 replies; 27+ messages in thread
From: Tantilov, Emil S @ 2013-08-06  0:56 UTC (permalink / raw)
  To: Ben Hutchings, Kirsher, Jeffrey T; +Cc: davem, netdev, gospo, sassmann

>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-
>owner@vger.kernel.org] On Behalf Of Ben Hutchings
>Sent: Friday, August 02, 2013 2:09 AM
>To: Kirsher, Jeffrey T
>Cc: davem@davemloft.net; Tantilov, Emil S;
>netdev@vger.kernel.org; gospo@redhat.com;
>sassmann@redhat.com
>Subject: Re: [net-next 07/15] ixgbe: fix SFF data dumps of
>SFP+ modules
>
>On Mon, 2013-07-29 at 05:52 -0700, Jeff Kirsher wrote:
>> From: Emil Tantilov <emil.s.tantilov@intel.com>
>>
>> This patch fixes several issues with the previous
>implementation of the
>> SFF data dump of SFP+ modules:
>>
>> - removed the __IXGBE_READ_I2C flag - I2C access locking
>is handled in the
>>   HW specific routines
>>
>> - fixed the read loop to read data from ee->offset to ee-
>>len
>>
>> - the reads fail if __IXGBE_IN_SFP_INIT is set in the
>process - this is
>>   needed because on some HW I2C operations can take long
>time and disrupt
>>   the SFP and link detection process
>>
>> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
>> Reported-by: Ben Hutchings <bhutchings@solarflare.com>
>> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
>> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>[...]
>> @@ -2969,48 +2955,25 @@ static int
>ixgbe_get_module_eeprom(struct net_device *dev,
>>  	int i = 0;
>>  	int ret_val = 0;
>>
>> -	/* ixgbe_get_module_info is called before this function
>in all
>> -	 * cases, so we do not need any checks we already do
>above,
>> -	 * and can trust ee->len to be a known value.
>> -	 */
>> +	if (ee->len == 0)
>> +		return -EINVAL;
>>
>> -	while (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
>> -		msleep(100);
>> -	set_bit(__IXGBE_READ_I2C, &adapter->state);
>> +	for (i = ee->offset; i < ee->len; i++) {
>
>                               i < ee->offset + ee->len
>
>> +		/* I2C reads can take long time */
>> +		if (test_bit(__IXGBE_IN_SFP_INIT, &adapter-
>>state))
>> +			return -EBUSY;
>>
>> -	/* Read the first block, SFF-8079 */
>> -	for (i = 0; i < ETH_MODULE_SFF_8079_LEN; i++) {
>> -		status = hw->phy.ops.read_i2c_eeprom(hw, i,
>&databyte);
>> -		if (status != 0) {
>> -			/* Error occured while reading module */
>> +		if (i < ETH_MODULE_SFF_8079_LEN)
>> +			status  = hw->phy.ops.read_i2c_eeprom(hw, i,
>&databyte);
>> +		else
>> +			status = hw->phy.ops.read_i2c_sff8472(hw, i,
>&databyte);
>[...]
>                                                     i -
>ETH_MODULE_SFF_8079_LEN ?
>
>But this works anyway because the address is truncated to
>u8.

Actually as is the loop will only work when offset is 0, so it looks like it should be:

for (i = ee->offset; i < ee->offset + ee->len; i++) {


Unless you had something else in mind.

I will submit a fix for this.

Thanks,
Emil

>
>Ben.


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2013-08-06  0:56 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-29 12:51 [net-next 00/15][pull request] Intel Wired LAN Driver Updates Jeff Kirsher
2013-07-29 12:51 ` [net-next 01/15] ixgbe: Retain VLAN filtering in promiscuous + VT mode Jeff Kirsher
2013-07-29 12:51 ` [net-next 02/15] ixgbe: Use pci_vfs_assigned instead of ixgbe_vfs_are_assigned Jeff Kirsher
2013-07-29 12:51 ` [net-next 03/15] ixgbe: fix fc autoneg ethtool reporting Jeff Kirsher
2013-07-30  5:18   ` David Miller
2013-07-30 16:17     ` Skidmore, Donald C
2013-07-29 12:52 ` [net-next 04/15] ixgbe: add new media type Jeff Kirsher
2013-07-30  5:20   ` David Miller
2013-07-29 12:52 ` [net-next 05/15] ixgbe: bump version number Jeff Kirsher
2013-07-29 12:52 ` [net-next 06/15] ixgbe: fix semaphore lock for I2C read/writes on 82598 Jeff Kirsher
2013-07-29 12:52 ` [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules Jeff Kirsher
2013-08-02  9:08   ` Ben Hutchings
2013-08-06  0:56     ` Tantilov, Emil S
2013-07-29 12:52 ` [net-next 08/15] pci: expose pcie_link_speed and pcix_bus_speed arrays Jeff Kirsher
2013-07-29 18:44   ` Bjorn Helgaas
2013-07-29 21:03     ` Keller, Jacob E
2013-07-29 21:19       ` Bjorn Helgaas
2013-07-29 12:52 ` [net-next 09/15] pci: move enum pcie_link_width into pci.h Jeff Kirsher
2013-07-29 18:39   ` Bjorn Helgaas
2013-07-29 12:52 ` [net-next 10/15] pci: Add function to obtain minimum link width and speed Jeff Kirsher
2013-07-29 18:45   ` Bjorn Helgaas
2013-07-29 12:52 ` [net-next 11/15] ixgbe: call pcie_get_mimimum_link to check if device has enough bandwidth Jeff Kirsher
2013-07-29 21:46   ` Keller, Jacob E
2013-07-29 12:52 ` [net-next 12/15] ixgbe: fix lockdep annotation issue for ptp's work item Jeff Kirsher
2013-07-29 12:52 ` [net-next 13/15] ixgbe: rename LL_EXTENDED_STATS to use queue instead of q Jeff Kirsher
2013-07-29 12:52 ` [net-next 14/15] ixgbe: clear semaphore bits on timeouts Jeff Kirsher
2013-07-29 12:52 ` [net-next 15/15] ixgbe: add support for quad-port x520 adapter Jeff Kirsher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).