| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1 | /******************************************************************************* | 
|  | 2 |  | 
|  | 3 | Intel 10 Gigabit PCI Express Linux driver | 
| Peter P Waskiewicz Jr | 3efac5a | 2009-02-01 01:19:20 -0800 | [diff] [blame] | 4 | Copyright(c) 1999 - 2009 Intel Corporation. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 5 |  | 
|  | 6 | This program is free software; you can redistribute it and/or modify it | 
|  | 7 | under the terms and conditions of the GNU General Public License, | 
|  | 8 | version 2, as published by the Free Software Foundation. | 
|  | 9 |  | 
|  | 10 | This program is distributed in the hope it will be useful, but WITHOUT | 
|  | 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|  | 12 | FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
|  | 13 | more details. | 
|  | 14 |  | 
|  | 15 | You should have received a copy of the GNU General Public License along with | 
|  | 16 | this program; if not, write to the Free Software Foundation, Inc., | 
|  | 17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 
|  | 18 |  | 
|  | 19 | The full GNU General Public License is included in this distribution in | 
|  | 20 | the file called "COPYING". | 
|  | 21 |  | 
|  | 22 | Contact Information: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 23 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | 
|  | 24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 
|  | 25 |  | 
|  | 26 | *******************************************************************************/ | 
|  | 27 |  | 
|  | 28 | #include <linux/pci.h> | 
|  | 29 | #include <linux/delay.h> | 
|  | 30 | #include <linux/sched.h> | 
|  | 31 |  | 
| Stephen Hemminger | 9c8eb72 | 2007-10-29 10:46:24 -0700 | [diff] [blame] | 32 | #include "ixgbe.h" | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 33 | #include "ixgbe_phy.h" | 
|  | 34 |  | 
|  | 35 | #define IXGBE_82598_MAX_TX_QUEUES 32 | 
|  | 36 | #define IXGBE_82598_MAX_RX_QUEUES 64 | 
|  | 37 | #define IXGBE_82598_RAR_ENTRIES   16 | 
| Christopher Leech | 2c5645c | 2008-08-26 04:27:02 -0700 | [diff] [blame] | 38 | #define IXGBE_82598_MC_TBL_SIZE  128 | 
|  | 39 | #define IXGBE_82598_VFT_TBL_SIZE 128 | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 40 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 41 | static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, | 
|  | 42 | ixgbe_link_speed *speed, | 
|  | 43 | bool *autoneg); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 44 | static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 45 | static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, | 
|  | 46 | ixgbe_link_speed speed, | 
|  | 47 | bool autoneg, | 
|  | 48 | bool autoneg_wait_to_complete); | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 49 | static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, | 
|  | 50 | u8 *eeprom_data); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 51 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 52 | /** | 
| Peter P Waskiewicz Jr | eb7f139 | 2009-02-01 01:18:58 -0800 | [diff] [blame] | 53 | *  ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count | 
|  | 54 | *  @hw: pointer to hardware structure | 
|  | 55 | * | 
|  | 56 | *  Read PCIe configuration space, and get the MSI-X vector count from | 
|  | 57 | *  the capabilities table. | 
|  | 58 | **/ | 
| Hannes Eder | 1aef47c | 2009-02-14 11:38:36 +0000 | [diff] [blame] | 59 | static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw) | 
| Peter P Waskiewicz Jr | eb7f139 | 2009-02-01 01:18:58 -0800 | [diff] [blame] | 60 | { | 
|  | 61 | struct ixgbe_adapter *adapter = hw->back; | 
|  | 62 | u16 msix_count; | 
|  | 63 | pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82598_CAPS, | 
|  | 64 | &msix_count); | 
|  | 65 | msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; | 
|  | 66 |  | 
|  | 67 | /* MSI-X count is zero-based in HW, so increment to give proper value */ | 
|  | 68 | msix_count++; | 
|  | 69 |  | 
|  | 70 | return msix_count; | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 74 | */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 75 | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) | 
|  | 76 | { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 77 | struct ixgbe_mac_info *mac = &hw->mac; | 
| PJ Waskiewicz | 03cfa20 | 2009-03-19 01:23:29 +0000 | [diff] [blame] | 78 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 79 | /* Call PHY identify routine to get the phy type */ | 
|  | 80 | ixgbe_identify_phy_generic(hw); | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 81 |  | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 82 | mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; | 
|  | 83 | mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; | 
|  | 84 | mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; | 
|  | 85 | mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; | 
|  | 86 | mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; | 
|  | 87 | mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); | 
|  | 88 |  | 
|  | 89 | return 0; | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | /** | 
|  | 93 | *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init | 
|  | 94 | *  @hw: pointer to hardware structure | 
|  | 95 | * | 
|  | 96 | *  Initialize any function pointers that were not able to be | 
|  | 97 | *  set during get_invariants because the PHY/SFP type was | 
|  | 98 | *  not known.  Perform the SFP init if necessary. | 
|  | 99 | * | 
|  | 100 | **/ | 
|  | 101 | s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) | 
|  | 102 | { | 
|  | 103 | struct ixgbe_mac_info *mac = &hw->mac; | 
|  | 104 | struct ixgbe_phy_info *phy = &hw->phy; | 
|  | 105 | s32 ret_val = 0; | 
|  | 106 | u16 list_offset, data_offset; | 
|  | 107 |  | 
|  | 108 | /* Identify the PHY */ | 
|  | 109 | phy->ops.identify(hw); | 
|  | 110 |  | 
|  | 111 | /* Overwrite the link function pointers if copper PHY */ | 
|  | 112 | if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { | 
|  | 113 | mac->ops.setup_link = &ixgbe_setup_copper_link_82598; | 
|  | 114 | mac->ops.setup_link_speed = | 
|  | 115 | &ixgbe_setup_copper_link_speed_82598; | 
|  | 116 | mac->ops.get_link_capabilities = | 
|  | 117 | &ixgbe_get_copper_link_capabilities_82598; | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | switch (hw->phy.type) { | 
| Jesse Brandeburg | 0befdb3 | 2008-10-31 00:46:40 -0700 | [diff] [blame] | 121 | case ixgbe_phy_tn: | 
|  | 122 | phy->ops.check_link = &ixgbe_check_phy_link_tnx; | 
|  | 123 | phy->ops.get_firmware_version = | 
|  | 124 | &ixgbe_get_phy_firmware_version_tnx; | 
|  | 125 | break; | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 126 | case ixgbe_phy_nl: | 
|  | 127 | phy->ops.reset = &ixgbe_reset_phy_nl; | 
|  | 128 |  | 
|  | 129 | /* Call SFP+ identify routine to get the SFP+ module type */ | 
|  | 130 | ret_val = phy->ops.identify_sfp(hw); | 
|  | 131 | if (ret_val != 0) | 
|  | 132 | goto out; | 
|  | 133 | else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) { | 
|  | 134 | ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; | 
|  | 135 | goto out; | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | /* Check to see if SFP+ module is supported */ | 
|  | 139 | ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 140 | &list_offset, | 
|  | 141 | &data_offset); | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 142 | if (ret_val != 0) { | 
|  | 143 | ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; | 
|  | 144 | goto out; | 
|  | 145 | } | 
|  | 146 | break; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 147 | default: | 
|  | 148 | break; | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 149 | } | 
|  | 150 |  | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 151 | out: | 
|  | 152 | return ret_val; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 153 | } | 
|  | 154 |  | 
|  | 155 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 156 | *  ixgbe_get_link_capabilities_82598 - Determines link capabilities | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 157 | *  @hw: pointer to hardware structure | 
|  | 158 | *  @speed: pointer to link speed | 
|  | 159 | *  @autoneg: boolean auto-negotiation value | 
|  | 160 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 161 | *  Determines the link capabilities by reading the AUTOC register. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 162 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 163 | static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 164 | ixgbe_link_speed *speed, | 
|  | 165 | bool *autoneg) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 166 | { | 
|  | 167 | s32 status = 0; | 
| PJ Waskiewicz | 1eb99d5 | 2009-04-09 22:28:33 +0000 | [diff] [blame] | 168 | u32 autoc = 0; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 169 |  | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 170 | /* | 
|  | 171 | * Determine link capabilities based on the stored value of AUTOC, | 
| PJ Waskiewicz | 1eb99d5 | 2009-04-09 22:28:33 +0000 | [diff] [blame] | 172 | * which represents EEPROM defaults.  If AUTOC value has not been | 
|  | 173 | * stored, use the current register value. | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 174 | */ | 
| PJ Waskiewicz | 1eb99d5 | 2009-04-09 22:28:33 +0000 | [diff] [blame] | 175 | if (hw->mac.orig_link_settings_stored) | 
|  | 176 | autoc = hw->mac.orig_autoc; | 
|  | 177 | else | 
|  | 178 | autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 179 |  | 
|  | 180 | switch (autoc & IXGBE_AUTOC_LMS_MASK) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 181 | case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: | 
|  | 182 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 
|  | 183 | *autoneg = false; | 
|  | 184 | break; | 
|  | 185 |  | 
|  | 186 | case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: | 
|  | 187 | *speed = IXGBE_LINK_SPEED_10GB_FULL; | 
|  | 188 | *autoneg = false; | 
|  | 189 | break; | 
|  | 190 |  | 
|  | 191 | case IXGBE_AUTOC_LMS_1G_AN: | 
|  | 192 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 
|  | 193 | *autoneg = true; | 
|  | 194 | break; | 
|  | 195 |  | 
|  | 196 | case IXGBE_AUTOC_LMS_KX4_AN: | 
|  | 197 | case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: | 
|  | 198 | *speed = IXGBE_LINK_SPEED_UNKNOWN; | 
| PJ Waskiewicz | 1eb99d5 | 2009-04-09 22:28:33 +0000 | [diff] [blame] | 199 | if (autoc & IXGBE_AUTOC_KX4_SUPP) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 200 | *speed |= IXGBE_LINK_SPEED_10GB_FULL; | 
| PJ Waskiewicz | 1eb99d5 | 2009-04-09 22:28:33 +0000 | [diff] [blame] | 201 | if (autoc & IXGBE_AUTOC_KX_SUPP) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 202 | *speed |= IXGBE_LINK_SPEED_1GB_FULL; | 
|  | 203 | *autoneg = true; | 
|  | 204 | break; | 
|  | 205 |  | 
|  | 206 | default: | 
|  | 207 | status = IXGBE_ERR_LINK_SETUP; | 
|  | 208 | break; | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | return status; | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 215 | *  ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 216 | *  @hw: pointer to hardware structure | 
|  | 217 | *  @speed: pointer to link speed | 
|  | 218 | *  @autoneg: boolean auto-negotiation value | 
|  | 219 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 220 | *  Determines the link capabilities by reading the AUTOC register. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 221 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 222 | static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, | 
|  | 223 | ixgbe_link_speed *speed, | 
|  | 224 | bool *autoneg) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 225 | { | 
|  | 226 | s32 status = IXGBE_ERR_LINK_SETUP; | 
|  | 227 | u16 speed_ability; | 
|  | 228 |  | 
|  | 229 | *speed = 0; | 
|  | 230 | *autoneg = true; | 
|  | 231 |  | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 232 | status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 233 | &speed_ability); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 234 |  | 
|  | 235 | if (status == 0) { | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 236 | if (speed_ability & MDIO_SPEED_10G) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 237 | *speed |= IXGBE_LINK_SPEED_10GB_FULL; | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 238 | if (speed_ability & MDIO_PMA_SPEED_1000) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 239 | *speed |= IXGBE_LINK_SPEED_1GB_FULL; | 
|  | 240 | } | 
|  | 241 |  | 
|  | 242 | return status; | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | /** | 
|  | 246 | *  ixgbe_get_media_type_82598 - Determines media type | 
|  | 247 | *  @hw: pointer to hardware structure | 
|  | 248 | * | 
|  | 249 | *  Returns the media type (fiber, copper, backplane) | 
|  | 250 | **/ | 
|  | 251 | static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) | 
|  | 252 | { | 
|  | 253 | enum ixgbe_media_type media_type; | 
|  | 254 |  | 
|  | 255 | /* Media type for I82598 is based on device ID */ | 
|  | 256 | switch (hw->device_id) { | 
| Don Skidmore | 1e336d0 | 2009-01-26 20:57:51 -0800 | [diff] [blame] | 257 | case IXGBE_DEV_ID_82598: | 
| Don Skidmore | 2f21bdd | 2009-02-01 01:18:23 -0800 | [diff] [blame] | 258 | case IXGBE_DEV_ID_82598_BX: | 
| Don Skidmore | 1e336d0 | 2009-01-26 20:57:51 -0800 | [diff] [blame] | 259 | media_type = ixgbe_media_type_backplane; | 
|  | 260 | break; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 261 | case IXGBE_DEV_ID_82598AF_DUAL_PORT: | 
|  | 262 | case IXGBE_DEV_ID_82598AF_SINGLE_PORT: | 
|  | 263 | case IXGBE_DEV_ID_82598EB_CX4: | 
| Jesse Brandeburg | 8d792cd | 2008-08-08 16:24:19 -0700 | [diff] [blame] | 264 | case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 265 | case IXGBE_DEV_ID_82598_DA_DUAL_PORT: | 
|  | 266 | case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: | 
| Jesse Brandeburg | b95f5fc | 2008-09-11 19:58:59 -0700 | [diff] [blame] | 267 | case IXGBE_DEV_ID_82598EB_XF_LR: | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 268 | case IXGBE_DEV_ID_82598EB_SFP_LOM: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 269 | media_type = ixgbe_media_type_fiber; | 
|  | 270 | break; | 
| Jesse Brandeburg | 0befdb3 | 2008-10-31 00:46:40 -0700 | [diff] [blame] | 271 | case IXGBE_DEV_ID_82598AT: | 
|  | 272 | media_type = ixgbe_media_type_copper; | 
|  | 273 | break; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 274 | default: | 
|  | 275 | media_type = ixgbe_media_type_unknown; | 
|  | 276 | break; | 
|  | 277 | } | 
|  | 278 |  | 
|  | 279 | return media_type; | 
|  | 280 | } | 
|  | 281 |  | 
|  | 282 | /** | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 283 | *  ixgbe_fc_enable_82598 - Enable flow control | 
|  | 284 | *  @hw: pointer to hardware structure | 
|  | 285 | *  @packetbuf_num: packet buffer number (0-7) | 
|  | 286 | * | 
|  | 287 | *  Enable flow control according to the current settings. | 
|  | 288 | **/ | 
|  | 289 | static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) | 
|  | 290 | { | 
|  | 291 | s32 ret_val = 0; | 
|  | 292 | u32 fctrl_reg; | 
|  | 293 | u32 rmcs_reg; | 
|  | 294 | u32 reg; | 
|  | 295 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 296 | #ifdef CONFIG_DCB | 
|  | 297 | if (hw->fc.requested_mode == ixgbe_fc_pfc) | 
|  | 298 | goto out; | 
|  | 299 |  | 
|  | 300 | #endif /* CONFIG_DCB */ | 
|  | 301 | /* Negotiate the fc mode to use */ | 
|  | 302 | ret_val = ixgbe_fc_autoneg(hw); | 
|  | 303 | if (ret_val) | 
|  | 304 | goto out; | 
|  | 305 |  | 
|  | 306 | /* Disable any previous flow control settings */ | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 307 | fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | 
|  | 308 | fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); | 
|  | 309 |  | 
|  | 310 | rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | 
|  | 311 | rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); | 
|  | 312 |  | 
|  | 313 | /* | 
|  | 314 | * The possible values of fc.current_mode are: | 
|  | 315 | * 0: Flow control is completely disabled | 
|  | 316 | * 1: Rx flow control is enabled (we can receive pause frames, | 
|  | 317 | *    but not send pause frames). | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 318 | * 2: Tx flow control is enabled (we can send pause frames but | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 319 | *     we do not support receiving pause frames). | 
|  | 320 | * 3: Both Rx and Tx flow control (symmetric) are enabled. | 
|  | 321 | * other: Invalid. | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 322 | #ifdef CONFIG_DCB | 
|  | 323 | * 4: Priority Flow Control is enabled. | 
|  | 324 | #endif | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 325 | */ | 
|  | 326 | switch (hw->fc.current_mode) { | 
|  | 327 | case ixgbe_fc_none: | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 328 | /* | 
|  | 329 | * Flow control is disabled by software override or autoneg. | 
|  | 330 | * The code below will actually disable it in the HW. | 
|  | 331 | */ | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 332 | break; | 
|  | 333 | case ixgbe_fc_rx_pause: | 
|  | 334 | /* | 
|  | 335 | * Rx Flow control is enabled and Tx Flow control is | 
|  | 336 | * disabled by software override. Since there really | 
|  | 337 | * isn't a way to advertise that we are capable of RX | 
|  | 338 | * Pause ONLY, we will advertise that we support both | 
|  | 339 | * symmetric and asymmetric Rx PAUSE.  Later, we will | 
|  | 340 | * disable the adapter's ability to send PAUSE frames. | 
|  | 341 | */ | 
|  | 342 | fctrl_reg |= IXGBE_FCTRL_RFCE; | 
|  | 343 | break; | 
|  | 344 | case ixgbe_fc_tx_pause: | 
|  | 345 | /* | 
|  | 346 | * Tx Flow control is enabled, and Rx Flow control is | 
|  | 347 | * disabled by software override. | 
|  | 348 | */ | 
|  | 349 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 
|  | 350 | break; | 
|  | 351 | case ixgbe_fc_full: | 
|  | 352 | /* Flow control (both Rx and Tx) is enabled by SW override. */ | 
|  | 353 | fctrl_reg |= IXGBE_FCTRL_RFCE; | 
|  | 354 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 
|  | 355 | break; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 356 | #ifdef CONFIG_DCB | 
|  | 357 | case ixgbe_fc_pfc: | 
|  | 358 | goto out; | 
|  | 359 | break; | 
|  | 360 | #endif /* CONFIG_DCB */ | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 361 | default: | 
|  | 362 | hw_dbg(hw, "Flow control param set incorrectly\n"); | 
|  | 363 | ret_val = -IXGBE_ERR_CONFIG; | 
|  | 364 | goto out; | 
|  | 365 | break; | 
|  | 366 | } | 
|  | 367 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 368 | /* Set 802.3x based flow control settings. */ | 
| PJ Waskiewicz | 2132d38 | 2009-04-09 22:26:21 +0000 | [diff] [blame] | 369 | fctrl_reg |= IXGBE_FCTRL_DPF; | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 370 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); | 
|  | 371 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); | 
|  | 372 |  | 
|  | 373 | /* Set up and enable Rx high/low water mark thresholds, enable XON. */ | 
|  | 374 | if (hw->fc.current_mode & ixgbe_fc_tx_pause) { | 
|  | 375 | if (hw->fc.send_xon) { | 
|  | 376 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), | 
|  | 377 | (hw->fc.low_water | IXGBE_FCRTL_XONE)); | 
|  | 378 | } else { | 
|  | 379 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), | 
|  | 380 | hw->fc.low_water); | 
|  | 381 | } | 
|  | 382 |  | 
|  | 383 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), | 
|  | 384 | (hw->fc.high_water | IXGBE_FCRTH_FCEN)); | 
|  | 385 | } | 
|  | 386 |  | 
|  | 387 | /* Configure pause time (2 TCs per register) */ | 
| Peter P Waskiewicz Jr | 264857b | 2009-05-17 12:35:16 +0000 | [diff] [blame] | 388 | reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 389 | if ((packetbuf_num & 1) == 0) | 
|  | 390 | reg = (reg & 0xFFFF0000) | hw->fc.pause_time; | 
|  | 391 | else | 
|  | 392 | reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); | 
|  | 393 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); | 
|  | 394 |  | 
|  | 395 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); | 
|  | 396 |  | 
|  | 397 | out: | 
|  | 398 | return ret_val; | 
|  | 399 | } | 
|  | 400 |  | 
|  | 401 | /** | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 402 | *  ixgbe_setup_mac_link_82598 - Configures MAC link settings | 
|  | 403 | *  @hw: pointer to hardware structure | 
|  | 404 | * | 
|  | 405 | *  Configures link settings based on values in the ixgbe_hw struct. | 
|  | 406 | *  Restarts the link.  Performs autonegotiation if needed. | 
|  | 407 | **/ | 
|  | 408 | static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) | 
|  | 409 | { | 
|  | 410 | u32 autoc_reg; | 
|  | 411 | u32 links_reg; | 
|  | 412 | u32 i; | 
|  | 413 | s32 status = 0; | 
|  | 414 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 415 | /* Restart link */ | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 416 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 417 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 
|  | 418 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 
|  | 419 |  | 
|  | 420 | /* Only poll for autoneg to complete if specified to do so */ | 
|  | 421 | if (hw->phy.autoneg_wait_to_complete) { | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 422 | if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 
|  | 423 | IXGBE_AUTOC_LMS_KX4_AN || | 
|  | 424 | (autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 
|  | 425 | IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 426 | links_reg = 0; /* Just in case Autoneg time = 0 */ | 
|  | 427 | for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { | 
|  | 428 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
|  | 429 | if (links_reg & IXGBE_LINKS_KX_AN_COMP) | 
|  | 430 | break; | 
|  | 431 | msleep(100); | 
|  | 432 | } | 
|  | 433 | if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { | 
|  | 434 | status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 435 | hw_dbg(hw, "Autonegotiation did not complete.\n"); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 436 | } | 
|  | 437 | } | 
|  | 438 | } | 
|  | 439 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 440 | /* Add delay to filter out noises during initial link setup */ | 
|  | 441 | msleep(50); | 
|  | 442 |  | 
|  | 443 | return status; | 
|  | 444 | } | 
|  | 445 |  | 
|  | 446 | /** | 
|  | 447 | *  ixgbe_check_mac_link_82598 - Get link/speed status | 
|  | 448 | *  @hw: pointer to hardware structure | 
|  | 449 | *  @speed: pointer to link speed | 
|  | 450 | *  @link_up: true is link is up, false otherwise | 
| Jesse Brandeburg | cf8280e | 2008-09-11 19:55:32 -0700 | [diff] [blame] | 451 | *  @link_up_wait_to_complete: bool used to wait for link up or not | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 452 | * | 
|  | 453 | *  Reads the links register to determine if link is up and the current speed | 
|  | 454 | **/ | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 455 | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, | 
|  | 456 | ixgbe_link_speed *speed, bool *link_up, | 
|  | 457 | bool link_up_wait_to_complete) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 458 | { | 
|  | 459 | u32 links_reg; | 
| Jesse Brandeburg | cf8280e | 2008-09-11 19:55:32 -0700 | [diff] [blame] | 460 | u32 i; | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 461 | u16 link_reg, adapt_comp_reg; | 
|  | 462 |  | 
|  | 463 | /* | 
|  | 464 | * SERDES PHY requires us to read link status from register 0xC79F. | 
|  | 465 | * Bit 0 set indicates link is up/ready; clear indicates link down. | 
|  | 466 | * 0xC00C is read to check that the XAUI lanes are active.  Bit 0 | 
|  | 467 | * clear indicates active; set indicates inactive. | 
|  | 468 | */ | 
|  | 469 | if (hw->phy.type == ixgbe_phy_nl) { | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 470 | hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); | 
|  | 471 | hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); | 
|  | 472 | hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 473 | &adapt_comp_reg); | 
|  | 474 | if (link_up_wait_to_complete) { | 
|  | 475 | for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { | 
|  | 476 | if ((link_reg & 1) && | 
|  | 477 | ((adapt_comp_reg & 1) == 0)) { | 
|  | 478 | *link_up = true; | 
|  | 479 | break; | 
|  | 480 | } else { | 
|  | 481 | *link_up = false; | 
|  | 482 | } | 
|  | 483 | msleep(100); | 
|  | 484 | hw->phy.ops.read_reg(hw, 0xC79F, | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 485 | MDIO_MMD_PMAPMD, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 486 | &link_reg); | 
|  | 487 | hw->phy.ops.read_reg(hw, 0xC00C, | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 488 | MDIO_MMD_PMAPMD, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 489 | &adapt_comp_reg); | 
|  | 490 | } | 
|  | 491 | } else { | 
|  | 492 | if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0)) | 
|  | 493 | *link_up = true; | 
|  | 494 | else | 
|  | 495 | *link_up = false; | 
|  | 496 | } | 
|  | 497 |  | 
|  | 498 | if (*link_up == false) | 
|  | 499 | goto out; | 
|  | 500 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 501 |  | 
|  | 502 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
| Jesse Brandeburg | cf8280e | 2008-09-11 19:55:32 -0700 | [diff] [blame] | 503 | if (link_up_wait_to_complete) { | 
|  | 504 | for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { | 
|  | 505 | if (links_reg & IXGBE_LINKS_UP) { | 
|  | 506 | *link_up = true; | 
|  | 507 | break; | 
|  | 508 | } else { | 
|  | 509 | *link_up = false; | 
|  | 510 | } | 
|  | 511 | msleep(100); | 
|  | 512 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
|  | 513 | } | 
|  | 514 | } else { | 
|  | 515 | if (links_reg & IXGBE_LINKS_UP) | 
|  | 516 | *link_up = true; | 
|  | 517 | else | 
|  | 518 | *link_up = false; | 
|  | 519 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 520 |  | 
|  | 521 | if (links_reg & IXGBE_LINKS_SPEED) | 
|  | 522 | *speed = IXGBE_LINK_SPEED_10GB_FULL; | 
|  | 523 | else | 
|  | 524 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 
|  | 525 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 526 | /* if link is down, zero out the current_mode */ | 
|  | 527 | if (*link_up == false) { | 
|  | 528 | hw->fc.current_mode = ixgbe_fc_none; | 
|  | 529 | hw->fc.fc_was_autonegged = false; | 
|  | 530 | } | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 531 | out: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 532 | return 0; | 
|  | 533 | } | 
|  | 534 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 535 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 536 | /** | 
|  | 537 | *  ixgbe_setup_mac_link_speed_82598 - Set MAC link speed | 
|  | 538 | *  @hw: pointer to hardware structure | 
|  | 539 | *  @speed: new link speed | 
|  | 540 | *  @autoneg: true if auto-negotiation enabled | 
|  | 541 | *  @autoneg_wait_to_complete: true if waiting is needed to complete | 
|  | 542 | * | 
|  | 543 | *  Set the link speed in the AUTOC register and restarts link. | 
|  | 544 | **/ | 
|  | 545 | static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 546 | ixgbe_link_speed speed, bool autoneg, | 
|  | 547 | bool autoneg_wait_to_complete) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 548 | { | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 549 | s32              status            = 0; | 
|  | 550 | ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; | 
|  | 551 | u32              curr_autoc        = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 552 | u32              autoc             = curr_autoc; | 
|  | 553 | u32              link_mode         = autoc & IXGBE_AUTOC_LMS_MASK; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 554 |  | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 555 | /* Check to see if speed passed in is supported. */ | 
|  | 556 | ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg); | 
|  | 557 | speed &= link_capabilities; | 
|  | 558 |  | 
|  | 559 | if (speed == IXGBE_LINK_SPEED_UNKNOWN) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 560 | status = IXGBE_ERR_LINK_SETUP; | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 561 |  | 
|  | 562 | /* Set KX4/KX support according to speed requested */ | 
|  | 563 | else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || | 
|  | 564 | link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | 
|  | 565 | autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK; | 
|  | 566 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) | 
|  | 567 | autoc |= IXGBE_AUTOC_KX4_SUPP; | 
|  | 568 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) | 
|  | 569 | autoc |= IXGBE_AUTOC_KX_SUPP; | 
|  | 570 | if (autoc != curr_autoc) | 
|  | 571 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 572 | } | 
|  | 573 |  | 
|  | 574 | if (status == 0) { | 
|  | 575 | hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete; | 
|  | 576 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 577 | /* | 
|  | 578 | * Setup and restart the link based on the new values in | 
|  | 579 | * ixgbe_hw This will write the AUTOC register based on the new | 
|  | 580 | * stored values | 
|  | 581 | */ | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 582 | status = ixgbe_setup_mac_link_82598(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 583 | } | 
|  | 584 |  | 
|  | 585 | return status; | 
|  | 586 | } | 
|  | 587 |  | 
|  | 588 |  | 
|  | 589 | /** | 
|  | 590 | *  ixgbe_setup_copper_link_82598 - Setup copper link settings | 
|  | 591 | *  @hw: pointer to hardware structure | 
|  | 592 | * | 
|  | 593 | *  Configures link settings based on values in the ixgbe_hw struct. | 
|  | 594 | *  Restarts the link.  Performs autonegotiation if needed.  Restart | 
|  | 595 | *  phy and wait for autonegotiate to finish.  Then synchronize the | 
|  | 596 | *  MAC and PHY. | 
|  | 597 | **/ | 
|  | 598 | static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) | 
|  | 599 | { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 600 | s32 status; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 601 |  | 
|  | 602 | /* Restart autonegotiation on PHY */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 603 | status = hw->phy.ops.setup_link(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 604 |  | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 605 | /* Set up MAC */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 606 | ixgbe_setup_mac_link_82598(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 607 |  | 
|  | 608 | return status; | 
|  | 609 | } | 
|  | 610 |  | 
|  | 611 | /** | 
|  | 612 | *  ixgbe_setup_copper_link_speed_82598 - Set the PHY autoneg advertised field | 
|  | 613 | *  @hw: pointer to hardware structure | 
|  | 614 | *  @speed: new link speed | 
|  | 615 | *  @autoneg: true if autonegotiation enabled | 
|  | 616 | *  @autoneg_wait_to_complete: true if waiting is needed to complete | 
|  | 617 | * | 
|  | 618 | *  Sets the link speed in the AUTOC register in the MAC and restarts link. | 
|  | 619 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 620 | static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 621 | ixgbe_link_speed speed, | 
|  | 622 | bool autoneg, | 
|  | 623 | bool autoneg_wait_to_complete) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 624 | { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 625 | s32 status; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 626 |  | 
|  | 627 | /* Setup the PHY according to input speed */ | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 628 | status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, | 
|  | 629 | autoneg_wait_to_complete); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 630 |  | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 631 | /* Set up MAC */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 632 | ixgbe_setup_mac_link_82598(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 633 |  | 
|  | 634 | return status; | 
|  | 635 | } | 
|  | 636 |  | 
|  | 637 | /** | 
|  | 638 | *  ixgbe_reset_hw_82598 - Performs hardware reset | 
|  | 639 | *  @hw: pointer to hardware structure | 
|  | 640 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 641 | *  Resets the hardware by resetting the transmit and receive units, masks and | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 642 | *  clears all interrupts, performing a PHY reset, and performing a link (MAC) | 
|  | 643 | *  reset. | 
|  | 644 | **/ | 
|  | 645 | static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | 
|  | 646 | { | 
|  | 647 | s32 status = 0; | 
| Don Skidmore | 8ca783a | 2009-05-26 20:40:47 -0700 | [diff] [blame] | 648 | s32 phy_status = 0; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 649 | u32 ctrl; | 
|  | 650 | u32 gheccr; | 
|  | 651 | u32 i; | 
|  | 652 | u32 autoc; | 
|  | 653 | u8  analog_val; | 
|  | 654 |  | 
|  | 655 | /* Call adapter stop to disable tx/rx and clear interrupts */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 656 | hw->mac.ops.stop_adapter(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 657 |  | 
|  | 658 | /* | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 659 | * Power up the Atlas Tx lanes if they are currently powered down. | 
|  | 660 | * Atlas Tx lanes are powered down for MAC loopback tests, but | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 661 | * they are not automatically restored on reset. | 
|  | 662 | */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 663 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 664 | if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 665 | /* Enable Tx Atlas so packets can be transmitted again */ | 
|  | 666 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, | 
|  | 667 | &analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 668 | analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 669 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, | 
|  | 670 | analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 671 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 672 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, | 
|  | 673 | &analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 674 | analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 675 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, | 
|  | 676 | analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 677 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 678 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, | 
|  | 679 | &analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 680 | analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 681 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, | 
|  | 682 | analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 683 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 684 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, | 
|  | 685 | &analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 686 | analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 687 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, | 
|  | 688 | analog_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 689 | } | 
|  | 690 |  | 
|  | 691 | /* Reset PHY */ | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 692 | if (hw->phy.reset_disable == false) { | 
|  | 693 | /* PHY ops must be identified and initialized prior to reset */ | 
|  | 694 |  | 
|  | 695 | /* Init PHY and function pointers, perform SFP setup */ | 
| Don Skidmore | 8ca783a | 2009-05-26 20:40:47 -0700 | [diff] [blame] | 696 | phy_status = hw->phy.ops.init(hw); | 
|  | 697 | if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 698 | goto reset_hw_out; | 
| Don Skidmore | 8ca783a | 2009-05-26 20:40:47 -0700 | [diff] [blame] | 699 | else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) | 
|  | 700 | goto no_phy_reset; | 
|  | 701 |  | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 702 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 703 | hw->phy.ops.reset(hw); | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 704 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 705 |  | 
| Don Skidmore | 8ca783a | 2009-05-26 20:40:47 -0700 | [diff] [blame] | 706 | no_phy_reset: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 707 | /* | 
|  | 708 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 
|  | 709 | * access and verify no pending requests before reset | 
|  | 710 | */ | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 711 | status = ixgbe_disable_pcie_master(hw); | 
|  | 712 | if (status != 0) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 713 | status = IXGBE_ERR_MASTER_REQUESTS_PENDING; | 
|  | 714 | hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); | 
|  | 715 | } | 
|  | 716 |  | 
|  | 717 | /* | 
|  | 718 | * Issue global reset to the MAC.  This needs to be a SW reset. | 
|  | 719 | * If link reset is used, it might reset the MAC when mng is using it | 
|  | 720 | */ | 
|  | 721 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 
|  | 722 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); | 
|  | 723 | IXGBE_WRITE_FLUSH(hw); | 
|  | 724 |  | 
|  | 725 | /* Poll for reset bit to self-clear indicating reset is complete */ | 
|  | 726 | for (i = 0; i < 10; i++) { | 
|  | 727 | udelay(1); | 
|  | 728 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 
|  | 729 | if (!(ctrl & IXGBE_CTRL_RST)) | 
|  | 730 | break; | 
|  | 731 | } | 
|  | 732 | if (ctrl & IXGBE_CTRL_RST) { | 
|  | 733 | status = IXGBE_ERR_RESET_FAILED; | 
|  | 734 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 
|  | 735 | } | 
|  | 736 |  | 
|  | 737 | msleep(50); | 
|  | 738 |  | 
|  | 739 | gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); | 
|  | 740 | gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6)); | 
|  | 741 | IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); | 
|  | 742 |  | 
|  | 743 | /* | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 744 | * Store the original AUTOC value if it has not been | 
|  | 745 | * stored off yet.  Otherwise restore the stored original | 
|  | 746 | * AUTOC value since the reset operation sets back to deaults. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 747 | */ | 
|  | 748 | autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
| Peter P Waskiewicz Jr | 3201d31 | 2009-02-05 23:54:21 -0800 | [diff] [blame] | 749 | if (hw->mac.orig_link_settings_stored == false) { | 
|  | 750 | hw->mac.orig_autoc = autoc; | 
|  | 751 | hw->mac.orig_link_settings_stored = true; | 
|  | 752 | } else if (autoc != hw->mac.orig_autoc) { | 
|  | 753 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 754 | } | 
|  | 755 |  | 
| Waskiewicz Jr, Peter P | aca6bee | 2009-05-17 12:32:48 +0000 | [diff] [blame] | 756 | /* | 
|  | 757 | * Store MAC address from RAR0, clear receive address registers, and | 
|  | 758 | * clear the multicast table | 
|  | 759 | */ | 
|  | 760 | hw->mac.ops.init_rx_addrs(hw); | 
|  | 761 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 762 | /* Store the permanent mac address */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 763 | hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 764 |  | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 765 | reset_hw_out: | 
| Don Skidmore | 8ca783a | 2009-05-26 20:40:47 -0700 | [diff] [blame] | 766 | if (phy_status) | 
|  | 767 | status = phy_status; | 
|  | 768 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 769 | return status; | 
|  | 770 | } | 
|  | 771 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 772 | /** | 
|  | 773 | *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address | 
|  | 774 | *  @hw: pointer to hardware struct | 
|  | 775 | *  @rar: receive address register index to associate with a VMDq index | 
|  | 776 | *  @vmdq: VMDq set index | 
|  | 777 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 778 | static s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 779 | { | 
|  | 780 | u32 rar_high; | 
|  | 781 |  | 
|  | 782 | rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); | 
|  | 783 | rar_high &= ~IXGBE_RAH_VIND_MASK; | 
|  | 784 | rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK); | 
|  | 785 | IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); | 
|  | 786 | return 0; | 
|  | 787 | } | 
|  | 788 |  | 
|  | 789 | /** | 
|  | 790 | *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address | 
|  | 791 | *  @hw: pointer to hardware struct | 
|  | 792 | *  @rar: receive address register index to associate with a VMDq index | 
|  | 793 | *  @vmdq: VMDq clear index (not used in 82598, but elsewhere) | 
|  | 794 | **/ | 
|  | 795 | static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
|  | 796 | { | 
|  | 797 | u32 rar_high; | 
|  | 798 | u32 rar_entries = hw->mac.num_rar_entries; | 
|  | 799 |  | 
|  | 800 | if (rar < rar_entries) { | 
|  | 801 | rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); | 
|  | 802 | if (rar_high & IXGBE_RAH_VIND_MASK) { | 
|  | 803 | rar_high &= ~IXGBE_RAH_VIND_MASK; | 
|  | 804 | IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); | 
|  | 805 | } | 
|  | 806 | } else { | 
|  | 807 | hw_dbg(hw, "RAR index %d is out of range.\n", rar); | 
|  | 808 | } | 
|  | 809 |  | 
|  | 810 | return 0; | 
|  | 811 | } | 
|  | 812 |  | 
|  | 813 | /** | 
|  | 814 | *  ixgbe_set_vfta_82598 - Set VLAN filter table | 
|  | 815 | *  @hw: pointer to hardware structure | 
|  | 816 | *  @vlan: VLAN id to write to VLAN filter | 
|  | 817 | *  @vind: VMDq output index that maps queue to VLAN id in VFTA | 
|  | 818 | *  @vlan_on: boolean flag to turn on/off VLAN in VFTA | 
|  | 819 | * | 
|  | 820 | *  Turn on/off specified VLAN in the VLAN filter table. | 
|  | 821 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 822 | static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, | 
|  | 823 | bool vlan_on) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 824 | { | 
|  | 825 | u32 regindex; | 
|  | 826 | u32 bitindex; | 
|  | 827 | u32 bits; | 
|  | 828 | u32 vftabyte; | 
|  | 829 |  | 
|  | 830 | if (vlan > 4095) | 
|  | 831 | return IXGBE_ERR_PARAM; | 
|  | 832 |  | 
|  | 833 | /* Determine 32-bit word position in array */ | 
|  | 834 | regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */ | 
|  | 835 |  | 
|  | 836 | /* Determine the location of the (VMD) queue index */ | 
|  | 837 | vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ | 
|  | 838 | bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */ | 
|  | 839 |  | 
|  | 840 | /* Set the nibble for VMD queue index */ | 
|  | 841 | bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex)); | 
|  | 842 | bits &= (~(0x0F << bitindex)); | 
|  | 843 | bits |= (vind << bitindex); | 
|  | 844 | IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits); | 
|  | 845 |  | 
|  | 846 | /* Determine the location of the bit for this VLAN id */ | 
|  | 847 | bitindex = vlan & 0x1F;   /* lower five bits */ | 
|  | 848 |  | 
|  | 849 | bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); | 
|  | 850 | if (vlan_on) | 
|  | 851 | /* Turn on this VLAN id */ | 
|  | 852 | bits |= (1 << bitindex); | 
|  | 853 | else | 
|  | 854 | /* Turn off this VLAN id */ | 
|  | 855 | bits &= ~(1 << bitindex); | 
|  | 856 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); | 
|  | 857 |  | 
|  | 858 | return 0; | 
|  | 859 | } | 
|  | 860 |  | 
|  | 861 | /** | 
|  | 862 | *  ixgbe_clear_vfta_82598 - Clear VLAN filter table | 
|  | 863 | *  @hw: pointer to hardware structure | 
|  | 864 | * | 
|  | 865 | *  Clears the VLAN filer table, and the VMDq index associated with the filter | 
|  | 866 | **/ | 
|  | 867 | static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) | 
|  | 868 | { | 
|  | 869 | u32 offset; | 
|  | 870 | u32 vlanbyte; | 
|  | 871 |  | 
|  | 872 | for (offset = 0; offset < hw->mac.vft_size; offset++) | 
|  | 873 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | 
|  | 874 |  | 
|  | 875 | for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) | 
|  | 876 | for (offset = 0; offset < hw->mac.vft_size; offset++) | 
|  | 877 | IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 878 | 0); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 879 |  | 
|  | 880 | return 0; | 
|  | 881 | } | 
|  | 882 |  | 
|  | 883 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 884 | *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register | 
|  | 885 | *  @hw: pointer to hardware structure | 
|  | 886 | *  @reg: analog register to read | 
|  | 887 | *  @val: read value | 
|  | 888 | * | 
|  | 889 | *  Performs read operation to Atlas analog register specified. | 
|  | 890 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 891 | static s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 892 | { | 
|  | 893 | u32  atlas_ctl; | 
|  | 894 |  | 
|  | 895 | IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, | 
|  | 896 | IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); | 
|  | 897 | IXGBE_WRITE_FLUSH(hw); | 
|  | 898 | udelay(10); | 
|  | 899 | atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL); | 
|  | 900 | *val = (u8)atlas_ctl; | 
|  | 901 |  | 
|  | 902 | return 0; | 
|  | 903 | } | 
|  | 904 |  | 
|  | 905 | /** | 
|  | 906 | *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register | 
|  | 907 | *  @hw: pointer to hardware structure | 
|  | 908 | *  @reg: atlas register to write | 
|  | 909 | *  @val: value to write | 
|  | 910 | * | 
|  | 911 | *  Performs write operation to Atlas analog register specified. | 
|  | 912 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 913 | static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 914 | { | 
|  | 915 | u32  atlas_ctl; | 
|  | 916 |  | 
|  | 917 | atlas_ctl = (reg << 8) | val; | 
|  | 918 | IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); | 
|  | 919 | IXGBE_WRITE_FLUSH(hw); | 
|  | 920 | udelay(10); | 
|  | 921 |  | 
|  | 922 | return 0; | 
|  | 923 | } | 
|  | 924 |  | 
|  | 925 | /** | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 926 | *  ixgbe_read_i2c_eeprom_82598 - Read 8 bit EEPROM word of an SFP+ module | 
|  | 927 | *  over I2C interface through an intermediate phy. | 
|  | 928 | *  @hw: pointer to hardware structure | 
|  | 929 | *  @byte_offset: EEPROM byte offset to read | 
|  | 930 | *  @eeprom_data: value read | 
|  | 931 | * | 
|  | 932 | *  Performs byte read operation to SFP module's EEPROM over I2C interface. | 
|  | 933 | **/ | 
| Hannes Eder | e855aac | 2008-12-26 00:03:59 -0800 | [diff] [blame] | 934 | static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, | 
|  | 935 | u8 *eeprom_data) | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 936 | { | 
|  | 937 | s32 status = 0; | 
|  | 938 | u16 sfp_addr = 0; | 
|  | 939 | u16 sfp_data = 0; | 
|  | 940 | u16 sfp_stat = 0; | 
|  | 941 | u32 i; | 
|  | 942 |  | 
|  | 943 | if (hw->phy.type == ixgbe_phy_nl) { | 
|  | 944 | /* | 
|  | 945 | * phy SDA/SCL registers are at addresses 0xC30A to | 
|  | 946 | * 0xC30D.  These registers are used to talk to the SFP+ | 
|  | 947 | * module's EEPROM through the SDA/SCL (I2C) interface. | 
|  | 948 | */ | 
|  | 949 | sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset; | 
|  | 950 | sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); | 
|  | 951 | hw->phy.ops.write_reg(hw, | 
|  | 952 | IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 953 | MDIO_MMD_PMAPMD, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 954 | sfp_addr); | 
|  | 955 |  | 
|  | 956 | /* Poll status */ | 
|  | 957 | for (i = 0; i < 100; i++) { | 
|  | 958 | hw->phy.ops.read_reg(hw, | 
|  | 959 | IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 960 | MDIO_MMD_PMAPMD, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 961 | &sfp_stat); | 
|  | 962 | sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; | 
|  | 963 | if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) | 
|  | 964 | break; | 
|  | 965 | msleep(10); | 
|  | 966 | } | 
|  | 967 |  | 
|  | 968 | if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { | 
|  | 969 | hw_dbg(hw, "EEPROM read did not pass.\n"); | 
|  | 970 | status = IXGBE_ERR_SFP_NOT_PRESENT; | 
|  | 971 | goto out; | 
|  | 972 | } | 
|  | 973 |  | 
|  | 974 | /* Read data */ | 
|  | 975 | hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 976 | MDIO_MMD_PMAPMD, &sfp_data); | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 977 |  | 
|  | 978 | *eeprom_data = (u8)(sfp_data >> 8); | 
|  | 979 | } else { | 
|  | 980 | status = IXGBE_ERR_PHY; | 
|  | 981 | goto out; | 
|  | 982 | } | 
|  | 983 |  | 
|  | 984 | out: | 
|  | 985 | return status; | 
|  | 986 | } | 
|  | 987 |  | 
|  | 988 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 989 | *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type | 
|  | 990 | *  @hw: pointer to hardware structure | 
|  | 991 | * | 
|  | 992 | *  Determines physical layer capabilities of the current configuration. | 
|  | 993 | **/ | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 994 | static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 995 | { | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 996 | u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 997 | u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 998 | u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; | 
|  | 999 | u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; | 
|  | 1000 | u16 ext_ability = 0; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1001 |  | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1002 | hw->phy.ops.identify(hw); | 
|  | 1003 |  | 
|  | 1004 | /* Copper PHY must be checked before AUTOC LMS to determine correct | 
|  | 1005 | * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ | 
|  | 1006 | if (hw->phy.type == ixgbe_phy_tn || | 
|  | 1007 | hw->phy.type == ixgbe_phy_cu_unknown) { | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 1008 | hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, | 
|  | 1009 | &ext_ability); | 
|  | 1010 | if (ext_ability & MDIO_PMA_EXTABLE_10GBT) | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1011 | physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 1012 | if (ext_ability & MDIO_PMA_EXTABLE_1000BT) | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1013 | physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; | 
| Ben Hutchings | 6b73e10 | 2009-04-29 08:08:58 +0000 | [diff] [blame] | 1014 | if (ext_ability & MDIO_PMA_EXTABLE_100BTX) | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1015 | physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; | 
|  | 1016 | goto out; | 
|  | 1017 | } | 
|  | 1018 |  | 
|  | 1019 | switch (autoc & IXGBE_AUTOC_LMS_MASK) { | 
|  | 1020 | case IXGBE_AUTOC_LMS_1G_AN: | 
|  | 1021 | case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: | 
|  | 1022 | if (pma_pmd_1g == IXGBE_AUTOC_1G_KX) | 
|  | 1023 | physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; | 
|  | 1024 | else | 
|  | 1025 | physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; | 
| Don Skidmore | 1e336d0 | 2009-01-26 20:57:51 -0800 | [diff] [blame] | 1026 | break; | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1027 | case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: | 
|  | 1028 | if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4) | 
|  | 1029 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; | 
|  | 1030 | else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4) | 
|  | 1031 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; | 
|  | 1032 | else /* XAUI */ | 
|  | 1033 | physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1034 | break; | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1035 | case IXGBE_AUTOC_LMS_KX4_AN: | 
|  | 1036 | case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: | 
|  | 1037 | if (autoc & IXGBE_AUTOC_KX_SUPP) | 
|  | 1038 | physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; | 
|  | 1039 | if (autoc & IXGBE_AUTOC_KX4_SUPP) | 
|  | 1040 | physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 1041 | break; | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1042 | default: | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1043 | break; | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1044 | } | 
|  | 1045 |  | 
|  | 1046 | if (hw->phy.type == ixgbe_phy_nl) { | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 1047 | hw->phy.ops.identify_sfp(hw); | 
|  | 1048 |  | 
|  | 1049 | switch (hw->phy.sfp_type) { | 
|  | 1050 | case ixgbe_sfp_type_da_cu: | 
|  | 1051 | physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; | 
|  | 1052 | break; | 
|  | 1053 | case ixgbe_sfp_type_sr: | 
|  | 1054 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; | 
|  | 1055 | break; | 
|  | 1056 | case ixgbe_sfp_type_lr: | 
|  | 1057 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; | 
|  | 1058 | break; | 
|  | 1059 | default: | 
|  | 1060 | physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
|  | 1061 | break; | 
|  | 1062 | } | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1063 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1064 |  | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1065 | switch (hw->device_id) { | 
|  | 1066 | case IXGBE_DEV_ID_82598_DA_DUAL_PORT: | 
|  | 1067 | physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; | 
|  | 1068 | break; | 
|  | 1069 | case IXGBE_DEV_ID_82598AF_DUAL_PORT: | 
|  | 1070 | case IXGBE_DEV_ID_82598AF_SINGLE_PORT: | 
|  | 1071 | case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: | 
|  | 1072 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; | 
|  | 1073 | break; | 
|  | 1074 | case IXGBE_DEV_ID_82598EB_XF_LR: | 
|  | 1075 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; | 
|  | 1076 | break; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1077 | default: | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1078 | break; | 
|  | 1079 | } | 
|  | 1080 |  | 
| Peter P Waskiewicz Jr | 0419305 | 2009-04-09 22:28:50 +0000 | [diff] [blame] | 1081 | out: | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1082 | return physical_layer; | 
|  | 1083 | } | 
|  | 1084 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1085 | static struct ixgbe_mac_operations mac_ops_82598 = { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1086 | .init_hw		= &ixgbe_init_hw_generic, | 
|  | 1087 | .reset_hw		= &ixgbe_reset_hw_82598, | 
|  | 1088 | .start_hw		= &ixgbe_start_hw_generic, | 
|  | 1089 | .clear_hw_cntrs		= &ixgbe_clear_hw_cntrs_generic, | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1090 | .get_media_type		= &ixgbe_get_media_type_82598, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1091 | .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598, | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1092 | .enable_rx_dma          = &ixgbe_enable_rx_dma_generic, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1093 | .get_mac_addr		= &ixgbe_get_mac_addr_generic, | 
|  | 1094 | .stop_adapter		= &ixgbe_stop_adapter_generic, | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1095 | .get_bus_info           = &ixgbe_get_bus_info_generic, | 
|  | 1096 | .set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1097 | .read_analog_reg8	= &ixgbe_read_analog_reg8_82598, | 
|  | 1098 | .write_analog_reg8	= &ixgbe_write_analog_reg8_82598, | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 1099 | .setup_link		= &ixgbe_setup_mac_link_82598, | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 1100 | .setup_link_speed	= &ixgbe_setup_mac_link_speed_82598, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1101 | .check_link		= &ixgbe_check_mac_link_82598, | 
|  | 1102 | .get_link_capabilities	= &ixgbe_get_link_capabilities_82598, | 
|  | 1103 | .led_on			= &ixgbe_led_on_generic, | 
|  | 1104 | .led_off		= &ixgbe_led_off_generic, | 
| PJ Waskiewicz | 87c1201 | 2009-04-08 13:20:31 +0000 | [diff] [blame] | 1105 | .blink_led_start	= &ixgbe_blink_led_start_generic, | 
|  | 1106 | .blink_led_stop		= &ixgbe_blink_led_stop_generic, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1107 | .set_rar		= &ixgbe_set_rar_generic, | 
|  | 1108 | .clear_rar		= &ixgbe_clear_rar_generic, | 
|  | 1109 | .set_vmdq		= &ixgbe_set_vmdq_82598, | 
|  | 1110 | .clear_vmdq		= &ixgbe_clear_vmdq_82598, | 
|  | 1111 | .init_rx_addrs		= &ixgbe_init_rx_addrs_generic, | 
|  | 1112 | .update_uc_addr_list	= &ixgbe_update_uc_addr_list_generic, | 
|  | 1113 | .update_mc_addr_list	= &ixgbe_update_mc_addr_list_generic, | 
|  | 1114 | .enable_mc		= &ixgbe_enable_mc_generic, | 
|  | 1115 | .disable_mc		= &ixgbe_disable_mc_generic, | 
|  | 1116 | .clear_vfta		= &ixgbe_clear_vfta_82598, | 
|  | 1117 | .set_vfta		= &ixgbe_set_vfta_82598, | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1118 | .fc_enable		= &ixgbe_fc_enable_82598, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1119 | }; | 
|  | 1120 |  | 
|  | 1121 | static struct ixgbe_eeprom_operations eeprom_ops_82598 = { | 
|  | 1122 | .init_params		= &ixgbe_init_eeprom_params_generic, | 
|  | 1123 | .read			= &ixgbe_read_eeprom_generic, | 
|  | 1124 | .validate_checksum	= &ixgbe_validate_eeprom_checksum_generic, | 
|  | 1125 | .update_checksum	= &ixgbe_update_eeprom_checksum_generic, | 
|  | 1126 | }; | 
|  | 1127 |  | 
|  | 1128 | static struct ixgbe_phy_operations phy_ops_82598 = { | 
|  | 1129 | .identify		= &ixgbe_identify_phy_generic, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 1130 | .identify_sfp		= &ixgbe_identify_sfp_module_generic, | 
| PJ Waskiewicz | 04f165e | 2009-04-09 22:27:57 +0000 | [diff] [blame] | 1131 | .init			= &ixgbe_init_phy_ops_82598, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1132 | .reset			= &ixgbe_reset_phy_generic, | 
|  | 1133 | .read_reg		= &ixgbe_read_phy_reg_generic, | 
|  | 1134 | .write_reg		= &ixgbe_write_phy_reg_generic, | 
|  | 1135 | .setup_link		= &ixgbe_setup_phy_link_generic, | 
|  | 1136 | .setup_link_speed	= &ixgbe_setup_phy_link_speed_generic, | 
| Donald Skidmore | c4900be | 2008-11-20 21:11:42 -0800 | [diff] [blame] | 1137 | .read_i2c_eeprom	= &ixgbe_read_i2c_eeprom_82598, | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1138 | }; | 
|  | 1139 |  | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 1140 | struct ixgbe_info ixgbe_82598_info = { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1141 | .mac			= ixgbe_mac_82598EB, | 
|  | 1142 | .get_invariants		= &ixgbe_get_invariants_82598, | 
|  | 1143 | .mac_ops		= &mac_ops_82598, | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1144 | .eeprom_ops		= &eeprom_ops_82598, | 
|  | 1145 | .phy_ops		= &phy_ops_82598, | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1146 | }; | 
|  | 1147 |  |