ixgbe: Add support for 82599 alternative WWNN/WWPN prefix
authorYi Zou <yi.zou@intel.com>
Wed, 28 Oct 2009 18:23:57 +0000 (18:23 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 29 Oct 2009 08:04:01 +0000 (01:04 -0700)
The 82599 EEPROM supports alternative prefix for World Wide Node Name
(WWNN) and World Wide Port Name (WWPN). The prefixes can be used together
with the SAN MAC address to form the WWNN and WWPN, which can be used by
upper layer drivers such as Fiber Channel over Ethernet (FCoE).

Signed-off-by: Yi Zou <yi.zou@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_type.h

index ae27c41..7210689 100644 (file)
@@ -1000,6 +1000,10 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
                hw->mac.num_rar_entries--;
        }
 
+       /* Store the alternative WWNN/WWPN prefix */
+       hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
+                                      &hw->mac.wwpn_prefix);
+
 reset_hw_out:
        return status;
 }
@@ -2536,6 +2540,51 @@ fw_version_out:
        return status;
 }
 
+/**
+ *  ixgbe_get_wwn_prefix_82599 - Get alternative WWNN/WWPN prefix from
+ *  the EEPROM
+ *  @hw: pointer to hardware structure
+ *  @wwnn_prefix: the alternative WWNN prefix
+ *  @wwpn_prefix: the alternative WWPN prefix
+ *
+ *  This function will read the EEPROM from the alternative SAN MAC address
+ *  block to check the support for the alternative WWNN/WWPN prefix support.
+ **/
+static s32 ixgbe_get_wwn_prefix_82599(struct ixgbe_hw *hw, u16 *wwnn_prefix,
+                                      u16 *wwpn_prefix)
+{
+       u16 offset, caps;
+       u16 alt_san_mac_blk_offset;
+
+       /* clear output first */
+       *wwnn_prefix = 0xFFFF;
+       *wwpn_prefix = 0xFFFF;
+
+       /* check if alternative SAN MAC is supported */
+       hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
+                           &alt_san_mac_blk_offset);
+
+       if ((alt_san_mac_blk_offset == 0) ||
+           (alt_san_mac_blk_offset == 0xFFFF))
+               goto wwn_prefix_out;
+
+       /* check capability in alternative san mac address block */
+       offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
+       hw->eeprom.ops.read(hw, offset, &caps);
+       if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
+               goto wwn_prefix_out;
+
+       /* get the corresponding prefix for WWNN/WWPN */
+       offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
+       hw->eeprom.ops.read(hw, offset, wwnn_prefix);
+
+       offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
+       hw->eeprom.ops.read(hw, offset, wwpn_prefix);
+
+wwn_prefix_out:
+       return 0;
+}
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
        .init_hw                = &ixgbe_init_hw_generic,
        .reset_hw               = &ixgbe_reset_hw_82599,
@@ -2547,6 +2596,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
        .get_mac_addr           = &ixgbe_get_mac_addr_generic,
        .get_san_mac_addr       = &ixgbe_get_san_mac_addr_82599,
        .get_device_caps        = &ixgbe_get_device_caps_82599,
+       .get_wwn_prefix         = &ixgbe_get_wwn_prefix_82599,
        .stop_adapter           = &ixgbe_stop_adapter_generic,
        .get_bus_info           = &ixgbe_get_bus_info_generic,
        .set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
index 1cab53e..21b6633 100644 (file)
 #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR   0x4
 #define IXGBE_FW_PATCH_VERSION_4   0x7
 
+/* Alternative SAN MAC Address Block */
+#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR      0x27 /* Alt. SAN MAC block */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET  0x0 /* Alt. SAN MAC capability */
+#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_PORT1_OFFSET 0x4 /* Alt. SAN MAC 1 offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET  0x7 /* Alt. WWNN prefix offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET  0x8 /* Alt. WWPN prefix offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_SANMAC  0x0 /* Alt. SAN MAC exists */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN  0x1 /* Alt. WWN base exists */
+
 /* PCI Bus Info */
 #define IXGBE_PCI_LINK_STATUS     0xB2
 #define IXGBE_PCI_DEVICE_CONTROL2 0xC8
@@ -2345,6 +2355,7 @@ struct ixgbe_mac_operations {
        s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
        s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
        s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
+       s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *);
        s32 (*stop_adapter)(struct ixgbe_hw *);
        s32 (*get_bus_info)(struct ixgbe_hw *);
        void (*set_lan_id)(struct ixgbe_hw *);
@@ -2416,6 +2427,10 @@ struct ixgbe_mac_info {
        u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
        u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
        u8                              san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+       /* prefix for World Wide Node Name (WWNN) */
+       u16                             wwnn_prefix;
+       /* prefix for World Wide Port Name (WWPN) */
+       u16                             wwpn_prefix;
        s32                             mc_filter_type;
        u32                             mcft_size;
        u32                             vft_size;