| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1 | /******************************************************************************* | 
|  | 2 |  | 
|  | 3 | Intel 10 Gigabit PCI Express Linux driver | 
| Don Skidmore | a52055e | 2011-02-23 09:58:39 +0000 | [diff] [blame] | 4 | Copyright(c) 1999 - 2011 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> | 
| Jiri Pirko | ccffad2 | 2009-05-22 23:22:17 +0000 | [diff] [blame] | 31 | #include <linux/netdevice.h> | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 32 |  | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 33 | #include "ixgbe.h" | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 34 | #include "ixgbe_common.h" | 
|  | 35 | #include "ixgbe_phy.h" | 
|  | 36 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 37 | static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 38 | static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); | 
|  | 39 | static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 40 | static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); | 
|  | 41 | static void ixgbe_standby_eeprom(struct ixgbe_hw *hw); | 
|  | 42 | static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, | 
|  | 43 | u16 count); | 
|  | 44 | static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); | 
|  | 45 | static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); | 
|  | 46 | static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); | 
|  | 47 | static void ixgbe_release_eeprom(struct ixgbe_hw *hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 48 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 49 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 50 | static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw); | 
|  | 51 | static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw); | 
|  | 52 | static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw); | 
|  | 53 | static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); | 
|  | 54 | static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, | 
|  | 55 | u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); | 
| Don Skidmore | 7b25cdb | 2009-08-25 04:47:32 +0000 | [diff] [blame] | 56 | static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 57 |  | 
|  | 58 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 59 | *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 60 | *  @hw: pointer to hardware structure | 
|  | 61 | * | 
|  | 62 | *  Starts the hardware by filling the bus info structure and media type, clears | 
|  | 63 | *  all on chip counters, initializes receive address registers, multicast | 
|  | 64 | *  table, VLAN filter table, calls routine to set up link and flow control | 
|  | 65 | *  settings, and leaves transmit and receive units disabled and uninitialized | 
|  | 66 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 67 | s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 68 | { | 
|  | 69 | u32 ctrl_ext; | 
|  | 70 |  | 
|  | 71 | /* Set the media type */ | 
|  | 72 | hw->phy.media_type = hw->mac.ops.get_media_type(hw); | 
|  | 73 |  | 
|  | 74 | /* Identify the PHY */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 75 | hw->phy.ops.identify(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 76 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 77 | /* Clear the VLAN filter table */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 78 | hw->mac.ops.clear_vfta(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 79 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 80 | /* Clear statistics registers */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 81 | hw->mac.ops.clear_hw_cntrs(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 82 |  | 
|  | 83 | /* Set No Snoop Disable */ | 
|  | 84 | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); | 
|  | 85 | ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; | 
|  | 86 | IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 87 | IXGBE_WRITE_FLUSH(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 88 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 89 | /* Setup flow control */ | 
|  | 90 | ixgbe_setup_fc(hw, 0); | 
|  | 91 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 92 | /* Clear adapter stopped flag */ | 
|  | 93 | hw->adapter_stopped = false; | 
|  | 94 |  | 
|  | 95 | return 0; | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 99 | *  ixgbe_init_hw_generic - Generic hardware initialization | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 100 | *  @hw: pointer to hardware structure | 
|  | 101 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 102 | *  Initialize the hardware by resetting the hardware, filling the bus info | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 103 | *  structure and media type, clears all on chip counters, initializes receive | 
|  | 104 | *  address registers, multicast table, VLAN filter table, calls routine to set | 
|  | 105 | *  up link and flow control settings, and leaves transmit and receive units | 
|  | 106 | *  disabled and uninitialized | 
|  | 107 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 108 | s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 109 | { | 
| Peter P Waskiewicz Jr | 794caeb | 2009-06-04 16:02:24 +0000 | [diff] [blame] | 110 | s32 status; | 
|  | 111 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 112 | /* Reset the hardware */ | 
| Peter P Waskiewicz Jr | 794caeb | 2009-06-04 16:02:24 +0000 | [diff] [blame] | 113 | status = hw->mac.ops.reset_hw(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 114 |  | 
| Peter P Waskiewicz Jr | 794caeb | 2009-06-04 16:02:24 +0000 | [diff] [blame] | 115 | if (status == 0) { | 
|  | 116 | /* Start the HW */ | 
|  | 117 | status = hw->mac.ops.start_hw(hw); | 
|  | 118 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 119 |  | 
| Peter P Waskiewicz Jr | 794caeb | 2009-06-04 16:02:24 +0000 | [diff] [blame] | 120 | return status; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 121 | } | 
|  | 122 |  | 
|  | 123 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 124 | *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 125 | *  @hw: pointer to hardware structure | 
|  | 126 | * | 
|  | 127 | *  Clears all hardware statistics counters by reading them from the hardware | 
|  | 128 | *  Statistics counters are clear on read. | 
|  | 129 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 130 | s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 131 | { | 
|  | 132 | u16 i = 0; | 
|  | 133 |  | 
|  | 134 | IXGBE_READ_REG(hw, IXGBE_CRCERRS); | 
|  | 135 | IXGBE_READ_REG(hw, IXGBE_ILLERRC); | 
|  | 136 | IXGBE_READ_REG(hw, IXGBE_ERRBC); | 
|  | 137 | IXGBE_READ_REG(hw, IXGBE_MSPDC); | 
|  | 138 | for (i = 0; i < 8; i++) | 
|  | 139 | IXGBE_READ_REG(hw, IXGBE_MPC(i)); | 
|  | 140 |  | 
|  | 141 | IXGBE_READ_REG(hw, IXGBE_MLFC); | 
|  | 142 | IXGBE_READ_REG(hw, IXGBE_MRFC); | 
|  | 143 | IXGBE_READ_REG(hw, IXGBE_RLEC); | 
|  | 144 | IXGBE_READ_REG(hw, IXGBE_LXONTXC); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 145 | IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); | 
| Emil Tantilov | 667c756 | 2011-02-26 06:40:05 +0000 | [diff] [blame] | 146 | if (hw->mac.type >= ixgbe_mac_82599EB) { | 
|  | 147 | IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); | 
|  | 148 | IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); | 
|  | 149 | } else { | 
|  | 150 | IXGBE_READ_REG(hw, IXGBE_LXONRXC); | 
|  | 151 | IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); | 
|  | 152 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 153 |  | 
|  | 154 | for (i = 0; i < 8; i++) { | 
|  | 155 | IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 156 | IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); | 
| Emil Tantilov | 667c756 | 2011-02-26 06:40:05 +0000 | [diff] [blame] | 157 | if (hw->mac.type >= ixgbe_mac_82599EB) { | 
|  | 158 | IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); | 
|  | 159 | IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); | 
|  | 160 | } else { | 
|  | 161 | IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); | 
|  | 162 | IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); | 
|  | 163 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 164 | } | 
| Emil Tantilov | 667c756 | 2011-02-26 06:40:05 +0000 | [diff] [blame] | 165 | if (hw->mac.type >= ixgbe_mac_82599EB) | 
|  | 166 | for (i = 0; i < 8; i++) | 
|  | 167 | IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 168 | IXGBE_READ_REG(hw, IXGBE_PRC64); | 
|  | 169 | IXGBE_READ_REG(hw, IXGBE_PRC127); | 
|  | 170 | IXGBE_READ_REG(hw, IXGBE_PRC255); | 
|  | 171 | IXGBE_READ_REG(hw, IXGBE_PRC511); | 
|  | 172 | IXGBE_READ_REG(hw, IXGBE_PRC1023); | 
|  | 173 | IXGBE_READ_REG(hw, IXGBE_PRC1522); | 
|  | 174 | IXGBE_READ_REG(hw, IXGBE_GPRC); | 
|  | 175 | IXGBE_READ_REG(hw, IXGBE_BPRC); | 
|  | 176 | IXGBE_READ_REG(hw, IXGBE_MPRC); | 
|  | 177 | IXGBE_READ_REG(hw, IXGBE_GPTC); | 
|  | 178 | IXGBE_READ_REG(hw, IXGBE_GORCL); | 
|  | 179 | IXGBE_READ_REG(hw, IXGBE_GORCH); | 
|  | 180 | IXGBE_READ_REG(hw, IXGBE_GOTCL); | 
|  | 181 | IXGBE_READ_REG(hw, IXGBE_GOTCH); | 
|  | 182 | for (i = 0; i < 8; i++) | 
|  | 183 | IXGBE_READ_REG(hw, IXGBE_RNBC(i)); | 
|  | 184 | IXGBE_READ_REG(hw, IXGBE_RUC); | 
|  | 185 | IXGBE_READ_REG(hw, IXGBE_RFC); | 
|  | 186 | IXGBE_READ_REG(hw, IXGBE_ROC); | 
|  | 187 | IXGBE_READ_REG(hw, IXGBE_RJC); | 
|  | 188 | IXGBE_READ_REG(hw, IXGBE_MNGPRC); | 
|  | 189 | IXGBE_READ_REG(hw, IXGBE_MNGPDC); | 
|  | 190 | IXGBE_READ_REG(hw, IXGBE_MNGPTC); | 
|  | 191 | IXGBE_READ_REG(hw, IXGBE_TORL); | 
|  | 192 | IXGBE_READ_REG(hw, IXGBE_TORH); | 
|  | 193 | IXGBE_READ_REG(hw, IXGBE_TPR); | 
|  | 194 | IXGBE_READ_REG(hw, IXGBE_TPT); | 
|  | 195 | IXGBE_READ_REG(hw, IXGBE_PTC64); | 
|  | 196 | IXGBE_READ_REG(hw, IXGBE_PTC127); | 
|  | 197 | IXGBE_READ_REG(hw, IXGBE_PTC255); | 
|  | 198 | IXGBE_READ_REG(hw, IXGBE_PTC511); | 
|  | 199 | IXGBE_READ_REG(hw, IXGBE_PTC1023); | 
|  | 200 | IXGBE_READ_REG(hw, IXGBE_PTC1522); | 
|  | 201 | IXGBE_READ_REG(hw, IXGBE_MPTC); | 
|  | 202 | IXGBE_READ_REG(hw, IXGBE_BPTC); | 
|  | 203 | for (i = 0; i < 16; i++) { | 
|  | 204 | IXGBE_READ_REG(hw, IXGBE_QPRC(i)); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 205 | IXGBE_READ_REG(hw, IXGBE_QPTC(i)); | 
| Emil Tantilov | 667c756 | 2011-02-26 06:40:05 +0000 | [diff] [blame] | 206 | if (hw->mac.type >= ixgbe_mac_82599EB) { | 
|  | 207 | IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); | 
|  | 208 | IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); | 
|  | 209 | IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); | 
|  | 210 | IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); | 
|  | 211 | IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); | 
|  | 212 | } else { | 
|  | 213 | IXGBE_READ_REG(hw, IXGBE_QBRC(i)); | 
|  | 214 | IXGBE_READ_REG(hw, IXGBE_QBTC(i)); | 
|  | 215 | } | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 216 | } | 
|  | 217 |  | 
| Emil Tantilov | a3aeea0 | 2011-02-26 06:40:11 +0000 | [diff] [blame] | 218 | if (hw->mac.type == ixgbe_mac_X540) { | 
|  | 219 | if (hw->phy.id == 0) | 
|  | 220 | hw->phy.ops.identify(hw); | 
|  | 221 | hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECL, &i); | 
|  | 222 | hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECH, &i); | 
|  | 223 | hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECL, &i); | 
|  | 224 | hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECH, &i); | 
|  | 225 | } | 
|  | 226 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 227 | return 0; | 
|  | 228 | } | 
|  | 229 |  | 
|  | 230 | /** | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 231 | *  ixgbe_read_pba_string_generic - Reads part number string from EEPROM | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 232 | *  @hw: pointer to hardware structure | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 233 | *  @pba_num: stores the part number string from the EEPROM | 
|  | 234 | *  @pba_num_size: part number string buffer length | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 235 | * | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 236 | *  Reads the part number string from the EEPROM. | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 237 | **/ | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 238 | s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, | 
|  | 239 | u32 pba_num_size) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 240 | { | 
|  | 241 | s32 ret_val; | 
|  | 242 | u16 data; | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 243 | u16 pba_ptr; | 
|  | 244 | u16 offset; | 
|  | 245 | u16 length; | 
|  | 246 |  | 
|  | 247 | if (pba_num == NULL) { | 
|  | 248 | hw_dbg(hw, "PBA string buffer was null\n"); | 
|  | 249 | return IXGBE_ERR_INVALID_ARGUMENT; | 
|  | 250 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 251 |  | 
|  | 252 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); | 
|  | 253 | if (ret_val) { | 
|  | 254 | hw_dbg(hw, "NVM Read Error\n"); | 
|  | 255 | return ret_val; | 
|  | 256 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 257 |  | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 258 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 259 | if (ret_val) { | 
|  | 260 | hw_dbg(hw, "NVM Read Error\n"); | 
|  | 261 | return ret_val; | 
|  | 262 | } | 
| Don Skidmore | 289700d | 2010-12-03 03:32:58 +0000 | [diff] [blame] | 263 |  | 
|  | 264 | /* | 
|  | 265 | * if data is not ptr guard the PBA must be in legacy format which | 
|  | 266 | * means pba_ptr is actually our second data word for the PBA number | 
|  | 267 | * and we can decode it into an ascii string | 
|  | 268 | */ | 
|  | 269 | if (data != IXGBE_PBANUM_PTR_GUARD) { | 
|  | 270 | hw_dbg(hw, "NVM PBA number is not stored as string\n"); | 
|  | 271 |  | 
|  | 272 | /* we will need 11 characters to store the PBA */ | 
|  | 273 | if (pba_num_size < 11) { | 
|  | 274 | hw_dbg(hw, "PBA string buffer too small\n"); | 
|  | 275 | return IXGBE_ERR_NO_SPACE; | 
|  | 276 | } | 
|  | 277 |  | 
|  | 278 | /* extract hex string from data and pba_ptr */ | 
|  | 279 | pba_num[0] = (data >> 12) & 0xF; | 
|  | 280 | pba_num[1] = (data >> 8) & 0xF; | 
|  | 281 | pba_num[2] = (data >> 4) & 0xF; | 
|  | 282 | pba_num[3] = data & 0xF; | 
|  | 283 | pba_num[4] = (pba_ptr >> 12) & 0xF; | 
|  | 284 | pba_num[5] = (pba_ptr >> 8) & 0xF; | 
|  | 285 | pba_num[6] = '-'; | 
|  | 286 | pba_num[7] = 0; | 
|  | 287 | pba_num[8] = (pba_ptr >> 4) & 0xF; | 
|  | 288 | pba_num[9] = pba_ptr & 0xF; | 
|  | 289 |  | 
|  | 290 | /* put a null character on the end of our string */ | 
|  | 291 | pba_num[10] = '\0'; | 
|  | 292 |  | 
|  | 293 | /* switch all the data but the '-' to hex char */ | 
|  | 294 | for (offset = 0; offset < 10; offset++) { | 
|  | 295 | if (pba_num[offset] < 0xA) | 
|  | 296 | pba_num[offset] += '0'; | 
|  | 297 | else if (pba_num[offset] < 0x10) | 
|  | 298 | pba_num[offset] += 'A' - 0xA; | 
|  | 299 | } | 
|  | 300 |  | 
|  | 301 | return 0; | 
|  | 302 | } | 
|  | 303 |  | 
|  | 304 | ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); | 
|  | 305 | if (ret_val) { | 
|  | 306 | hw_dbg(hw, "NVM Read Error\n"); | 
|  | 307 | return ret_val; | 
|  | 308 | } | 
|  | 309 |  | 
|  | 310 | if (length == 0xFFFF || length == 0) { | 
|  | 311 | hw_dbg(hw, "NVM PBA number section invalid length\n"); | 
|  | 312 | return IXGBE_ERR_PBA_SECTION; | 
|  | 313 | } | 
|  | 314 |  | 
|  | 315 | /* check if pba_num buffer is big enough */ | 
|  | 316 | if (pba_num_size  < (((u32)length * 2) - 1)) { | 
|  | 317 | hw_dbg(hw, "PBA string buffer too small\n"); | 
|  | 318 | return IXGBE_ERR_NO_SPACE; | 
|  | 319 | } | 
|  | 320 |  | 
|  | 321 | /* trim pba length from start of string */ | 
|  | 322 | pba_ptr++; | 
|  | 323 | length--; | 
|  | 324 |  | 
|  | 325 | for (offset = 0; offset < length; offset++) { | 
|  | 326 | ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); | 
|  | 327 | if (ret_val) { | 
|  | 328 | hw_dbg(hw, "NVM Read Error\n"); | 
|  | 329 | return ret_val; | 
|  | 330 | } | 
|  | 331 | pba_num[offset * 2] = (u8)(data >> 8); | 
|  | 332 | pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); | 
|  | 333 | } | 
|  | 334 | pba_num[offset * 2] = '\0'; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 335 |  | 
|  | 336 | return 0; | 
|  | 337 | } | 
|  | 338 |  | 
|  | 339 | /** | 
|  | 340 | *  ixgbe_get_mac_addr_generic - Generic get MAC address | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 341 | *  @hw: pointer to hardware structure | 
|  | 342 | *  @mac_addr: Adapter MAC address | 
|  | 343 | * | 
|  | 344 | *  Reads the adapter's MAC address from first Receive Address Register (RAR0) | 
|  | 345 | *  A reset of the adapter must be performed prior to calling this function | 
|  | 346 | *  in order for the MAC address to have been loaded from the EEPROM into RAR0 | 
|  | 347 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 348 | s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 349 | { | 
|  | 350 | u32 rar_high; | 
|  | 351 | u32 rar_low; | 
|  | 352 | u16 i; | 
|  | 353 |  | 
|  | 354 | rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); | 
|  | 355 | rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); | 
|  | 356 |  | 
|  | 357 | for (i = 0; i < 4; i++) | 
|  | 358 | mac_addr[i] = (u8)(rar_low >> (i*8)); | 
|  | 359 |  | 
|  | 360 | for (i = 0; i < 2; i++) | 
|  | 361 | mac_addr[i+4] = (u8)(rar_high >> (i*8)); | 
|  | 362 |  | 
|  | 363 | return 0; | 
|  | 364 | } | 
|  | 365 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 366 | /** | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 367 | *  ixgbe_get_bus_info_generic - Generic set PCI bus info | 
|  | 368 | *  @hw: pointer to hardware structure | 
|  | 369 | * | 
|  | 370 | *  Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure | 
|  | 371 | **/ | 
|  | 372 | s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) | 
|  | 373 | { | 
|  | 374 | struct ixgbe_adapter *adapter = hw->back; | 
|  | 375 | struct ixgbe_mac_info *mac = &hw->mac; | 
|  | 376 | u16 link_status; | 
|  | 377 |  | 
|  | 378 | hw->bus.type = ixgbe_bus_type_pci_express; | 
|  | 379 |  | 
|  | 380 | /* Get the negotiated link width and speed from PCI config space */ | 
|  | 381 | pci_read_config_word(adapter->pdev, IXGBE_PCI_LINK_STATUS, | 
|  | 382 | &link_status); | 
|  | 383 |  | 
|  | 384 | switch (link_status & IXGBE_PCI_LINK_WIDTH) { | 
|  | 385 | case IXGBE_PCI_LINK_WIDTH_1: | 
|  | 386 | hw->bus.width = ixgbe_bus_width_pcie_x1; | 
|  | 387 | break; | 
|  | 388 | case IXGBE_PCI_LINK_WIDTH_2: | 
|  | 389 | hw->bus.width = ixgbe_bus_width_pcie_x2; | 
|  | 390 | break; | 
|  | 391 | case IXGBE_PCI_LINK_WIDTH_4: | 
|  | 392 | hw->bus.width = ixgbe_bus_width_pcie_x4; | 
|  | 393 | break; | 
|  | 394 | case IXGBE_PCI_LINK_WIDTH_8: | 
|  | 395 | hw->bus.width = ixgbe_bus_width_pcie_x8; | 
|  | 396 | break; | 
|  | 397 | default: | 
|  | 398 | hw->bus.width = ixgbe_bus_width_unknown; | 
|  | 399 | break; | 
|  | 400 | } | 
|  | 401 |  | 
|  | 402 | switch (link_status & IXGBE_PCI_LINK_SPEED) { | 
|  | 403 | case IXGBE_PCI_LINK_SPEED_2500: | 
|  | 404 | hw->bus.speed = ixgbe_bus_speed_2500; | 
|  | 405 | break; | 
|  | 406 | case IXGBE_PCI_LINK_SPEED_5000: | 
|  | 407 | hw->bus.speed = ixgbe_bus_speed_5000; | 
|  | 408 | break; | 
|  | 409 | default: | 
|  | 410 | hw->bus.speed = ixgbe_bus_speed_unknown; | 
|  | 411 | break; | 
|  | 412 | } | 
|  | 413 |  | 
|  | 414 | mac->ops.set_lan_id(hw); | 
|  | 415 |  | 
|  | 416 | return 0; | 
|  | 417 | } | 
|  | 418 |  | 
|  | 419 | /** | 
|  | 420 | *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices | 
|  | 421 | *  @hw: pointer to the HW structure | 
|  | 422 | * | 
|  | 423 | *  Determines the LAN function id by reading memory-mapped registers | 
|  | 424 | *  and swaps the port value if requested. | 
|  | 425 | **/ | 
|  | 426 | void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) | 
|  | 427 | { | 
|  | 428 | struct ixgbe_bus_info *bus = &hw->bus; | 
|  | 429 | u32 reg; | 
|  | 430 |  | 
|  | 431 | reg = IXGBE_READ_REG(hw, IXGBE_STATUS); | 
|  | 432 | bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; | 
|  | 433 | bus->lan_id = bus->func; | 
|  | 434 |  | 
|  | 435 | /* check for a port swap */ | 
|  | 436 | reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); | 
|  | 437 | if (reg & IXGBE_FACTPS_LFS) | 
|  | 438 | bus->func ^= 0x1; | 
|  | 439 | } | 
|  | 440 |  | 
|  | 441 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 442 | *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 443 | *  @hw: pointer to hardware structure | 
|  | 444 | * | 
|  | 445 | *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, | 
|  | 446 | *  disables transmit and receive units. The adapter_stopped flag is used by | 
|  | 447 | *  the shared code and drivers to determine if the adapter is in a stopped | 
|  | 448 | *  state and should not touch the hardware. | 
|  | 449 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 450 | s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 451 | { | 
|  | 452 | u32 number_of_queues; | 
|  | 453 | u32 reg_val; | 
|  | 454 | u16 i; | 
|  | 455 |  | 
|  | 456 | /* | 
|  | 457 | * Set the adapter_stopped flag so other driver functions stop touching | 
|  | 458 | * the hardware | 
|  | 459 | */ | 
|  | 460 | hw->adapter_stopped = true; | 
|  | 461 |  | 
|  | 462 | /* Disable the receive unit */ | 
|  | 463 | reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | 
|  | 464 | reg_val &= ~(IXGBE_RXCTRL_RXEN); | 
|  | 465 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 466 | IXGBE_WRITE_FLUSH(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 467 | msleep(2); | 
|  | 468 |  | 
|  | 469 | /* Clear interrupt mask to stop from interrupts being generated */ | 
|  | 470 | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); | 
|  | 471 |  | 
|  | 472 | /* Clear any pending interrupts */ | 
|  | 473 | IXGBE_READ_REG(hw, IXGBE_EICR); | 
|  | 474 |  | 
|  | 475 | /* Disable the transmit unit.  Each queue must be disabled. */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 476 | number_of_queues = hw->mac.max_tx_queues; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 477 | for (i = 0; i < number_of_queues; i++) { | 
|  | 478 | reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); | 
|  | 479 | if (reg_val & IXGBE_TXDCTL_ENABLE) { | 
|  | 480 | reg_val &= ~IXGBE_TXDCTL_ENABLE; | 
|  | 481 | IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), reg_val); | 
|  | 482 | } | 
|  | 483 | } | 
|  | 484 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 485 | /* | 
|  | 486 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 
|  | 487 | * access and verify no pending requests | 
|  | 488 | */ | 
| Emil Tantilov | a4297dc | 2011-02-14 08:45:13 +0000 | [diff] [blame] | 489 | ixgbe_disable_pcie_master(hw); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 490 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 491 | return 0; | 
|  | 492 | } | 
|  | 493 |  | 
|  | 494 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 495 | *  ixgbe_led_on_generic - Turns on the software controllable LEDs. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 496 | *  @hw: pointer to hardware structure | 
|  | 497 | *  @index: led number to turn on | 
|  | 498 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 499 | s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 500 | { | 
|  | 501 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 
|  | 502 |  | 
|  | 503 | /* To turn on the LED, set mode to ON. */ | 
|  | 504 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | 
|  | 505 | led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); | 
|  | 506 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 507 | IXGBE_WRITE_FLUSH(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 508 |  | 
|  | 509 | return 0; | 
|  | 510 | } | 
|  | 511 |  | 
|  | 512 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 513 | *  ixgbe_led_off_generic - Turns off the software controllable LEDs. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 514 | *  @hw: pointer to hardware structure | 
|  | 515 | *  @index: led number to turn off | 
|  | 516 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 517 | s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 518 | { | 
|  | 519 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 
|  | 520 |  | 
|  | 521 | /* To turn off the LED, set mode to OFF. */ | 
|  | 522 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | 
|  | 523 | led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); | 
|  | 524 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 525 | IXGBE_WRITE_FLUSH(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 526 |  | 
|  | 527 | return 0; | 
|  | 528 | } | 
|  | 529 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 530 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 531 | *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 532 | *  @hw: pointer to hardware structure | 
|  | 533 | * | 
|  | 534 | *  Initializes the EEPROM parameters ixgbe_eeprom_info within the | 
|  | 535 | *  ixgbe_hw struct in order to set up EEPROM access. | 
|  | 536 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 537 | s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 538 | { | 
|  | 539 | struct ixgbe_eeprom_info *eeprom = &hw->eeprom; | 
|  | 540 | u32 eec; | 
|  | 541 | u16 eeprom_size; | 
|  | 542 |  | 
|  | 543 | if (eeprom->type == ixgbe_eeprom_uninitialized) { | 
|  | 544 | eeprom->type = ixgbe_eeprom_none; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 545 | /* Set default semaphore delay to 10ms which is a well | 
|  | 546 | * tested value */ | 
|  | 547 | eeprom->semaphore_delay = 10; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 548 |  | 
|  | 549 | /* | 
|  | 550 | * Check for EEPROM present first. | 
|  | 551 | * If not present leave as none | 
|  | 552 | */ | 
|  | 553 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 554 | if (eec & IXGBE_EEC_PRES) { | 
|  | 555 | eeprom->type = ixgbe_eeprom_spi; | 
|  | 556 |  | 
|  | 557 | /* | 
|  | 558 | * SPI EEPROM is assumed here.  This code would need to | 
|  | 559 | * change if a future EEPROM is not SPI. | 
|  | 560 | */ | 
|  | 561 | eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> | 
|  | 562 | IXGBE_EEC_SIZE_SHIFT); | 
|  | 563 | eeprom->word_size = 1 << (eeprom_size + | 
|  | 564 | IXGBE_EEPROM_WORD_SIZE_SHIFT); | 
|  | 565 | } | 
|  | 566 |  | 
|  | 567 | if (eec & IXGBE_EEC_ADDR_SIZE) | 
|  | 568 | eeprom->address_bits = 16; | 
|  | 569 | else | 
|  | 570 | eeprom->address_bits = 8; | 
|  | 571 | hw_dbg(hw, "Eeprom params: type = %d, size = %d, address bits: " | 
|  | 572 | "%d\n", eeprom->type, eeprom->word_size, | 
|  | 573 | eeprom->address_bits); | 
|  | 574 | } | 
|  | 575 |  | 
|  | 576 | return 0; | 
|  | 577 | } | 
|  | 578 |  | 
|  | 579 | /** | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 580 | *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM | 
|  | 581 | *  @hw: pointer to hardware structure | 
|  | 582 | *  @offset: offset within the EEPROM to be written to | 
|  | 583 | *  @data: 16 bit word to be written to the EEPROM | 
|  | 584 | * | 
|  | 585 | *  If ixgbe_eeprom_update_checksum is not called after this function, the | 
|  | 586 | *  EEPROM will most likely contain an invalid checksum. | 
|  | 587 | **/ | 
|  | 588 | s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) | 
|  | 589 | { | 
|  | 590 | s32 status; | 
|  | 591 | u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; | 
|  | 592 |  | 
|  | 593 | hw->eeprom.ops.init_params(hw); | 
|  | 594 |  | 
|  | 595 | if (offset >= hw->eeprom.word_size) { | 
|  | 596 | status = IXGBE_ERR_EEPROM; | 
|  | 597 | goto out; | 
|  | 598 | } | 
|  | 599 |  | 
|  | 600 | /* Prepare the EEPROM for writing  */ | 
|  | 601 | status = ixgbe_acquire_eeprom(hw); | 
|  | 602 |  | 
|  | 603 | if (status == 0) { | 
|  | 604 | if (ixgbe_ready_eeprom(hw) != 0) { | 
|  | 605 | ixgbe_release_eeprom(hw); | 
|  | 606 | status = IXGBE_ERR_EEPROM; | 
|  | 607 | } | 
|  | 608 | } | 
|  | 609 |  | 
|  | 610 | if (status == 0) { | 
|  | 611 | ixgbe_standby_eeprom(hw); | 
|  | 612 |  | 
|  | 613 | /*  Send the WRITE ENABLE command (8 bit opcode )  */ | 
|  | 614 | ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI, | 
|  | 615 | IXGBE_EEPROM_OPCODE_BITS); | 
|  | 616 |  | 
|  | 617 | ixgbe_standby_eeprom(hw); | 
|  | 618 |  | 
|  | 619 | /* | 
|  | 620 | * Some SPI eeproms use the 8th address bit embedded in the | 
|  | 621 | * opcode | 
|  | 622 | */ | 
|  | 623 | if ((hw->eeprom.address_bits == 8) && (offset >= 128)) | 
|  | 624 | write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; | 
|  | 625 |  | 
|  | 626 | /* Send the Write command (8-bit opcode + addr) */ | 
|  | 627 | ixgbe_shift_out_eeprom_bits(hw, write_opcode, | 
|  | 628 | IXGBE_EEPROM_OPCODE_BITS); | 
|  | 629 | ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), | 
|  | 630 | hw->eeprom.address_bits); | 
|  | 631 |  | 
|  | 632 | /* Send the data */ | 
|  | 633 | data = (data >> 8) | (data << 8); | 
|  | 634 | ixgbe_shift_out_eeprom_bits(hw, data, 16); | 
|  | 635 | ixgbe_standby_eeprom(hw); | 
|  | 636 |  | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 637 | /* Done with writing - release the EEPROM */ | 
|  | 638 | ixgbe_release_eeprom(hw); | 
|  | 639 | } | 
|  | 640 |  | 
|  | 641 | out: | 
|  | 642 | return status; | 
|  | 643 | } | 
|  | 644 |  | 
|  | 645 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 646 | *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang | 
|  | 647 | *  @hw: pointer to hardware structure | 
|  | 648 | *  @offset: offset within the EEPROM to be read | 
|  | 649 | *  @data: read 16 bit value from EEPROM | 
|  | 650 | * | 
|  | 651 | *  Reads 16 bit value from EEPROM through bit-bang method | 
|  | 652 | **/ | 
|  | 653 | s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, | 
|  | 654 | u16 *data) | 
|  | 655 | { | 
|  | 656 | s32 status; | 
|  | 657 | u16 word_in; | 
|  | 658 | u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; | 
|  | 659 |  | 
|  | 660 | hw->eeprom.ops.init_params(hw); | 
|  | 661 |  | 
|  | 662 | if (offset >= hw->eeprom.word_size) { | 
|  | 663 | status = IXGBE_ERR_EEPROM; | 
|  | 664 | goto out; | 
|  | 665 | } | 
|  | 666 |  | 
|  | 667 | /* Prepare the EEPROM for reading  */ | 
|  | 668 | status = ixgbe_acquire_eeprom(hw); | 
|  | 669 |  | 
|  | 670 | if (status == 0) { | 
|  | 671 | if (ixgbe_ready_eeprom(hw) != 0) { | 
|  | 672 | ixgbe_release_eeprom(hw); | 
|  | 673 | status = IXGBE_ERR_EEPROM; | 
|  | 674 | } | 
|  | 675 | } | 
|  | 676 |  | 
|  | 677 | if (status == 0) { | 
|  | 678 | ixgbe_standby_eeprom(hw); | 
|  | 679 |  | 
|  | 680 | /* | 
|  | 681 | * Some SPI eeproms use the 8th address bit embedded in the | 
|  | 682 | * opcode | 
|  | 683 | */ | 
|  | 684 | if ((hw->eeprom.address_bits == 8) && (offset >= 128)) | 
|  | 685 | read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; | 
|  | 686 |  | 
|  | 687 | /* Send the READ command (opcode + addr) */ | 
|  | 688 | ixgbe_shift_out_eeprom_bits(hw, read_opcode, | 
|  | 689 | IXGBE_EEPROM_OPCODE_BITS); | 
|  | 690 | ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), | 
|  | 691 | hw->eeprom.address_bits); | 
|  | 692 |  | 
|  | 693 | /* Read the data. */ | 
|  | 694 | word_in = ixgbe_shift_in_eeprom_bits(hw, 16); | 
|  | 695 | *data = (word_in >> 8) | (word_in << 8); | 
|  | 696 |  | 
|  | 697 | /* End this read operation */ | 
|  | 698 | ixgbe_release_eeprom(hw); | 
|  | 699 | } | 
|  | 700 |  | 
|  | 701 | out: | 
|  | 702 | return status; | 
|  | 703 | } | 
|  | 704 |  | 
|  | 705 | /** | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 706 | *  ixgbe_read_eerd_generic - Read EEPROM word using EERD | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 707 | *  @hw: pointer to hardware structure | 
|  | 708 | *  @offset: offset of  word in the EEPROM to read | 
|  | 709 | *  @data: word read from the EEPROM | 
|  | 710 | * | 
|  | 711 | *  Reads a 16 bit word from the EEPROM using the EERD register. | 
|  | 712 | **/ | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 713 | s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 714 | { | 
|  | 715 | u32 eerd; | 
|  | 716 | s32 status; | 
|  | 717 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 718 | hw->eeprom.ops.init_params(hw); | 
|  | 719 |  | 
|  | 720 | if (offset >= hw->eeprom.word_size) { | 
|  | 721 | status = IXGBE_ERR_EEPROM; | 
|  | 722 | goto out; | 
|  | 723 | } | 
|  | 724 |  | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 725 | eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) + | 
|  | 726 | IXGBE_EEPROM_RW_REG_START; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 727 |  | 
|  | 728 | IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 729 | status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 730 |  | 
|  | 731 | if (status == 0) | 
|  | 732 | *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 733 | IXGBE_EEPROM_RW_REG_DATA); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 734 | else | 
|  | 735 | hw_dbg(hw, "Eeprom read timed out\n"); | 
|  | 736 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 737 | out: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 738 | return status; | 
|  | 739 | } | 
|  | 740 |  | 
|  | 741 | /** | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 742 | *  ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 743 | *  @hw: pointer to hardware structure | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 744 | *  @ee_reg: EEPROM flag for polling | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 745 | * | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 746 | *  Polls the status bit (bit 1) of the EERD or EEWR to determine when the | 
|  | 747 | *  read or write is done respectively. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 748 | **/ | 
| Don Skidmore | a391f1d | 2010-11-16 19:27:15 -0800 | [diff] [blame] | 749 | s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 750 | { | 
|  | 751 | u32 i; | 
|  | 752 | u32 reg; | 
|  | 753 | s32 status = IXGBE_ERR_EEPROM; | 
|  | 754 |  | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 755 | for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { | 
|  | 756 | if (ee_reg == IXGBE_NVM_POLL_READ) | 
|  | 757 | reg = IXGBE_READ_REG(hw, IXGBE_EERD); | 
|  | 758 | else | 
|  | 759 | reg = IXGBE_READ_REG(hw, IXGBE_EEWR); | 
|  | 760 |  | 
|  | 761 | if (reg & IXGBE_EEPROM_RW_REG_DONE) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 762 | status = 0; | 
|  | 763 | break; | 
|  | 764 | } | 
|  | 765 | udelay(5); | 
|  | 766 | } | 
|  | 767 | return status; | 
|  | 768 | } | 
|  | 769 |  | 
|  | 770 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 771 | *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang | 
|  | 772 | *  @hw: pointer to hardware structure | 
|  | 773 | * | 
|  | 774 | *  Prepares EEPROM for access using bit-bang method. This function should | 
|  | 775 | *  be called before issuing a command to the EEPROM. | 
|  | 776 | **/ | 
|  | 777 | static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) | 
|  | 778 | { | 
|  | 779 | s32 status = 0; | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 780 | u32 eec; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 781 | u32 i; | 
|  | 782 |  | 
| Don Skidmore | 5e65510 | 2011-02-25 01:58:04 +0000 | [diff] [blame] | 783 | if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 784 | status = IXGBE_ERR_SWFW_SYNC; | 
|  | 785 |  | 
|  | 786 | if (status == 0) { | 
|  | 787 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 788 |  | 
|  | 789 | /* Request EEPROM Access */ | 
|  | 790 | eec |= IXGBE_EEC_REQ; | 
|  | 791 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 792 |  | 
|  | 793 | for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { | 
|  | 794 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 795 | if (eec & IXGBE_EEC_GNT) | 
|  | 796 | break; | 
|  | 797 | udelay(5); | 
|  | 798 | } | 
|  | 799 |  | 
|  | 800 | /* Release if grant not acquired */ | 
|  | 801 | if (!(eec & IXGBE_EEC_GNT)) { | 
|  | 802 | eec &= ~IXGBE_EEC_REQ; | 
|  | 803 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 804 | hw_dbg(hw, "Could not acquire EEPROM grant\n"); | 
|  | 805 |  | 
| Don Skidmore | 5e65510 | 2011-02-25 01:58:04 +0000 | [diff] [blame] | 806 | hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 807 | status = IXGBE_ERR_EEPROM; | 
|  | 808 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 809 |  | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 810 | /* Setup EEPROM for Read/Write */ | 
|  | 811 | if (status == 0) { | 
|  | 812 | /* Clear CS and SK */ | 
|  | 813 | eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); | 
|  | 814 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 815 | IXGBE_WRITE_FLUSH(hw); | 
|  | 816 | udelay(1); | 
|  | 817 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 818 | } | 
|  | 819 | return status; | 
|  | 820 | } | 
|  | 821 |  | 
|  | 822 | /** | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 823 | *  ixgbe_get_eeprom_semaphore - Get hardware semaphore | 
|  | 824 | *  @hw: pointer to hardware structure | 
|  | 825 | * | 
|  | 826 | *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method | 
|  | 827 | **/ | 
|  | 828 | static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) | 
|  | 829 | { | 
|  | 830 | s32 status = IXGBE_ERR_EEPROM; | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 831 | u32 timeout = 2000; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 832 | u32 i; | 
|  | 833 | u32 swsm; | 
|  | 834 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 835 | /* Get SMBI software semaphore between device drivers first */ | 
|  | 836 | for (i = 0; i < timeout; i++) { | 
|  | 837 | /* | 
|  | 838 | * If the SMBI bit is 0 when we read it, then the bit will be | 
|  | 839 | * set and we have the semaphore | 
|  | 840 | */ | 
|  | 841 | swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | 
|  | 842 | if (!(swsm & IXGBE_SWSM_SMBI)) { | 
|  | 843 | status = 0; | 
|  | 844 | break; | 
|  | 845 | } | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 846 | udelay(50); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 847 | } | 
|  | 848 |  | 
|  | 849 | /* Now get the semaphore between SW/FW through the SWESMBI bit */ | 
|  | 850 | if (status == 0) { | 
|  | 851 | for (i = 0; i < timeout; i++) { | 
|  | 852 | swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | 
|  | 853 |  | 
|  | 854 | /* Set the SW EEPROM semaphore bit to request access */ | 
|  | 855 | swsm |= IXGBE_SWSM_SWESMBI; | 
|  | 856 | IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); | 
|  | 857 |  | 
|  | 858 | /* | 
|  | 859 | * If we set the bit successfully then we got the | 
|  | 860 | * semaphore. | 
|  | 861 | */ | 
|  | 862 | swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | 
|  | 863 | if (swsm & IXGBE_SWSM_SWESMBI) | 
|  | 864 | break; | 
|  | 865 |  | 
|  | 866 | udelay(50); | 
|  | 867 | } | 
|  | 868 |  | 
|  | 869 | /* | 
|  | 870 | * Release semaphores and return error if SW EEPROM semaphore | 
|  | 871 | * was not granted because we don't have access to the EEPROM | 
|  | 872 | */ | 
|  | 873 | if (i >= timeout) { | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 874 | hw_dbg(hw, "SWESMBI Software EEPROM semaphore " | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 875 | "not granted.\n"); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 876 | ixgbe_release_eeprom_semaphore(hw); | 
|  | 877 | status = IXGBE_ERR_EEPROM; | 
|  | 878 | } | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 879 | } else { | 
|  | 880 | hw_dbg(hw, "Software semaphore SMBI between device drivers " | 
|  | 881 | "not granted.\n"); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 882 | } | 
|  | 883 |  | 
|  | 884 | return status; | 
|  | 885 | } | 
|  | 886 |  | 
|  | 887 | /** | 
|  | 888 | *  ixgbe_release_eeprom_semaphore - Release hardware semaphore | 
|  | 889 | *  @hw: pointer to hardware structure | 
|  | 890 | * | 
|  | 891 | *  This function clears hardware semaphore bits. | 
|  | 892 | **/ | 
|  | 893 | static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) | 
|  | 894 | { | 
|  | 895 | u32 swsm; | 
|  | 896 |  | 
|  | 897 | swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | 
|  | 898 |  | 
|  | 899 | /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ | 
|  | 900 | swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); | 
|  | 901 | IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); | 
| Auke Kok | 3957d63 | 2007-10-31 15:22:10 -0700 | [diff] [blame] | 902 | IXGBE_WRITE_FLUSH(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 903 | } | 
|  | 904 |  | 
|  | 905 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 906 | *  ixgbe_ready_eeprom - Polls for EEPROM ready | 
|  | 907 | *  @hw: pointer to hardware structure | 
|  | 908 | **/ | 
|  | 909 | static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) | 
|  | 910 | { | 
|  | 911 | s32 status = 0; | 
|  | 912 | u16 i; | 
|  | 913 | u8 spi_stat_reg; | 
|  | 914 |  | 
|  | 915 | /* | 
|  | 916 | * Read "Status Register" repeatedly until the LSB is cleared.  The | 
|  | 917 | * EEPROM will signal that the command has been completed by clearing | 
|  | 918 | * bit 0 of the internal status register.  If it's not cleared within | 
|  | 919 | * 5 milliseconds, then error out. | 
|  | 920 | */ | 
|  | 921 | for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { | 
|  | 922 | ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, | 
|  | 923 | IXGBE_EEPROM_OPCODE_BITS); | 
|  | 924 | spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); | 
|  | 925 | if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) | 
|  | 926 | break; | 
|  | 927 |  | 
|  | 928 | udelay(5); | 
|  | 929 | ixgbe_standby_eeprom(hw); | 
|  | 930 | }; | 
|  | 931 |  | 
|  | 932 | /* | 
|  | 933 | * On some parts, SPI write time could vary from 0-20mSec on 3.3V | 
|  | 934 | * devices (and only 0-5mSec on 5V devices) | 
|  | 935 | */ | 
|  | 936 | if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { | 
|  | 937 | hw_dbg(hw, "SPI EEPROM Status error\n"); | 
|  | 938 | status = IXGBE_ERR_EEPROM; | 
|  | 939 | } | 
|  | 940 |  | 
|  | 941 | return status; | 
|  | 942 | } | 
|  | 943 |  | 
|  | 944 | /** | 
|  | 945 | *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state | 
|  | 946 | *  @hw: pointer to hardware structure | 
|  | 947 | **/ | 
|  | 948 | static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) | 
|  | 949 | { | 
|  | 950 | u32 eec; | 
|  | 951 |  | 
|  | 952 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 953 |  | 
|  | 954 | /* Toggle CS to flush commands */ | 
|  | 955 | eec |= IXGBE_EEC_CS; | 
|  | 956 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 957 | IXGBE_WRITE_FLUSH(hw); | 
|  | 958 | udelay(1); | 
|  | 959 | eec &= ~IXGBE_EEC_CS; | 
|  | 960 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 961 | IXGBE_WRITE_FLUSH(hw); | 
|  | 962 | udelay(1); | 
|  | 963 | } | 
|  | 964 |  | 
|  | 965 | /** | 
|  | 966 | *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. | 
|  | 967 | *  @hw: pointer to hardware structure | 
|  | 968 | *  @data: data to send to the EEPROM | 
|  | 969 | *  @count: number of bits to shift out | 
|  | 970 | **/ | 
|  | 971 | static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, | 
|  | 972 | u16 count) | 
|  | 973 | { | 
|  | 974 | u32 eec; | 
|  | 975 | u32 mask; | 
|  | 976 | u32 i; | 
|  | 977 |  | 
|  | 978 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 979 |  | 
|  | 980 | /* | 
|  | 981 | * Mask is used to shift "count" bits of "data" out to the EEPROM | 
|  | 982 | * one bit at a time.  Determine the starting bit based on count | 
|  | 983 | */ | 
|  | 984 | mask = 0x01 << (count - 1); | 
|  | 985 |  | 
|  | 986 | for (i = 0; i < count; i++) { | 
|  | 987 | /* | 
|  | 988 | * A "1" is shifted out to the EEPROM by setting bit "DI" to a | 
|  | 989 | * "1", and then raising and then lowering the clock (the SK | 
|  | 990 | * bit controls the clock input to the EEPROM).  A "0" is | 
|  | 991 | * shifted out to the EEPROM by setting "DI" to "0" and then | 
|  | 992 | * raising and then lowering the clock. | 
|  | 993 | */ | 
|  | 994 | if (data & mask) | 
|  | 995 | eec |= IXGBE_EEC_DI; | 
|  | 996 | else | 
|  | 997 | eec &= ~IXGBE_EEC_DI; | 
|  | 998 |  | 
|  | 999 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 1000 | IXGBE_WRITE_FLUSH(hw); | 
|  | 1001 |  | 
|  | 1002 | udelay(1); | 
|  | 1003 |  | 
|  | 1004 | ixgbe_raise_eeprom_clk(hw, &eec); | 
|  | 1005 | ixgbe_lower_eeprom_clk(hw, &eec); | 
|  | 1006 |  | 
|  | 1007 | /* | 
|  | 1008 | * Shift mask to signify next bit of data to shift in to the | 
|  | 1009 | * EEPROM | 
|  | 1010 | */ | 
|  | 1011 | mask = mask >> 1; | 
|  | 1012 | }; | 
|  | 1013 |  | 
|  | 1014 | /* We leave the "DI" bit set to "0" when we leave this routine. */ | 
|  | 1015 | eec &= ~IXGBE_EEC_DI; | 
|  | 1016 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 1017 | IXGBE_WRITE_FLUSH(hw); | 
|  | 1018 | } | 
|  | 1019 |  | 
|  | 1020 | /** | 
|  | 1021 | *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM | 
|  | 1022 | *  @hw: pointer to hardware structure | 
|  | 1023 | **/ | 
|  | 1024 | static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) | 
|  | 1025 | { | 
|  | 1026 | u32 eec; | 
|  | 1027 | u32 i; | 
|  | 1028 | u16 data = 0; | 
|  | 1029 |  | 
|  | 1030 | /* | 
|  | 1031 | * In order to read a register from the EEPROM, we need to shift | 
|  | 1032 | * 'count' bits in from the EEPROM. Bits are "shifted in" by raising | 
|  | 1033 | * the clock input to the EEPROM (setting the SK bit), and then reading | 
|  | 1034 | * the value of the "DO" bit.  During this "shifting in" process the | 
|  | 1035 | * "DI" bit should always be clear. | 
|  | 1036 | */ | 
|  | 1037 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 1038 |  | 
|  | 1039 | eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); | 
|  | 1040 |  | 
|  | 1041 | for (i = 0; i < count; i++) { | 
|  | 1042 | data = data << 1; | 
|  | 1043 | ixgbe_raise_eeprom_clk(hw, &eec); | 
|  | 1044 |  | 
|  | 1045 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 1046 |  | 
|  | 1047 | eec &= ~(IXGBE_EEC_DI); | 
|  | 1048 | if (eec & IXGBE_EEC_DO) | 
|  | 1049 | data |= 1; | 
|  | 1050 |  | 
|  | 1051 | ixgbe_lower_eeprom_clk(hw, &eec); | 
|  | 1052 | } | 
|  | 1053 |  | 
|  | 1054 | return data; | 
|  | 1055 | } | 
|  | 1056 |  | 
|  | 1057 | /** | 
|  | 1058 | *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. | 
|  | 1059 | *  @hw: pointer to hardware structure | 
|  | 1060 | *  @eec: EEC register's current value | 
|  | 1061 | **/ | 
|  | 1062 | static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) | 
|  | 1063 | { | 
|  | 1064 | /* | 
|  | 1065 | * Raise the clock input to the EEPROM | 
|  | 1066 | * (setting the SK bit), then delay | 
|  | 1067 | */ | 
|  | 1068 | *eec = *eec | IXGBE_EEC_SK; | 
|  | 1069 | IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); | 
|  | 1070 | IXGBE_WRITE_FLUSH(hw); | 
|  | 1071 | udelay(1); | 
|  | 1072 | } | 
|  | 1073 |  | 
|  | 1074 | /** | 
|  | 1075 | *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. | 
|  | 1076 | *  @hw: pointer to hardware structure | 
|  | 1077 | *  @eecd: EECD's current value | 
|  | 1078 | **/ | 
|  | 1079 | static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) | 
|  | 1080 | { | 
|  | 1081 | /* | 
|  | 1082 | * Lower the clock input to the EEPROM (clearing the SK bit), then | 
|  | 1083 | * delay | 
|  | 1084 | */ | 
|  | 1085 | *eec = *eec & ~IXGBE_EEC_SK; | 
|  | 1086 | IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); | 
|  | 1087 | IXGBE_WRITE_FLUSH(hw); | 
|  | 1088 | udelay(1); | 
|  | 1089 | } | 
|  | 1090 |  | 
|  | 1091 | /** | 
|  | 1092 | *  ixgbe_release_eeprom - Release EEPROM, release semaphores | 
|  | 1093 | *  @hw: pointer to hardware structure | 
|  | 1094 | **/ | 
|  | 1095 | static void ixgbe_release_eeprom(struct ixgbe_hw *hw) | 
|  | 1096 | { | 
|  | 1097 | u32 eec; | 
|  | 1098 |  | 
|  | 1099 | eec = IXGBE_READ_REG(hw, IXGBE_EEC); | 
|  | 1100 |  | 
|  | 1101 | eec |= IXGBE_EEC_CS;  /* Pull CS high */ | 
|  | 1102 | eec &= ~IXGBE_EEC_SK; /* Lower SCK */ | 
|  | 1103 |  | 
|  | 1104 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 1105 | IXGBE_WRITE_FLUSH(hw); | 
|  | 1106 |  | 
|  | 1107 | udelay(1); | 
|  | 1108 |  | 
|  | 1109 | /* Stop requesting EEPROM access */ | 
|  | 1110 | eec &= ~IXGBE_EEC_REQ; | 
|  | 1111 | IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); | 
|  | 1112 |  | 
| Don Skidmore | 9082799 | 2011-03-05 18:59:20 -0800 | [diff] [blame] | 1113 | hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 1114 |  | 
|  | 1115 | /* Delay before attempt to obtain semaphore again to allow FW access */ | 
|  | 1116 | msleep(hw->eeprom.semaphore_delay); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1117 | } | 
|  | 1118 |  | 
|  | 1119 | /** | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 1120 | *  ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1121 | *  @hw: pointer to hardware structure | 
|  | 1122 | **/ | 
| Don Skidmore | a391f1d | 2010-11-16 19:27:15 -0800 | [diff] [blame] | 1123 | u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1124 | { | 
|  | 1125 | u16 i; | 
|  | 1126 | u16 j; | 
|  | 1127 | u16 checksum = 0; | 
|  | 1128 | u16 length = 0; | 
|  | 1129 | u16 pointer = 0; | 
|  | 1130 | u16 word = 0; | 
|  | 1131 |  | 
|  | 1132 | /* Include 0x0-0x3F in the checksum */ | 
|  | 1133 | for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1134 | if (hw->eeprom.ops.read(hw, i, &word) != 0) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1135 | hw_dbg(hw, "EEPROM read failed\n"); | 
|  | 1136 | break; | 
|  | 1137 | } | 
|  | 1138 | checksum += word; | 
|  | 1139 | } | 
|  | 1140 |  | 
|  | 1141 | /* Include all data from pointers except for the fw pointer */ | 
|  | 1142 | for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1143 | hw->eeprom.ops.read(hw, i, &pointer); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1144 |  | 
|  | 1145 | /* Make sure the pointer seems valid */ | 
|  | 1146 | if (pointer != 0xFFFF && pointer != 0) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1147 | hw->eeprom.ops.read(hw, pointer, &length); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1148 |  | 
|  | 1149 | if (length != 0xFFFF && length != 0) { | 
|  | 1150 | for (j = pointer+1; j <= pointer+length; j++) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1151 | hw->eeprom.ops.read(hw, j, &word); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1152 | checksum += word; | 
|  | 1153 | } | 
|  | 1154 | } | 
|  | 1155 | } | 
|  | 1156 | } | 
|  | 1157 |  | 
|  | 1158 | checksum = (u16)IXGBE_EEPROM_SUM - checksum; | 
|  | 1159 |  | 
|  | 1160 | return checksum; | 
|  | 1161 | } | 
|  | 1162 |  | 
|  | 1163 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1164 | *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1165 | *  @hw: pointer to hardware structure | 
|  | 1166 | *  @checksum_val: calculated checksum | 
|  | 1167 | * | 
|  | 1168 | *  Performs checksum calculation and validates the EEPROM checksum.  If the | 
|  | 1169 | *  caller does not need checksum_val, the value can be NULL. | 
|  | 1170 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1171 | s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, | 
|  | 1172 | u16 *checksum_val) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1173 | { | 
|  | 1174 | s32 status; | 
|  | 1175 | u16 checksum; | 
|  | 1176 | u16 read_checksum = 0; | 
|  | 1177 |  | 
|  | 1178 | /* | 
|  | 1179 | * Read the first word from the EEPROM. If this times out or fails, do | 
|  | 1180 | * not continue or we could be in for a very long wait while every | 
|  | 1181 | * EEPROM read fails | 
|  | 1182 | */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1183 | status = hw->eeprom.ops.read(hw, 0, &checksum); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1184 |  | 
|  | 1185 | if (status == 0) { | 
| Don Skidmore | a391f1d | 2010-11-16 19:27:15 -0800 | [diff] [blame] | 1186 | checksum = hw->eeprom.ops.calc_checksum(hw); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1187 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1188 | hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1189 |  | 
|  | 1190 | /* | 
|  | 1191 | * Verify read checksum from EEPROM is the same as | 
|  | 1192 | * calculated checksum | 
|  | 1193 | */ | 
|  | 1194 | if (read_checksum != checksum) | 
|  | 1195 | status = IXGBE_ERR_EEPROM_CHECKSUM; | 
|  | 1196 |  | 
|  | 1197 | /* If the user cares, return the calculated checksum */ | 
|  | 1198 | if (checksum_val) | 
|  | 1199 | *checksum_val = checksum; | 
|  | 1200 | } else { | 
|  | 1201 | hw_dbg(hw, "EEPROM read failed\n"); | 
|  | 1202 | } | 
|  | 1203 |  | 
|  | 1204 | return status; | 
|  | 1205 | } | 
|  | 1206 |  | 
|  | 1207 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1208 | *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum | 
|  | 1209 | *  @hw: pointer to hardware structure | 
|  | 1210 | **/ | 
|  | 1211 | s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) | 
|  | 1212 | { | 
|  | 1213 | s32 status; | 
|  | 1214 | u16 checksum; | 
|  | 1215 |  | 
|  | 1216 | /* | 
|  | 1217 | * Read the first word from the EEPROM. If this times out or fails, do | 
|  | 1218 | * not continue or we could be in for a very long wait while every | 
|  | 1219 | * EEPROM read fails | 
|  | 1220 | */ | 
|  | 1221 | status = hw->eeprom.ops.read(hw, 0, &checksum); | 
|  | 1222 |  | 
|  | 1223 | if (status == 0) { | 
| Don Skidmore | a391f1d | 2010-11-16 19:27:15 -0800 | [diff] [blame] | 1224 | checksum = hw->eeprom.ops.calc_checksum(hw); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1225 | status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, | 
| Emil Tantilov | 8c7bea3 | 2011-02-19 08:43:44 +0000 | [diff] [blame] | 1226 | checksum); | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1227 | } else { | 
|  | 1228 | hw_dbg(hw, "EEPROM read failed\n"); | 
|  | 1229 | } | 
|  | 1230 |  | 
|  | 1231 | return status; | 
|  | 1232 | } | 
|  | 1233 |  | 
|  | 1234 | /** | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1235 | *  ixgbe_validate_mac_addr - Validate MAC address | 
|  | 1236 | *  @mac_addr: pointer to MAC address. | 
|  | 1237 | * | 
|  | 1238 | *  Tests a MAC address to ensure it is a valid Individual Address | 
|  | 1239 | **/ | 
|  | 1240 | s32 ixgbe_validate_mac_addr(u8 *mac_addr) | 
|  | 1241 | { | 
|  | 1242 | s32 status = 0; | 
|  | 1243 |  | 
|  | 1244 | /* Make sure it is not a multicast address */ | 
|  | 1245 | if (IXGBE_IS_MULTICAST(mac_addr)) | 
|  | 1246 | status = IXGBE_ERR_INVALID_MAC_ADDR; | 
|  | 1247 | /* Not a broadcast address */ | 
|  | 1248 | else if (IXGBE_IS_BROADCAST(mac_addr)) | 
|  | 1249 | status = IXGBE_ERR_INVALID_MAC_ADDR; | 
|  | 1250 | /* Reject the zero address */ | 
|  | 1251 | else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1252 | mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1253 | status = IXGBE_ERR_INVALID_MAC_ADDR; | 
|  | 1254 |  | 
|  | 1255 | return status; | 
|  | 1256 | } | 
|  | 1257 |  | 
|  | 1258 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1259 | *  ixgbe_set_rar_generic - Set Rx address register | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1260 | *  @hw: pointer to hardware structure | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1261 | *  @index: Receive address register to write | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1262 | *  @addr: Address to put into receive address register | 
|  | 1263 | *  @vmdq: VMDq "set" or "pool" index | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1264 | *  @enable_addr: set flag that address is active | 
|  | 1265 | * | 
|  | 1266 | *  Puts an ethernet address into a receive address register. | 
|  | 1267 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1268 | s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, | 
|  | 1269 | u32 enable_addr) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1270 | { | 
|  | 1271 | u32 rar_low, rar_high; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1272 | u32 rar_entries = hw->mac.num_rar_entries; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1273 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1274 | /* Make sure we are using a valid rar index range */ | 
|  | 1275 | if (index >= rar_entries) { | 
|  | 1276 | hw_dbg(hw, "RAR index %d is out of range.\n", index); | 
|  | 1277 | return IXGBE_ERR_INVALID_ARGUMENT; | 
|  | 1278 | } | 
|  | 1279 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1280 | /* setup VMDq pool selection before this RAR gets enabled */ | 
|  | 1281 | hw->mac.ops.set_vmdq(hw, index, vmdq); | 
|  | 1282 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1283 | /* | 
|  | 1284 | * HW expects these in little endian so we reverse the byte | 
|  | 1285 | * order from network order (big endian) to little endian | 
|  | 1286 | */ | 
|  | 1287 | rar_low = ((u32)addr[0] | | 
|  | 1288 | ((u32)addr[1] << 8) | | 
|  | 1289 | ((u32)addr[2] << 16) | | 
|  | 1290 | ((u32)addr[3] << 24)); | 
|  | 1291 | /* | 
|  | 1292 | * Some parts put the VMDq setting in the extra RAH bits, | 
|  | 1293 | * so save everything except the lower 16 bits that hold part | 
|  | 1294 | * of the address and the address valid bit. | 
|  | 1295 | */ | 
|  | 1296 | rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); | 
|  | 1297 | rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); | 
|  | 1298 | rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1299 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1300 | if (enable_addr != 0) | 
|  | 1301 | rar_high |= IXGBE_RAH_AV; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1302 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1303 | IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); | 
|  | 1304 | IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1305 |  | 
|  | 1306 | return 0; | 
|  | 1307 | } | 
|  | 1308 |  | 
|  | 1309 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1310 | *  ixgbe_clear_rar_generic - Remove Rx address register | 
|  | 1311 | *  @hw: pointer to hardware structure | 
|  | 1312 | *  @index: Receive address register to write | 
|  | 1313 | * | 
|  | 1314 | *  Clears an ethernet address from a receive address register. | 
|  | 1315 | **/ | 
|  | 1316 | s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) | 
|  | 1317 | { | 
|  | 1318 | u32 rar_high; | 
|  | 1319 | u32 rar_entries = hw->mac.num_rar_entries; | 
|  | 1320 |  | 
|  | 1321 | /* Make sure we are using a valid rar index range */ | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1322 | if (index >= rar_entries) { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1323 | hw_dbg(hw, "RAR index %d is out of range.\n", index); | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1324 | return IXGBE_ERR_INVALID_ARGUMENT; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1325 | } | 
|  | 1326 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 1327 | /* | 
|  | 1328 | * Some parts put the VMDq setting in the extra RAH bits, | 
|  | 1329 | * so save everything except the lower 16 bits that hold part | 
|  | 1330 | * of the address and the address valid bit. | 
|  | 1331 | */ | 
|  | 1332 | rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); | 
|  | 1333 | rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); | 
|  | 1334 |  | 
|  | 1335 | IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); | 
|  | 1336 | IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); | 
|  | 1337 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1338 | /* clear VMDq pool/queue selection for this RAR */ | 
|  | 1339 | hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); | 
|  | 1340 |  | 
|  | 1341 | return 0; | 
|  | 1342 | } | 
|  | 1343 |  | 
|  | 1344 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1345 | *  ixgbe_init_rx_addrs_generic - Initializes receive address filters. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1346 | *  @hw: pointer to hardware structure | 
|  | 1347 | * | 
|  | 1348 | *  Places the MAC address in receive address register 0 and clears the rest | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1349 | *  of the receive address registers. Clears the multicast table. Assumes | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1350 | *  the receiver is in reset when the routine is called. | 
|  | 1351 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1352 | s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1353 | { | 
|  | 1354 | u32 i; | 
| Christopher Leech | 2c5645c | 2008-08-26 04:27:02 -0700 | [diff] [blame] | 1355 | u32 rar_entries = hw->mac.num_rar_entries; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1356 |  | 
|  | 1357 | /* | 
|  | 1358 | * If the current mac address is valid, assume it is a software override | 
|  | 1359 | * to the permanent address. | 
|  | 1360 | * Otherwise, use the permanent address from the eeprom. | 
|  | 1361 | */ | 
|  | 1362 | if (ixgbe_validate_mac_addr(hw->mac.addr) == | 
|  | 1363 | IXGBE_ERR_INVALID_MAC_ADDR) { | 
|  | 1364 | /* Get the MAC address from the RAR0 for later reference */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1365 | hw->mac.ops.get_mac_addr(hw, hw->mac.addr); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1366 |  | 
| hartleys | ce7194d | 2010-01-05 06:56:52 +0000 | [diff] [blame] | 1367 | hw_dbg(hw, " Keeping Current RAR0 Addr =%pM\n", hw->mac.addr); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1368 | } else { | 
|  | 1369 | /* Setup the receive address. */ | 
|  | 1370 | hw_dbg(hw, "Overriding MAC Address in RAR[0]\n"); | 
| hartleys | ce7194d | 2010-01-05 06:56:52 +0000 | [diff] [blame] | 1371 | hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1372 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1373 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | 
| Alexander Duyck | 96cc637 | 2011-01-19 18:33:05 +0000 | [diff] [blame] | 1374 |  | 
|  | 1375 | /*  clear VMDq pool/queue selection for RAR 0 */ | 
|  | 1376 | hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1377 | } | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1378 | hw->addr_ctrl.overflow_promisc = 0; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1379 |  | 
|  | 1380 | hw->addr_ctrl.rar_used_count = 1; | 
|  | 1381 |  | 
|  | 1382 | /* Zero out the other receive addresses. */ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1383 | hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1384 | for (i = 1; i < rar_entries; i++) { | 
|  | 1385 | IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); | 
|  | 1386 | IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); | 
|  | 1387 | } | 
|  | 1388 |  | 
|  | 1389 | /* Clear the MTA */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1390 | hw->addr_ctrl.mta_in_use = 0; | 
|  | 1391 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); | 
|  | 1392 |  | 
|  | 1393 | hw_dbg(hw, " Clearing MTA\n"); | 
| Christopher Leech | 2c5645c | 2008-08-26 04:27:02 -0700 | [diff] [blame] | 1394 | for (i = 0; i < hw->mac.mcft_size; i++) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1395 | IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); | 
|  | 1396 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1397 | if (hw->mac.ops.init_uta_tables) | 
|  | 1398 | hw->mac.ops.init_uta_tables(hw); | 
|  | 1399 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1400 | return 0; | 
|  | 1401 | } | 
|  | 1402 |  | 
|  | 1403 | /** | 
|  | 1404 | *  ixgbe_mta_vector - Determines bit-vector in multicast table to set | 
|  | 1405 | *  @hw: pointer to hardware structure | 
|  | 1406 | *  @mc_addr: the multicast address | 
|  | 1407 | * | 
|  | 1408 | *  Extracts the 12 bits, from a multicast address, to determine which | 
|  | 1409 | *  bit-vector to set in the multicast table. The hardware uses 12 bits, from | 
|  | 1410 | *  incoming rx multicast addresses, to determine the bit-vector to check in | 
|  | 1411 | *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1412 | *  by the MO field of the MCSTCTRL. The MO field is set during initialization | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1413 | *  to mc_filter_type. | 
|  | 1414 | **/ | 
|  | 1415 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) | 
|  | 1416 | { | 
|  | 1417 | u32 vector = 0; | 
|  | 1418 |  | 
|  | 1419 | switch (hw->mac.mc_filter_type) { | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1420 | case 0:   /* use bits [47:36] of the address */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1421 | vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); | 
|  | 1422 | break; | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1423 | case 1:   /* use bits [46:35] of the address */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1424 | vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); | 
|  | 1425 | break; | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1426 | case 2:   /* use bits [45:34] of the address */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1427 | vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); | 
|  | 1428 | break; | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1429 | case 3:   /* use bits [43:32] of the address */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1430 | vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); | 
|  | 1431 | break; | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1432 | default:  /* Invalid mc_filter_type */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1433 | hw_dbg(hw, "MC filter type param set incorrectly\n"); | 
|  | 1434 | break; | 
|  | 1435 | } | 
|  | 1436 |  | 
|  | 1437 | /* vector can only be 12-bits or boundary will be exceeded */ | 
|  | 1438 | vector &= 0xFFF; | 
|  | 1439 | return vector; | 
|  | 1440 | } | 
|  | 1441 |  | 
|  | 1442 | /** | 
|  | 1443 | *  ixgbe_set_mta - Set bit-vector in multicast table | 
|  | 1444 | *  @hw: pointer to hardware structure | 
|  | 1445 | *  @hash_value: Multicast address hash value | 
|  | 1446 | * | 
|  | 1447 | *  Sets the bit-vector in the multicast table. | 
|  | 1448 | **/ | 
|  | 1449 | static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) | 
|  | 1450 | { | 
|  | 1451 | u32 vector; | 
|  | 1452 | u32 vector_bit; | 
|  | 1453 | u32 vector_reg; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1454 |  | 
|  | 1455 | hw->addr_ctrl.mta_in_use++; | 
|  | 1456 |  | 
|  | 1457 | vector = ixgbe_mta_vector(hw, mc_addr); | 
|  | 1458 | hw_dbg(hw, " bit-vector = 0x%03X\n", vector); | 
|  | 1459 |  | 
|  | 1460 | /* | 
|  | 1461 | * The MTA is a register array of 128 32-bit registers. It is treated | 
|  | 1462 | * like an array of 4096 bits.  We want to set bit | 
|  | 1463 | * BitArray[vector_value]. So we figure out what register the bit is | 
|  | 1464 | * in, read it, OR in the new bit, then write back the new value.  The | 
|  | 1465 | * register is determined by the upper 7 bits of the vector value and | 
|  | 1466 | * the bit within that register are determined by the lower 5 bits of | 
|  | 1467 | * the value. | 
|  | 1468 | */ | 
|  | 1469 | vector_reg = (vector >> 5) & 0x7F; | 
|  | 1470 | vector_bit = vector & 0x1F; | 
| Emil Tantilov | 80960ab | 2011-02-18 08:58:27 +0000 | [diff] [blame] | 1471 | hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1472 | } | 
|  | 1473 |  | 
|  | 1474 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1475 | *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1476 | *  @hw: pointer to hardware structure | 
| Jiri Pirko | 2853eb8 | 2010-03-23 22:58:01 +0000 | [diff] [blame] | 1477 | *  @netdev: pointer to net device structure | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1478 | * | 
|  | 1479 | *  The given list replaces any existing list. Clears the MC addrs from receive | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1480 | *  address registers and the multicast table. Uses unused receive address | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1481 | *  registers for the first multicast addresses, and hashes the rest into the | 
|  | 1482 | *  multicast table. | 
|  | 1483 | **/ | 
| Jiri Pirko | 2853eb8 | 2010-03-23 22:58:01 +0000 | [diff] [blame] | 1484 | s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, | 
|  | 1485 | struct net_device *netdev) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1486 | { | 
| Jiri Pirko | 22bedad | 2010-04-01 21:22:57 +0000 | [diff] [blame] | 1487 | struct netdev_hw_addr *ha; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1488 | u32 i; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1489 |  | 
|  | 1490 | /* | 
|  | 1491 | * Set the new number of MC addresses that we are being requested to | 
|  | 1492 | * use. | 
|  | 1493 | */ | 
| Jiri Pirko | 2853eb8 | 2010-03-23 22:58:01 +0000 | [diff] [blame] | 1494 | hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1495 | hw->addr_ctrl.mta_in_use = 0; | 
|  | 1496 |  | 
| Emil Tantilov | 80960ab | 2011-02-18 08:58:27 +0000 | [diff] [blame] | 1497 | /* Clear mta_shadow */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1498 | hw_dbg(hw, " Clearing MTA\n"); | 
| Emil Tantilov | 80960ab | 2011-02-18 08:58:27 +0000 | [diff] [blame] | 1499 | memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1500 |  | 
| Emil Tantilov | 80960ab | 2011-02-18 08:58:27 +0000 | [diff] [blame] | 1501 | /* Update mta shadow */ | 
| Jiri Pirko | 22bedad | 2010-04-01 21:22:57 +0000 | [diff] [blame] | 1502 | netdev_for_each_mc_addr(ha, netdev) { | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1503 | hw_dbg(hw, " Adding the multicast addresses:\n"); | 
| Jiri Pirko | 22bedad | 2010-04-01 21:22:57 +0000 | [diff] [blame] | 1504 | ixgbe_set_mta(hw, ha->addr); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1505 | } | 
|  | 1506 |  | 
|  | 1507 | /* Enable mta */ | 
| Emil Tantilov | 80960ab | 2011-02-18 08:58:27 +0000 | [diff] [blame] | 1508 | for (i = 0; i < hw->mac.mcft_size; i++) | 
|  | 1509 | IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, | 
|  | 1510 | hw->mac.mta_shadow[i]); | 
|  | 1511 |  | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1512 | if (hw->addr_ctrl.mta_in_use > 0) | 
|  | 1513 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, | 
| Peter P Waskiewicz | b461724 | 2008-09-11 20:04:46 -0700 | [diff] [blame] | 1514 | IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1515 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1516 | hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n"); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1517 | return 0; | 
|  | 1518 | } | 
|  | 1519 |  | 
|  | 1520 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1521 | *  ixgbe_enable_mc_generic - Enable multicast address in RAR | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1522 | *  @hw: pointer to hardware structure | 
|  | 1523 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1524 | *  Enables multicast address in RAR and the use of the multicast hash table. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1525 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1526 | s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1527 | { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1528 | struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1529 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1530 | if (a->mta_in_use > 0) | 
|  | 1531 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | | 
|  | 1532 | hw->mac.mc_filter_type); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1533 |  | 
|  | 1534 | return 0; | 
|  | 1535 | } | 
|  | 1536 |  | 
|  | 1537 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1538 | *  ixgbe_disable_mc_generic - Disable multicast address in RAR | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1539 | *  @hw: pointer to hardware structure | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1540 | * | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1541 | *  Disables multicast address in RAR and the use of the multicast hash table. | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1542 | **/ | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1543 | s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1544 | { | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1545 | struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1546 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 1547 | if (a->mta_in_use > 0) | 
|  | 1548 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 1549 |  | 
|  | 1550 | return 0; | 
|  | 1551 | } | 
|  | 1552 |  | 
|  | 1553 | /** | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1554 | *  ixgbe_fc_enable_generic - Enable flow control | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1555 | *  @hw: pointer to hardware structure | 
|  | 1556 | *  @packetbuf_num: packet buffer number (0-7) | 
|  | 1557 | * | 
|  | 1558 | *  Enable flow control according to the current settings. | 
|  | 1559 | **/ | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1560 | s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1561 | { | 
|  | 1562 | s32 ret_val = 0; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1563 | u32 mflcn_reg, fccfg_reg; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1564 | u32 reg; | 
| Peter P Waskiewicz Jr | 70b7762 | 2009-05-17 12:34:55 +0000 | [diff] [blame] | 1565 | u32 rx_pba_size; | 
| John Fastabend | 16b61be | 2010-11-16 19:26:44 -0800 | [diff] [blame] | 1566 | u32 fcrtl, fcrth; | 
| Peter P Waskiewicz Jr | 70b7762 | 2009-05-17 12:34:55 +0000 | [diff] [blame] | 1567 |  | 
|  | 1568 | #ifdef CONFIG_DCB | 
|  | 1569 | if (hw->fc.requested_mode == ixgbe_fc_pfc) | 
|  | 1570 | goto out; | 
|  | 1571 |  | 
|  | 1572 | #endif /* CONFIG_DCB */ | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1573 | /* Negotiate the fc mode to use */ | 
|  | 1574 | ret_val = ixgbe_fc_autoneg(hw); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1575 | if (ret_val == IXGBE_ERR_FLOW_CONTROL) | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1576 | goto out; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1577 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1578 | /* Disable any previous flow control settings */ | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1579 | mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); | 
|  | 1580 | mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); | 
|  | 1581 |  | 
|  | 1582 | fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); | 
|  | 1583 | fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); | 
|  | 1584 |  | 
|  | 1585 | /* | 
|  | 1586 | * The possible values of fc.current_mode are: | 
|  | 1587 | * 0: Flow control is completely disabled | 
|  | 1588 | * 1: Rx flow control is enabled (we can receive pause frames, | 
|  | 1589 | *    but not send pause frames). | 
| PJ Waskiewicz | bb3daa4 | 2009-03-25 22:10:42 +0000 | [diff] [blame] | 1590 | * 2: Tx flow control is enabled (we can send pause frames but | 
|  | 1591 | *    we do not support receiving pause frames). | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1592 | * 3: Both Rx and Tx flow control (symmetric) are enabled. | 
| Emil Tantilov | 8c7bea3 | 2011-02-19 08:43:44 +0000 | [diff] [blame] | 1593 | #ifdef CONFIG_DCB | 
| PJ Waskiewicz | bb3daa4 | 2009-03-25 22:10:42 +0000 | [diff] [blame] | 1594 | * 4: Priority Flow Control is enabled. | 
| Emil Tantilov | 8c7bea3 | 2011-02-19 08:43:44 +0000 | [diff] [blame] | 1595 | #endif | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1596 | * other: Invalid. | 
|  | 1597 | */ | 
|  | 1598 | switch (hw->fc.current_mode) { | 
|  | 1599 | case ixgbe_fc_none: | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1600 | /* | 
|  | 1601 | * Flow control is disabled by software override or autoneg. | 
|  | 1602 | * The code below will actually disable it in the HW. | 
|  | 1603 | */ | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1604 | break; | 
|  | 1605 | case ixgbe_fc_rx_pause: | 
|  | 1606 | /* | 
|  | 1607 | * Rx Flow control is enabled and Tx Flow control is | 
|  | 1608 | * disabled by software override. Since there really | 
|  | 1609 | * isn't a way to advertise that we are capable of RX | 
|  | 1610 | * Pause ONLY, we will advertise that we support both | 
|  | 1611 | * symmetric and asymmetric Rx PAUSE.  Later, we will | 
|  | 1612 | * disable the adapter's ability to send PAUSE frames. | 
|  | 1613 | */ | 
|  | 1614 | mflcn_reg |= IXGBE_MFLCN_RFCE; | 
|  | 1615 | break; | 
|  | 1616 | case ixgbe_fc_tx_pause: | 
|  | 1617 | /* | 
|  | 1618 | * Tx Flow control is enabled, and Rx Flow control is | 
|  | 1619 | * disabled by software override. | 
|  | 1620 | */ | 
|  | 1621 | fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; | 
|  | 1622 | break; | 
|  | 1623 | case ixgbe_fc_full: | 
|  | 1624 | /* Flow control (both Rx and Tx) is enabled by SW override. */ | 
|  | 1625 | mflcn_reg |= IXGBE_MFLCN_RFCE; | 
|  | 1626 | fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; | 
|  | 1627 | break; | 
| PJ Waskiewicz | bb3daa4 | 2009-03-25 22:10:42 +0000 | [diff] [blame] | 1628 | #ifdef CONFIG_DCB | 
|  | 1629 | case ixgbe_fc_pfc: | 
|  | 1630 | goto out; | 
|  | 1631 | break; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1632 | #endif /* CONFIG_DCB */ | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1633 | default: | 
|  | 1634 | hw_dbg(hw, "Flow control param set incorrectly\n"); | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1635 | ret_val = IXGBE_ERR_CONFIG; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1636 | goto out; | 
|  | 1637 | break; | 
|  | 1638 | } | 
|  | 1639 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1640 | /* Set 802.3x based flow control settings. */ | 
| PJ Waskiewicz | 2132d38 | 2009-04-09 22:26:21 +0000 | [diff] [blame] | 1641 | mflcn_reg |= IXGBE_MFLCN_DPF; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1642 | IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); | 
|  | 1643 | IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); | 
|  | 1644 |  | 
| John Fastabend | 16b61be | 2010-11-16 19:26:44 -0800 | [diff] [blame] | 1645 | rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); | 
|  | 1646 | rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1647 |  | 
| John Fastabend | 16b61be | 2010-11-16 19:26:44 -0800 | [diff] [blame] | 1648 | fcrth = (rx_pba_size - hw->fc.high_water) << 10; | 
|  | 1649 | fcrtl = (rx_pba_size - hw->fc.low_water) << 10; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1650 |  | 
| John Fastabend | 16b61be | 2010-11-16 19:26:44 -0800 | [diff] [blame] | 1651 | if (hw->fc.current_mode & ixgbe_fc_tx_pause) { | 
|  | 1652 | fcrth |= IXGBE_FCRTH_FCEN; | 
|  | 1653 | if (hw->fc.send_xon) | 
|  | 1654 | fcrtl |= IXGBE_FCRTL_XONE; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1655 | } | 
|  | 1656 |  | 
| John Fastabend | 16b61be | 2010-11-16 19:26:44 -0800 | [diff] [blame] | 1657 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth); | 
|  | 1658 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl); | 
|  | 1659 |  | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1660 | /* Configure pause time (2 TCs per register) */ | 
| Peter P Waskiewicz Jr | 70b7762 | 2009-05-17 12:34:55 +0000 | [diff] [blame] | 1661 | reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1662 | if ((packetbuf_num & 1) == 0) | 
|  | 1663 | reg = (reg & 0xFFFF0000) | hw->fc.pause_time; | 
|  | 1664 | else | 
|  | 1665 | reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); | 
|  | 1666 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); | 
|  | 1667 |  | 
|  | 1668 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); | 
|  | 1669 |  | 
|  | 1670 | out: | 
|  | 1671 | return ret_val; | 
|  | 1672 | } | 
|  | 1673 |  | 
|  | 1674 | /** | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1675 | *  ixgbe_fc_autoneg - Configure flow control | 
|  | 1676 | *  @hw: pointer to hardware structure | 
|  | 1677 | * | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1678 | *  Compares our advertised flow control capabilities to those advertised by | 
|  | 1679 | *  our link partner, and determines the proper flow control mode to use. | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1680 | **/ | 
|  | 1681 | s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) | 
|  | 1682 | { | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1683 | s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1684 | ixgbe_link_speed speed; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1685 | bool link_up; | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1686 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1687 | if (hw->fc.disable_fc_autoneg) | 
|  | 1688 | goto out; | 
|  | 1689 |  | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1690 | /* | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1691 | * AN should have completed when the cable was plugged in. | 
|  | 1692 | * Look for reasons to bail out.  Bail out if: | 
|  | 1693 | * - FC autoneg is disabled, or if | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1694 | * - link is not up. | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1695 | * | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1696 | * Since we're being called from an LSC, link is already known to be up. | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1697 | * So use link_up_wait_to_complete=false. | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1698 | */ | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1699 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1700 | if (!link_up) { | 
|  | 1701 | ret_val = IXGBE_ERR_FLOW_CONTROL; | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1702 | goto out; | 
|  | 1703 | } | 
|  | 1704 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1705 | switch (hw->phy.media_type) { | 
|  | 1706 | /* Autoneg flow control on fiber adapters */ | 
|  | 1707 | case ixgbe_media_type_fiber: | 
|  | 1708 | if (speed == IXGBE_LINK_SPEED_1GB_FULL) | 
|  | 1709 | ret_val = ixgbe_fc_autoneg_fiber(hw); | 
|  | 1710 | break; | 
| Don Skidmore | 000c486 | 2009-11-24 18:51:48 +0000 | [diff] [blame] | 1711 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1712 | /* Autoneg flow control on backplane adapters */ | 
|  | 1713 | case ixgbe_media_type_backplane: | 
|  | 1714 | ret_val = ixgbe_fc_autoneg_backplane(hw); | 
|  | 1715 | break; | 
|  | 1716 |  | 
|  | 1717 | /* Autoneg flow control on copper adapters */ | 
|  | 1718 | case ixgbe_media_type_copper: | 
|  | 1719 | if (ixgbe_device_supports_autoneg_fc(hw) == 0) | 
|  | 1720 | ret_val = ixgbe_fc_autoneg_copper(hw); | 
|  | 1721 | break; | 
|  | 1722 |  | 
|  | 1723 | default: | 
|  | 1724 | break; | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1725 | } | 
|  | 1726 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1727 | out: | 
|  | 1728 | if (ret_val == 0) { | 
|  | 1729 | hw->fc.fc_was_autonegged = true; | 
|  | 1730 | } else { | 
|  | 1731 | hw->fc.fc_was_autonegged = false; | 
|  | 1732 | hw->fc.current_mode = hw->fc.requested_mode; | 
|  | 1733 | } | 
|  | 1734 | return ret_val; | 
|  | 1735 | } | 
|  | 1736 |  | 
|  | 1737 | /** | 
|  | 1738 | *  ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber | 
|  | 1739 | *  @hw: pointer to hardware structure | 
|  | 1740 | * | 
|  | 1741 | *  Enable flow control according on 1 gig fiber. | 
|  | 1742 | **/ | 
|  | 1743 | static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) | 
|  | 1744 | { | 
|  | 1745 | u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; | 
|  | 1746 | s32 ret_val; | 
|  | 1747 |  | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1748 | /* | 
|  | 1749 | * On multispeed fiber at 1g, bail out if | 
|  | 1750 | * - link is up but AN did not complete, or if | 
|  | 1751 | * - link is up and AN completed but timed out | 
|  | 1752 | */ | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 1753 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1754 | linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); | 
|  | 1755 | if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || | 
|  | 1756 | ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { | 
|  | 1757 | ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; | 
| PJ Waskiewicz | 9bbe3a5 | 2009-11-24 18:51:28 +0000 | [diff] [blame] | 1758 | goto out; | 
|  | 1759 | } | 
|  | 1760 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1761 | pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); | 
|  | 1762 | pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1763 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1764 | ret_val =  ixgbe_negotiate_fc(hw, pcs_anadv_reg, | 
|  | 1765 | pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, | 
|  | 1766 | IXGBE_PCS1GANA_ASM_PAUSE, | 
|  | 1767 | IXGBE_PCS1GANA_SYM_PAUSE, | 
|  | 1768 | IXGBE_PCS1GANA_ASM_PAUSE); | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1769 |  | 
| Peter P Waskiewicz Jr | 0ecc061 | 2009-02-06 21:46:54 -0800 | [diff] [blame] | 1770 | out: | 
|  | 1771 | return ret_val; | 
|  | 1772 | } | 
|  | 1773 |  | 
|  | 1774 | /** | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1775 | *  ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 | 
|  | 1776 | *  @hw: pointer to hardware structure | 
|  | 1777 | * | 
|  | 1778 | *  Enable flow control according to IEEE clause 37. | 
|  | 1779 | **/ | 
|  | 1780 | static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) | 
|  | 1781 | { | 
|  | 1782 | u32 links2, anlp1_reg, autoc_reg, links; | 
|  | 1783 | s32 ret_val; | 
|  | 1784 |  | 
|  | 1785 | /* | 
|  | 1786 | * On backplane, bail out if | 
|  | 1787 | * - backplane autoneg was not completed, or if | 
|  | 1788 | * - we are 82599 and link partner is not AN enabled | 
|  | 1789 | */ | 
|  | 1790 | links = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
|  | 1791 | if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { | 
|  | 1792 | hw->fc.fc_was_autonegged = false; | 
|  | 1793 | hw->fc.current_mode = hw->fc.requested_mode; | 
|  | 1794 | ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; | 
|  | 1795 | goto out; | 
|  | 1796 | } | 
|  | 1797 |  | 
|  | 1798 | if (hw->mac.type == ixgbe_mac_82599EB) { | 
|  | 1799 | links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); | 
|  | 1800 | if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { | 
|  | 1801 | hw->fc.fc_was_autonegged = false; | 
|  | 1802 | hw->fc.current_mode = hw->fc.requested_mode; | 
|  | 1803 | ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; | 
|  | 1804 | goto out; | 
|  | 1805 | } | 
|  | 1806 | } | 
|  | 1807 | /* | 
|  | 1808 | * Read the 10g AN autoc and LP ability registers and resolve | 
|  | 1809 | * local flow control settings accordingly | 
|  | 1810 | */ | 
|  | 1811 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 1812 | anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); | 
|  | 1813 |  | 
|  | 1814 | ret_val = ixgbe_negotiate_fc(hw, autoc_reg, | 
|  | 1815 | anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, | 
|  | 1816 | IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); | 
|  | 1817 |  | 
|  | 1818 | out: | 
|  | 1819 | return ret_val; | 
|  | 1820 | } | 
|  | 1821 |  | 
|  | 1822 | /** | 
|  | 1823 | *  ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 | 
|  | 1824 | *  @hw: pointer to hardware structure | 
|  | 1825 | * | 
|  | 1826 | *  Enable flow control according to IEEE clause 37. | 
|  | 1827 | **/ | 
|  | 1828 | static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) | 
|  | 1829 | { | 
|  | 1830 | u16 technology_ability_reg = 0; | 
|  | 1831 | u16 lp_technology_ability_reg = 0; | 
|  | 1832 |  | 
|  | 1833 | hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, | 
|  | 1834 | MDIO_MMD_AN, | 
|  | 1835 | &technology_ability_reg); | 
|  | 1836 | hw->phy.ops.read_reg(hw, MDIO_AN_LPA, | 
|  | 1837 | MDIO_MMD_AN, | 
|  | 1838 | &lp_technology_ability_reg); | 
|  | 1839 |  | 
|  | 1840 | return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, | 
|  | 1841 | (u32)lp_technology_ability_reg, | 
|  | 1842 | IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, | 
|  | 1843 | IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE); | 
|  | 1844 | } | 
|  | 1845 |  | 
|  | 1846 | /** | 
|  | 1847 | *  ixgbe_negotiate_fc - Negotiate flow control | 
|  | 1848 | *  @hw: pointer to hardware structure | 
|  | 1849 | *  @adv_reg: flow control advertised settings | 
|  | 1850 | *  @lp_reg: link partner's flow control settings | 
|  | 1851 | *  @adv_sym: symmetric pause bit in advertisement | 
|  | 1852 | *  @adv_asm: asymmetric pause bit in advertisement | 
|  | 1853 | *  @lp_sym: symmetric pause bit in link partner advertisement | 
|  | 1854 | *  @lp_asm: asymmetric pause bit in link partner advertisement | 
|  | 1855 | * | 
|  | 1856 | *  Find the intersection between advertised settings and link partner's | 
|  | 1857 | *  advertised settings | 
|  | 1858 | **/ | 
|  | 1859 | static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, | 
|  | 1860 | u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) | 
|  | 1861 | { | 
|  | 1862 | if ((!(adv_reg)) ||  (!(lp_reg))) | 
|  | 1863 | return IXGBE_ERR_FC_NOT_NEGOTIATED; | 
|  | 1864 |  | 
|  | 1865 | if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { | 
|  | 1866 | /* | 
|  | 1867 | * Now we need to check if the user selected Rx ONLY | 
|  | 1868 | * of pause frames.  In this case, we had to advertise | 
|  | 1869 | * FULL flow control because we could not advertise RX | 
|  | 1870 | * ONLY. Hence, we must now check to see if we need to | 
|  | 1871 | * turn OFF the TRANSMISSION of PAUSE frames. | 
|  | 1872 | */ | 
|  | 1873 | if (hw->fc.requested_mode == ixgbe_fc_full) { | 
|  | 1874 | hw->fc.current_mode = ixgbe_fc_full; | 
|  | 1875 | hw_dbg(hw, "Flow Control = FULL.\n"); | 
|  | 1876 | } else { | 
|  | 1877 | hw->fc.current_mode = ixgbe_fc_rx_pause; | 
|  | 1878 | hw_dbg(hw, "Flow Control=RX PAUSE frames only\n"); | 
|  | 1879 | } | 
|  | 1880 | } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && | 
|  | 1881 | (lp_reg & lp_sym) && (lp_reg & lp_asm)) { | 
|  | 1882 | hw->fc.current_mode = ixgbe_fc_tx_pause; | 
|  | 1883 | hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n"); | 
|  | 1884 | } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && | 
|  | 1885 | !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { | 
|  | 1886 | hw->fc.current_mode = ixgbe_fc_rx_pause; | 
|  | 1887 | hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); | 
|  | 1888 | } else { | 
|  | 1889 | hw->fc.current_mode = ixgbe_fc_none; | 
|  | 1890 | hw_dbg(hw, "Flow Control = NONE.\n"); | 
|  | 1891 | } | 
|  | 1892 | return 0; | 
|  | 1893 | } | 
|  | 1894 |  | 
|  | 1895 | /** | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1896 | *  ixgbe_setup_fc - Set up flow control | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1897 | *  @hw: pointer to hardware structure | 
|  | 1898 | * | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1899 | *  Called at init time to set up flow control. | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1900 | **/ | 
| Don Skidmore | 7b25cdb | 2009-08-25 04:47:32 +0000 | [diff] [blame] | 1901 | static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1902 | { | 
|  | 1903 | s32 ret_val = 0; | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1904 | u32 reg = 0, reg_bp = 0; | 
|  | 1905 | u16 reg_cu = 0; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1906 |  | 
| PJ Waskiewicz | bb3daa4 | 2009-03-25 22:10:42 +0000 | [diff] [blame] | 1907 | #ifdef CONFIG_DCB | 
|  | 1908 | if (hw->fc.requested_mode == ixgbe_fc_pfc) { | 
|  | 1909 | hw->fc.current_mode = hw->fc.requested_mode; | 
|  | 1910 | goto out; | 
|  | 1911 | } | 
|  | 1912 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1913 | #endif /* CONFIG_DCB */ | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1914 | /* Validate the packetbuf configuration */ | 
|  | 1915 | if (packetbuf_num < 0 || packetbuf_num > 7) { | 
|  | 1916 | hw_dbg(hw, "Invalid packet buffer number [%d], expected range " | 
|  | 1917 | "is 0-7\n", packetbuf_num); | 
|  | 1918 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | 
|  | 1919 | goto out; | 
|  | 1920 | } | 
|  | 1921 |  | 
|  | 1922 | /* | 
|  | 1923 | * Validate the water mark configuration.  Zero water marks are invalid | 
|  | 1924 | * because it causes the controller to just blast out fc packets. | 
|  | 1925 | */ | 
|  | 1926 | if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1927 | hw_dbg(hw, "Invalid water mark configuration\n"); | 
|  | 1928 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | 
|  | 1929 | goto out; | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1930 | } | 
|  | 1931 |  | 
|  | 1932 | /* | 
|  | 1933 | * Validate the requested mode.  Strict IEEE mode does not allow | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1934 | * ixgbe_fc_rx_pause because it will cause us to fail at UNH. | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1935 | */ | 
|  | 1936 | if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { | 
|  | 1937 | hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict " | 
|  | 1938 | "IEEE mode\n"); | 
|  | 1939 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | 
|  | 1940 | goto out; | 
|  | 1941 | } | 
|  | 1942 |  | 
|  | 1943 | /* | 
|  | 1944 | * 10gig parts do not have a word in the EEPROM to determine the | 
|  | 1945 | * default flow control setting, so we explicitly set it to full. | 
|  | 1946 | */ | 
|  | 1947 | if (hw->fc.requested_mode == ixgbe_fc_default) | 
|  | 1948 | hw->fc.requested_mode = ixgbe_fc_full; | 
|  | 1949 |  | 
|  | 1950 | /* | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1951 | * Set up the 1G and 10G flow control advertisement registers so the | 
|  | 1952 | * HW will be able to do fc autoneg once the cable is plugged in.  If | 
|  | 1953 | * we link at 10G, the 1G advertisement is harmless and vice versa. | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1954 | */ | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1955 |  | 
|  | 1956 | switch (hw->phy.media_type) { | 
|  | 1957 | case ixgbe_media_type_fiber: | 
|  | 1958 | case ixgbe_media_type_backplane: | 
|  | 1959 | reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); | 
|  | 1960 | reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 1961 | break; | 
|  | 1962 |  | 
|  | 1963 | case ixgbe_media_type_copper: | 
|  | 1964 | hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, | 
|  | 1965 | MDIO_MMD_AN, ®_cu); | 
|  | 1966 | break; | 
|  | 1967 |  | 
|  | 1968 | default: | 
|  | 1969 | ; | 
|  | 1970 | } | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 1971 |  | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1972 | /* | 
|  | 1973 | * The possible values of fc.requested_mode are: | 
|  | 1974 | * 0: Flow control is completely disabled | 
|  | 1975 | * 1: Rx flow control is enabled (we can receive pause frames, | 
|  | 1976 | *    but not send pause frames). | 
|  | 1977 | * 2: Tx flow control is enabled (we can send pause frames but | 
|  | 1978 | *    we do not support receiving pause frames). | 
|  | 1979 | * 3: Both Rx and Tx flow control (symmetric) are enabled. | 
|  | 1980 | #ifdef CONFIG_DCB | 
|  | 1981 | * 4: Priority Flow Control is enabled. | 
|  | 1982 | #endif | 
|  | 1983 | * other: Invalid. | 
|  | 1984 | */ | 
|  | 1985 | switch (hw->fc.requested_mode) { | 
|  | 1986 | case ixgbe_fc_none: | 
|  | 1987 | /* Flow control completely disabled by software override. */ | 
|  | 1988 | reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 1989 | if (hw->phy.media_type == ixgbe_media_type_backplane) | 
|  | 1990 | reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | | 
|  | 1991 | IXGBE_AUTOC_ASM_PAUSE); | 
|  | 1992 | else if (hw->phy.media_type == ixgbe_media_type_copper) | 
|  | 1993 | reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 1994 | break; | 
|  | 1995 | case ixgbe_fc_rx_pause: | 
|  | 1996 | /* | 
|  | 1997 | * Rx Flow control is enabled and Tx Flow control is | 
|  | 1998 | * disabled by software override. Since there really | 
|  | 1999 | * isn't a way to advertise that we are capable of RX | 
|  | 2000 | * Pause ONLY, we will advertise that we support both | 
|  | 2001 | * symmetric and asymmetric Rx PAUSE.  Later, we will | 
|  | 2002 | * disable the adapter's ability to send PAUSE frames. | 
|  | 2003 | */ | 
|  | 2004 | reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2005 | if (hw->phy.media_type == ixgbe_media_type_backplane) | 
|  | 2006 | reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | | 
|  | 2007 | IXGBE_AUTOC_ASM_PAUSE); | 
|  | 2008 | else if (hw->phy.media_type == ixgbe_media_type_copper) | 
|  | 2009 | reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 2010 | break; | 
|  | 2011 | case ixgbe_fc_tx_pause: | 
|  | 2012 | /* | 
|  | 2013 | * Tx Flow control is enabled, and Rx Flow control is | 
|  | 2014 | * disabled by software override. | 
|  | 2015 | */ | 
|  | 2016 | reg |= (IXGBE_PCS1GANA_ASM_PAUSE); | 
|  | 2017 | reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2018 | if (hw->phy.media_type == ixgbe_media_type_backplane) { | 
|  | 2019 | reg_bp |= (IXGBE_AUTOC_ASM_PAUSE); | 
|  | 2020 | reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE); | 
|  | 2021 | } else if (hw->phy.media_type == ixgbe_media_type_copper) { | 
|  | 2022 | reg_cu |= (IXGBE_TAF_ASM_PAUSE); | 
|  | 2023 | reg_cu &= ~(IXGBE_TAF_SYM_PAUSE); | 
|  | 2024 | } | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 2025 | break; | 
|  | 2026 | case ixgbe_fc_full: | 
|  | 2027 | /* Flow control (both Rx and Tx) is enabled by SW override. */ | 
|  | 2028 | reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2029 | if (hw->phy.media_type == ixgbe_media_type_backplane) | 
|  | 2030 | reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | | 
|  | 2031 | IXGBE_AUTOC_ASM_PAUSE); | 
|  | 2032 | else if (hw->phy.media_type == ixgbe_media_type_copper) | 
|  | 2033 | reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 2034 | break; | 
|  | 2035 | #ifdef CONFIG_DCB | 
|  | 2036 | case ixgbe_fc_pfc: | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 2037 | goto out; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 2038 | break; | 
|  | 2039 | #endif /* CONFIG_DCB */ | 
|  | 2040 | default: | 
|  | 2041 | hw_dbg(hw, "Flow control param set incorrectly\n"); | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2042 | ret_val = IXGBE_ERR_CONFIG; | 
| Mallikarjuna R Chilakala | 620fa03 | 2009-06-04 11:11:13 +0000 | [diff] [blame] | 2043 | goto out; | 
|  | 2044 | break; | 
|  | 2045 | } | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 2046 |  | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2047 | if (hw->mac.type != ixgbe_mac_X540) { | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2048 | /* | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2049 | * Enable auto-negotiation between the MAC & PHY; | 
|  | 2050 | * the MAC will advertise clause 37 flow control. | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2051 | */ | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2052 | IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); | 
|  | 2053 | reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); | 
|  | 2054 |  | 
|  | 2055 | /* Disable AN timeout */ | 
|  | 2056 | if (hw->fc.strict_ieee) | 
|  | 2057 | reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; | 
|  | 2058 |  | 
|  | 2059 | IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); | 
|  | 2060 | hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2061 | } | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2062 |  | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2063 | /* | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2064 | * AUTOC restart handles negotiation of 1G and 10G on backplane | 
|  | 2065 | * and copper. There is no need to set the PCS1GCTL register. | 
|  | 2066 | * | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2067 | */ | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2068 | if (hw->phy.media_type == ixgbe_media_type_backplane) { | 
|  | 2069 | reg_bp |= IXGBE_AUTOC_AN_RESTART; | 
|  | 2070 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); | 
|  | 2071 | } else if ((hw->phy.media_type == ixgbe_media_type_copper) && | 
|  | 2072 | (ixgbe_device_supports_autoneg_fc(hw) == 0)) { | 
|  | 2073 | hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, | 
|  | 2074 | MDIO_MMD_AN, reg_cu); | 
|  | 2075 | } | 
|  | 2076 |  | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2077 | hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 2078 | out: | 
|  | 2079 | return ret_val; | 
|  | 2080 | } | 
|  | 2081 |  | 
|  | 2082 | /** | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2083 | *  ixgbe_disable_pcie_master - Disable PCI-express master access | 
|  | 2084 | *  @hw: pointer to hardware structure | 
|  | 2085 | * | 
|  | 2086 | *  Disables PCI-Express master access and verifies there are no pending | 
|  | 2087 | *  requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable | 
|  | 2088 | *  bit hasn't caused the master requests to be disabled, else 0 | 
|  | 2089 | *  is returned signifying master requests disabled. | 
|  | 2090 | **/ | 
|  | 2091 | s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) | 
|  | 2092 | { | 
| Emil Tantilov | a4297dc | 2011-02-14 08:45:13 +0000 | [diff] [blame] | 2093 | struct ixgbe_adapter *adapter = hw->back; | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 2094 | u32 i; | 
|  | 2095 | u32 reg_val; | 
|  | 2096 | u32 number_of_queues; | 
| Emil Tantilov | a4297dc | 2011-02-14 08:45:13 +0000 | [diff] [blame] | 2097 | s32 status = 0; | 
|  | 2098 | u16 dev_status = 0; | 
|  | 2099 |  | 
|  | 2100 | /* Just jump out if bus mastering is already disabled */ | 
|  | 2101 | if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) | 
|  | 2102 | goto out; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2103 |  | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 2104 | /* Disable the receive unit by stopping each queue */ | 
|  | 2105 | number_of_queues = hw->mac.max_rx_queues; | 
|  | 2106 | for (i = 0; i < number_of_queues; i++) { | 
|  | 2107 | reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); | 
|  | 2108 | if (reg_val & IXGBE_RXDCTL_ENABLE) { | 
|  | 2109 | reg_val &= ~IXGBE_RXDCTL_ENABLE; | 
|  | 2110 | IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); | 
|  | 2111 | } | 
|  | 2112 | } | 
|  | 2113 |  | 
|  | 2114 | reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL); | 
|  | 2115 | reg_val |= IXGBE_CTRL_GIO_DIS; | 
|  | 2116 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2117 |  | 
|  | 2118 | for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { | 
| Emil Tantilov | a4297dc | 2011-02-14 08:45:13 +0000 | [diff] [blame] | 2119 | if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) | 
|  | 2120 | goto check_device_status; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2121 | udelay(100); | 
|  | 2122 | } | 
|  | 2123 |  | 
| Emil Tantilov | a4297dc | 2011-02-14 08:45:13 +0000 | [diff] [blame] | 2124 | hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n"); | 
|  | 2125 | status = IXGBE_ERR_MASTER_REQUESTS_PENDING; | 
|  | 2126 |  | 
|  | 2127 | /* | 
|  | 2128 | * Before proceeding, make sure that the PCIe block does not have | 
|  | 2129 | * transactions pending. | 
|  | 2130 | */ | 
|  | 2131 | check_device_status: | 
|  | 2132 | for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { | 
|  | 2133 | pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS, | 
|  | 2134 | &dev_status); | 
|  | 2135 | if (!(dev_status & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) | 
|  | 2136 | break; | 
|  | 2137 | udelay(100); | 
|  | 2138 | } | 
|  | 2139 |  | 
|  | 2140 | if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) | 
|  | 2141 | hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n"); | 
|  | 2142 | else | 
|  | 2143 | goto out; | 
|  | 2144 |  | 
|  | 2145 | /* | 
|  | 2146 | * Two consecutive resets are required via CTRL.RST per datasheet | 
|  | 2147 | * 5.2.5.3.2 Master Disable.  We set a flag to inform the reset routine | 
|  | 2148 | * of this need.  The first reset prevents new master requests from | 
|  | 2149 | * being issued by our device.  We then must wait 1usec for any | 
|  | 2150 | * remaining completions from the PCIe bus to trickle in, and then reset | 
|  | 2151 | * again to clear out any effects they may have had on our device. | 
|  | 2152 | */ | 
|  | 2153 | hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | 
|  | 2154 |  | 
|  | 2155 | out: | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2156 | return status; | 
|  | 2157 | } | 
|  | 2158 |  | 
|  | 2159 |  | 
|  | 2160 | /** | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 2161 | *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2162 | *  @hw: pointer to hardware structure | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 2163 | *  @mask: Mask to specify which semaphore to acquire | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2164 | * | 
| Emil Tantilov | da74cd4 | 2011-03-03 09:25:07 +0000 | [diff] [blame] | 2165 | *  Acquires the SWFW semaphore through the GSSR register for the specified | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2166 | *  function (CSR, PHY0, PHY1, EEPROM, Flash) | 
|  | 2167 | **/ | 
|  | 2168 | s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) | 
|  | 2169 | { | 
|  | 2170 | u32 gssr; | 
|  | 2171 | u32 swmask = mask; | 
|  | 2172 | u32 fwmask = mask << 5; | 
|  | 2173 | s32 timeout = 200; | 
|  | 2174 |  | 
|  | 2175 | while (timeout) { | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 2176 | /* | 
|  | 2177 | * SW EEPROM semaphore bit is used for access to all | 
|  | 2178 | * SW_FW_SYNC/GSSR bits (not just EEPROM) | 
|  | 2179 | */ | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2180 | if (ixgbe_get_eeprom_semaphore(hw)) | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2181 | return IXGBE_ERR_SWFW_SYNC; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2182 |  | 
|  | 2183 | gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); | 
|  | 2184 | if (!(gssr & (fwmask | swmask))) | 
|  | 2185 | break; | 
|  | 2186 |  | 
|  | 2187 | /* | 
|  | 2188 | * Firmware currently using resource (fwmask) or other software | 
|  | 2189 | * thread currently using resource (swmask) | 
|  | 2190 | */ | 
|  | 2191 | ixgbe_release_eeprom_semaphore(hw); | 
|  | 2192 | msleep(5); | 
|  | 2193 | timeout--; | 
|  | 2194 | } | 
|  | 2195 |  | 
|  | 2196 | if (!timeout) { | 
| Emil Tantilov | dbf893e | 2011-02-08 09:42:41 +0000 | [diff] [blame] | 2197 | hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n"); | 
| Peter P Waskiewicz Jr | 539e5f0 | 2009-09-30 12:07:38 +0000 | [diff] [blame] | 2198 | return IXGBE_ERR_SWFW_SYNC; | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2199 | } | 
|  | 2200 |  | 
|  | 2201 | gssr |= swmask; | 
|  | 2202 | IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); | 
|  | 2203 |  | 
|  | 2204 | ixgbe_release_eeprom_semaphore(hw); | 
|  | 2205 | return 0; | 
|  | 2206 | } | 
|  | 2207 |  | 
|  | 2208 | /** | 
|  | 2209 | *  ixgbe_release_swfw_sync - Release SWFW semaphore | 
|  | 2210 | *  @hw: pointer to hardware structure | 
| Jesse Brandeburg | c44ade9 | 2008-09-11 19:59:59 -0700 | [diff] [blame] | 2211 | *  @mask: Mask to specify which semaphore to release | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2212 | * | 
| Emil Tantilov | da74cd4 | 2011-03-03 09:25:07 +0000 | [diff] [blame] | 2213 | *  Releases the SWFW semaphore through the GSSR register for the specified | 
| Auke Kok | 9a799d7 | 2007-09-15 14:07:45 -0700 | [diff] [blame] | 2214 | *  function (CSR, PHY0, PHY1, EEPROM, Flash) | 
|  | 2215 | **/ | 
|  | 2216 | void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) | 
|  | 2217 | { | 
|  | 2218 | u32 gssr; | 
|  | 2219 | u32 swmask = mask; | 
|  | 2220 |  | 
|  | 2221 | ixgbe_get_eeprom_semaphore(hw); | 
|  | 2222 |  | 
|  | 2223 | gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); | 
|  | 2224 | gssr &= ~swmask; | 
|  | 2225 | IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); | 
|  | 2226 |  | 
|  | 2227 | ixgbe_release_eeprom_semaphore(hw); | 
|  | 2228 | } | 
|  | 2229 |  | 
| PJ Waskiewicz | 11afc1b | 2009-02-27 15:44:30 +0000 | [diff] [blame] | 2230 | /** | 
|  | 2231 | *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit | 
|  | 2232 | *  @hw: pointer to hardware structure | 
|  | 2233 | *  @regval: register value to write to RXCTRL | 
|  | 2234 | * | 
|  | 2235 | *  Enables the Rx DMA unit | 
|  | 2236 | **/ | 
|  | 2237 | s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) | 
|  | 2238 | { | 
|  | 2239 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); | 
|  | 2240 |  | 
|  | 2241 | return 0; | 
|  | 2242 | } | 
| PJ Waskiewicz | 87c1201 | 2009-04-08 13:20:31 +0000 | [diff] [blame] | 2243 |  | 
|  | 2244 | /** | 
|  | 2245 | *  ixgbe_blink_led_start_generic - Blink LED based on index. | 
|  | 2246 | *  @hw: pointer to hardware structure | 
|  | 2247 | *  @index: led number to blink | 
|  | 2248 | **/ | 
|  | 2249 | s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | 
|  | 2250 | { | 
|  | 2251 | ixgbe_link_speed speed = 0; | 
|  | 2252 | bool link_up = 0; | 
|  | 2253 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 2254 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 
|  | 2255 |  | 
|  | 2256 | /* | 
|  | 2257 | * Link must be up to auto-blink the LEDs; | 
|  | 2258 | * Force it if link is down. | 
|  | 2259 | */ | 
|  | 2260 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | 
|  | 2261 |  | 
|  | 2262 | if (!link_up) { | 
| Peter P Waskiewicz Jr | 50ac58b | 2009-06-04 11:10:53 +0000 | [diff] [blame] | 2263 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 
| PJ Waskiewicz | 87c1201 | 2009-04-08 13:20:31 +0000 | [diff] [blame] | 2264 | autoc_reg |= IXGBE_AUTOC_FLU; | 
|  | 2265 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 
|  | 2266 | msleep(10); | 
|  | 2267 | } | 
|  | 2268 |  | 
|  | 2269 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | 
|  | 2270 | led_reg |= IXGBE_LED_BLINK(index); | 
|  | 2271 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 
|  | 2272 | IXGBE_WRITE_FLUSH(hw); | 
|  | 2273 |  | 
|  | 2274 | return 0; | 
|  | 2275 | } | 
|  | 2276 |  | 
|  | 2277 | /** | 
|  | 2278 | *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index. | 
|  | 2279 | *  @hw: pointer to hardware structure | 
|  | 2280 | *  @index: led number to stop blinking | 
|  | 2281 | **/ | 
|  | 2282 | s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) | 
|  | 2283 | { | 
|  | 2284 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
|  | 2285 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 
|  | 2286 |  | 
|  | 2287 | autoc_reg &= ~IXGBE_AUTOC_FLU; | 
|  | 2288 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 
|  | 2289 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 
|  | 2290 |  | 
|  | 2291 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | 
|  | 2292 | led_reg &= ~IXGBE_LED_BLINK(index); | 
|  | 2293 | led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); | 
|  | 2294 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 
|  | 2295 | IXGBE_WRITE_FLUSH(hw); | 
|  | 2296 |  | 
|  | 2297 | return 0; | 
|  | 2298 | } | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2299 |  | 
|  | 2300 | /** | 
|  | 2301 | *  ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM | 
|  | 2302 | *  @hw: pointer to hardware structure | 
|  | 2303 | *  @san_mac_offset: SAN MAC address offset | 
|  | 2304 | * | 
|  | 2305 | *  This function will read the EEPROM location for the SAN MAC address | 
|  | 2306 | *  pointer, and returns the value at that location.  This is used in both | 
|  | 2307 | *  get and set mac_addr routines. | 
|  | 2308 | **/ | 
|  | 2309 | static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, | 
|  | 2310 | u16 *san_mac_offset) | 
|  | 2311 | { | 
|  | 2312 | /* | 
|  | 2313 | * First read the EEPROM pointer to see if the MAC addresses are | 
|  | 2314 | * available. | 
|  | 2315 | */ | 
|  | 2316 | hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); | 
|  | 2317 |  | 
|  | 2318 | return 0; | 
|  | 2319 | } | 
|  | 2320 |  | 
|  | 2321 | /** | 
|  | 2322 | *  ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM | 
|  | 2323 | *  @hw: pointer to hardware structure | 
|  | 2324 | *  @san_mac_addr: SAN MAC address | 
|  | 2325 | * | 
|  | 2326 | *  Reads the SAN MAC address from the EEPROM, if it's available.  This is | 
|  | 2327 | *  per-port, so set_lan_id() must be called before reading the addresses. | 
|  | 2328 | *  set_lan_id() is called by identify_sfp(), but this cannot be relied | 
|  | 2329 | *  upon for non-SFP connections, so we must call it here. | 
|  | 2330 | **/ | 
|  | 2331 | s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) | 
|  | 2332 | { | 
|  | 2333 | u16 san_mac_data, san_mac_offset; | 
|  | 2334 | u8 i; | 
|  | 2335 |  | 
|  | 2336 | /* | 
|  | 2337 | * First read the EEPROM pointer to see if the MAC addresses are | 
|  | 2338 | * available.  If they're not, no point in calling set_lan_id() here. | 
|  | 2339 | */ | 
|  | 2340 | ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); | 
|  | 2341 |  | 
|  | 2342 | if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { | 
|  | 2343 | /* | 
|  | 2344 | * No addresses available in this EEPROM.  It's not an | 
|  | 2345 | * error though, so just wipe the local address and return. | 
|  | 2346 | */ | 
|  | 2347 | for (i = 0; i < 6; i++) | 
|  | 2348 | san_mac_addr[i] = 0xFF; | 
|  | 2349 |  | 
|  | 2350 | goto san_mac_addr_out; | 
|  | 2351 | } | 
|  | 2352 |  | 
|  | 2353 | /* make sure we know which port we need to program */ | 
|  | 2354 | hw->mac.ops.set_lan_id(hw); | 
|  | 2355 | /* apply the port offset to the address offset */ | 
|  | 2356 | (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : | 
|  | 2357 | (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); | 
|  | 2358 | for (i = 0; i < 3; i++) { | 
|  | 2359 | hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); | 
|  | 2360 | san_mac_addr[i * 2] = (u8)(san_mac_data); | 
|  | 2361 | san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); | 
|  | 2362 | san_mac_offset++; | 
|  | 2363 | } | 
|  | 2364 |  | 
|  | 2365 | san_mac_addr_out: | 
|  | 2366 | return 0; | 
|  | 2367 | } | 
|  | 2368 |  | 
|  | 2369 | /** | 
|  | 2370 | *  ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count | 
|  | 2371 | *  @hw: pointer to hardware structure | 
|  | 2372 | * | 
|  | 2373 | *  Read PCIe configuration space, and get the MSI-X vector count from | 
|  | 2374 | *  the capabilities table. | 
|  | 2375 | **/ | 
|  | 2376 | u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) | 
|  | 2377 | { | 
|  | 2378 | struct ixgbe_adapter *adapter = hw->back; | 
|  | 2379 | u16 msix_count; | 
|  | 2380 | pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82599_CAPS, | 
|  | 2381 | &msix_count); | 
|  | 2382 | msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; | 
|  | 2383 |  | 
|  | 2384 | /* MSI-X count is zero-based in HW, so increment to give proper value */ | 
|  | 2385 | msix_count++; | 
|  | 2386 |  | 
|  | 2387 | return msix_count; | 
|  | 2388 | } | 
|  | 2389 |  | 
|  | 2390 | /** | 
|  | 2391 | *  ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address | 
|  | 2392 | *  @hw: pointer to hardware struct | 
|  | 2393 | *  @rar: receive address register index to disassociate | 
|  | 2394 | *  @vmdq: VMDq pool index to remove from the rar | 
|  | 2395 | **/ | 
|  | 2396 | s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
|  | 2397 | { | 
|  | 2398 | u32 mpsar_lo, mpsar_hi; | 
|  | 2399 | u32 rar_entries = hw->mac.num_rar_entries; | 
|  | 2400 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 2401 | /* Make sure we are using a valid rar index range */ | 
|  | 2402 | if (rar >= rar_entries) { | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2403 | hw_dbg(hw, "RAR index %d is out of range.\n", rar); | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 2404 | return IXGBE_ERR_INVALID_ARGUMENT; | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2405 | } | 
|  | 2406 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 2407 | mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); | 
|  | 2408 | mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); | 
|  | 2409 |  | 
|  | 2410 | if (!mpsar_lo && !mpsar_hi) | 
|  | 2411 | goto done; | 
|  | 2412 |  | 
|  | 2413 | if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { | 
|  | 2414 | if (mpsar_lo) { | 
|  | 2415 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); | 
|  | 2416 | mpsar_lo = 0; | 
|  | 2417 | } | 
|  | 2418 | if (mpsar_hi) { | 
|  | 2419 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); | 
|  | 2420 | mpsar_hi = 0; | 
|  | 2421 | } | 
|  | 2422 | } else if (vmdq < 32) { | 
|  | 2423 | mpsar_lo &= ~(1 << vmdq); | 
|  | 2424 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); | 
|  | 2425 | } else { | 
|  | 2426 | mpsar_hi &= ~(1 << (vmdq - 32)); | 
|  | 2427 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); | 
|  | 2428 | } | 
|  | 2429 |  | 
|  | 2430 | /* was that the last pool using this rar? */ | 
|  | 2431 | if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) | 
|  | 2432 | hw->mac.ops.clear_rar(hw, rar); | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2433 | done: | 
|  | 2434 | return 0; | 
|  | 2435 | } | 
|  | 2436 |  | 
|  | 2437 | /** | 
|  | 2438 | *  ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address | 
|  | 2439 | *  @hw: pointer to hardware struct | 
|  | 2440 | *  @rar: receive address register index to associate with a VMDq index | 
|  | 2441 | *  @vmdq: VMDq pool index | 
|  | 2442 | **/ | 
|  | 2443 | s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
|  | 2444 | { | 
|  | 2445 | u32 mpsar; | 
|  | 2446 | u32 rar_entries = hw->mac.num_rar_entries; | 
|  | 2447 |  | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 2448 | /* Make sure we are using a valid rar index range */ | 
|  | 2449 | if (rar >= rar_entries) { | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2450 | hw_dbg(hw, "RAR index %d is out of range.\n", rar); | 
| Emil Tantilov | c700f4e | 2011-02-17 11:34:58 +0000 | [diff] [blame] | 2451 | return IXGBE_ERR_INVALID_ARGUMENT; | 
|  | 2452 | } | 
|  | 2453 |  | 
|  | 2454 | if (vmdq < 32) { | 
|  | 2455 | mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); | 
|  | 2456 | mpsar |= 1 << vmdq; | 
|  | 2457 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); | 
|  | 2458 | } else { | 
|  | 2459 | mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); | 
|  | 2460 | mpsar |= 1 << (vmdq - 32); | 
|  | 2461 | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2462 | } | 
|  | 2463 | return 0; | 
|  | 2464 | } | 
|  | 2465 |  | 
|  | 2466 | /** | 
|  | 2467 | *  ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array | 
|  | 2468 | *  @hw: pointer to hardware structure | 
|  | 2469 | **/ | 
|  | 2470 | s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) | 
|  | 2471 | { | 
|  | 2472 | int i; | 
|  | 2473 |  | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2474 | for (i = 0; i < 128; i++) | 
|  | 2475 | IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); | 
|  | 2476 |  | 
|  | 2477 | return 0; | 
|  | 2478 | } | 
|  | 2479 |  | 
|  | 2480 | /** | 
|  | 2481 | *  ixgbe_find_vlvf_slot - find the vlanid or the first empty slot | 
|  | 2482 | *  @hw: pointer to hardware structure | 
|  | 2483 | *  @vlan: VLAN id to write to VLAN filter | 
|  | 2484 | * | 
|  | 2485 | *  return the VLVF index where this VLAN id should be placed | 
|  | 2486 | * | 
|  | 2487 | **/ | 
| Emil Tantilov | 5d5b7c3 | 2010-10-12 22:20:59 +0000 | [diff] [blame] | 2488 | static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2489 | { | 
|  | 2490 | u32 bits = 0; | 
|  | 2491 | u32 first_empty_slot = 0; | 
|  | 2492 | s32 regindex; | 
|  | 2493 |  | 
|  | 2494 | /* short cut the special case */ | 
|  | 2495 | if (vlan == 0) | 
|  | 2496 | return 0; | 
|  | 2497 |  | 
|  | 2498 | /* | 
|  | 2499 | * Search for the vlan id in the VLVF entries. Save off the first empty | 
|  | 2500 | * slot found along the way | 
|  | 2501 | */ | 
|  | 2502 | for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { | 
|  | 2503 | bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); | 
|  | 2504 | if (!bits && !(first_empty_slot)) | 
|  | 2505 | first_empty_slot = regindex; | 
|  | 2506 | else if ((bits & 0x0FFF) == vlan) | 
|  | 2507 | break; | 
|  | 2508 | } | 
|  | 2509 |  | 
|  | 2510 | /* | 
|  | 2511 | * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan | 
|  | 2512 | * in the VLVF. Else use the first empty VLVF register for this | 
|  | 2513 | * vlan id. | 
|  | 2514 | */ | 
|  | 2515 | if (regindex >= IXGBE_VLVF_ENTRIES) { | 
|  | 2516 | if (first_empty_slot) | 
|  | 2517 | regindex = first_empty_slot; | 
|  | 2518 | else { | 
|  | 2519 | hw_dbg(hw, "No space in VLVF.\n"); | 
|  | 2520 | regindex = IXGBE_ERR_NO_SPACE; | 
|  | 2521 | } | 
|  | 2522 | } | 
|  | 2523 |  | 
|  | 2524 | return regindex; | 
|  | 2525 | } | 
|  | 2526 |  | 
|  | 2527 | /** | 
|  | 2528 | *  ixgbe_set_vfta_generic - Set VLAN filter table | 
|  | 2529 | *  @hw: pointer to hardware structure | 
|  | 2530 | *  @vlan: VLAN id to write to VLAN filter | 
|  | 2531 | *  @vind: VMDq output index that maps queue to VLAN id in VFVFB | 
|  | 2532 | *  @vlan_on: boolean flag to turn on/off VLAN in VFVF | 
|  | 2533 | * | 
|  | 2534 | *  Turn on/off specified VLAN in the VLAN filter table. | 
|  | 2535 | **/ | 
|  | 2536 | s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, | 
|  | 2537 | bool vlan_on) | 
|  | 2538 | { | 
|  | 2539 | s32 regindex; | 
|  | 2540 | u32 bitindex; | 
|  | 2541 | u32 vfta; | 
|  | 2542 | u32 bits; | 
|  | 2543 | u32 vt; | 
|  | 2544 | u32 targetbit; | 
|  | 2545 | bool vfta_changed = false; | 
|  | 2546 |  | 
|  | 2547 | if (vlan > 4095) | 
|  | 2548 | return IXGBE_ERR_PARAM; | 
|  | 2549 |  | 
|  | 2550 | /* | 
|  | 2551 | * this is a 2 part operation - first the VFTA, then the | 
|  | 2552 | * VLVF and VLVFB if VT Mode is set | 
|  | 2553 | * We don't write the VFTA until we know the VLVF part succeeded. | 
|  | 2554 | */ | 
|  | 2555 |  | 
|  | 2556 | /* Part 1 | 
|  | 2557 | * The VFTA is a bitstring made up of 128 32-bit registers | 
|  | 2558 | * that enable the particular VLAN id, much like the MTA: | 
|  | 2559 | *    bits[11-5]: which register | 
|  | 2560 | *    bits[4-0]:  which bit in the register | 
|  | 2561 | */ | 
|  | 2562 | regindex = (vlan >> 5) & 0x7F; | 
|  | 2563 | bitindex = vlan & 0x1F; | 
|  | 2564 | targetbit = (1 << bitindex); | 
|  | 2565 | vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); | 
|  | 2566 |  | 
|  | 2567 | if (vlan_on) { | 
|  | 2568 | if (!(vfta & targetbit)) { | 
|  | 2569 | vfta |= targetbit; | 
|  | 2570 | vfta_changed = true; | 
|  | 2571 | } | 
|  | 2572 | } else { | 
|  | 2573 | if ((vfta & targetbit)) { | 
|  | 2574 | vfta &= ~targetbit; | 
|  | 2575 | vfta_changed = true; | 
|  | 2576 | } | 
|  | 2577 | } | 
|  | 2578 |  | 
|  | 2579 | /* Part 2 | 
|  | 2580 | * If VT Mode is set | 
|  | 2581 | *   Either vlan_on | 
|  | 2582 | *     make sure the vlan is in VLVF | 
|  | 2583 | *     set the vind bit in the matching VLVFB | 
|  | 2584 | *   Or !vlan_on | 
|  | 2585 | *     clear the pool bit and possibly the vind | 
|  | 2586 | */ | 
|  | 2587 | vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); | 
|  | 2588 | if (vt & IXGBE_VT_CTL_VT_ENABLE) { | 
|  | 2589 | s32 vlvf_index; | 
|  | 2590 |  | 
|  | 2591 | vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); | 
|  | 2592 | if (vlvf_index < 0) | 
|  | 2593 | return vlvf_index; | 
|  | 2594 |  | 
|  | 2595 | if (vlan_on) { | 
|  | 2596 | /* set the pool bit */ | 
|  | 2597 | if (vind < 32) { | 
|  | 2598 | bits = IXGBE_READ_REG(hw, | 
|  | 2599 | IXGBE_VLVFB(vlvf_index*2)); | 
|  | 2600 | bits |= (1 << vind); | 
|  | 2601 | IXGBE_WRITE_REG(hw, | 
|  | 2602 | IXGBE_VLVFB(vlvf_index*2), | 
|  | 2603 | bits); | 
|  | 2604 | } else { | 
|  | 2605 | bits = IXGBE_READ_REG(hw, | 
|  | 2606 | IXGBE_VLVFB((vlvf_index*2)+1)); | 
|  | 2607 | bits |= (1 << (vind-32)); | 
|  | 2608 | IXGBE_WRITE_REG(hw, | 
|  | 2609 | IXGBE_VLVFB((vlvf_index*2)+1), | 
|  | 2610 | bits); | 
|  | 2611 | } | 
|  | 2612 | } else { | 
|  | 2613 | /* clear the pool bit */ | 
|  | 2614 | if (vind < 32) { | 
|  | 2615 | bits = IXGBE_READ_REG(hw, | 
|  | 2616 | IXGBE_VLVFB(vlvf_index*2)); | 
|  | 2617 | bits &= ~(1 << vind); | 
|  | 2618 | IXGBE_WRITE_REG(hw, | 
|  | 2619 | IXGBE_VLVFB(vlvf_index*2), | 
|  | 2620 | bits); | 
|  | 2621 | bits |= IXGBE_READ_REG(hw, | 
|  | 2622 | IXGBE_VLVFB((vlvf_index*2)+1)); | 
|  | 2623 | } else { | 
|  | 2624 | bits = IXGBE_READ_REG(hw, | 
|  | 2625 | IXGBE_VLVFB((vlvf_index*2)+1)); | 
|  | 2626 | bits &= ~(1 << (vind-32)); | 
|  | 2627 | IXGBE_WRITE_REG(hw, | 
|  | 2628 | IXGBE_VLVFB((vlvf_index*2)+1), | 
|  | 2629 | bits); | 
|  | 2630 | bits |= IXGBE_READ_REG(hw, | 
|  | 2631 | IXGBE_VLVFB(vlvf_index*2)); | 
|  | 2632 | } | 
|  | 2633 | } | 
|  | 2634 |  | 
|  | 2635 | /* | 
|  | 2636 | * If there are still bits set in the VLVFB registers | 
|  | 2637 | * for the VLAN ID indicated we need to see if the | 
|  | 2638 | * caller is requesting that we clear the VFTA entry bit. | 
|  | 2639 | * If the caller has requested that we clear the VFTA | 
|  | 2640 | * entry bit but there are still pools/VFs using this VLAN | 
|  | 2641 | * ID entry then ignore the request.  We're not worried | 
|  | 2642 | * about the case where we're turning the VFTA VLAN ID | 
|  | 2643 | * entry bit on, only when requested to turn it off as | 
|  | 2644 | * there may be multiple pools and/or VFs using the | 
|  | 2645 | * VLAN ID entry.  In that case we cannot clear the | 
|  | 2646 | * VFTA bit until all pools/VFs using that VLAN ID have also | 
|  | 2647 | * been cleared.  This will be indicated by "bits" being | 
|  | 2648 | * zero. | 
|  | 2649 | */ | 
|  | 2650 | if (bits) { | 
|  | 2651 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), | 
|  | 2652 | (IXGBE_VLVF_VIEN | vlan)); | 
|  | 2653 | if (!vlan_on) { | 
|  | 2654 | /* someone wants to clear the vfta entry | 
|  | 2655 | * but some pools/VFs are still using it. | 
|  | 2656 | * Ignore it. */ | 
|  | 2657 | vfta_changed = false; | 
|  | 2658 | } | 
|  | 2659 | } | 
|  | 2660 | else | 
|  | 2661 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); | 
|  | 2662 | } | 
|  | 2663 |  | 
|  | 2664 | if (vfta_changed) | 
|  | 2665 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); | 
|  | 2666 |  | 
|  | 2667 | return 0; | 
|  | 2668 | } | 
|  | 2669 |  | 
|  | 2670 | /** | 
|  | 2671 | *  ixgbe_clear_vfta_generic - Clear VLAN filter table | 
|  | 2672 | *  @hw: pointer to hardware structure | 
|  | 2673 | * | 
|  | 2674 | *  Clears the VLAN filer table, and the VMDq index associated with the filter | 
|  | 2675 | **/ | 
|  | 2676 | s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) | 
|  | 2677 | { | 
|  | 2678 | u32 offset; | 
|  | 2679 |  | 
|  | 2680 | for (offset = 0; offset < hw->mac.vft_size; offset++) | 
|  | 2681 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | 
|  | 2682 |  | 
|  | 2683 | for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { | 
|  | 2684 | IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); | 
|  | 2685 | IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); | 
|  | 2686 | IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); | 
|  | 2687 | } | 
|  | 2688 |  | 
|  | 2689 | return 0; | 
|  | 2690 | } | 
|  | 2691 |  | 
|  | 2692 | /** | 
|  | 2693 | *  ixgbe_check_mac_link_generic - Determine link and speed status | 
|  | 2694 | *  @hw: pointer to hardware structure | 
|  | 2695 | *  @speed: pointer to link speed | 
|  | 2696 | *  @link_up: true when link is up | 
|  | 2697 | *  @link_up_wait_to_complete: bool used to wait for link up or not | 
|  | 2698 | * | 
|  | 2699 | *  Reads the links register to determine if link is up and the current speed | 
|  | 2700 | **/ | 
|  | 2701 | s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, | 
| Emil Tantilov | 8c7bea3 | 2011-02-19 08:43:44 +0000 | [diff] [blame] | 2702 | bool *link_up, bool link_up_wait_to_complete) | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2703 | { | 
| Emil Tantilov | 48de36c | 2011-02-16 01:38:08 +0000 | [diff] [blame] | 2704 | u32 links_reg, links_orig; | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2705 | u32 i; | 
|  | 2706 |  | 
| Emil Tantilov | 48de36c | 2011-02-16 01:38:08 +0000 | [diff] [blame] | 2707 | /* clear the old state */ | 
|  | 2708 | links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
|  | 2709 |  | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2710 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
| Emil Tantilov | 48de36c | 2011-02-16 01:38:08 +0000 | [diff] [blame] | 2711 |  | 
|  | 2712 | if (links_orig != links_reg) { | 
|  | 2713 | hw_dbg(hw, "LINKS changed from %08X to %08X\n", | 
|  | 2714 | links_orig, links_reg); | 
|  | 2715 | } | 
|  | 2716 |  | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2717 | if (link_up_wait_to_complete) { | 
|  | 2718 | for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { | 
|  | 2719 | if (links_reg & IXGBE_LINKS_UP) { | 
|  | 2720 | *link_up = true; | 
|  | 2721 | break; | 
|  | 2722 | } else { | 
|  | 2723 | *link_up = false; | 
|  | 2724 | } | 
|  | 2725 | msleep(100); | 
|  | 2726 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
|  | 2727 | } | 
|  | 2728 | } else { | 
|  | 2729 | if (links_reg & IXGBE_LINKS_UP) | 
|  | 2730 | *link_up = true; | 
|  | 2731 | else | 
|  | 2732 | *link_up = false; | 
|  | 2733 | } | 
|  | 2734 |  | 
|  | 2735 | if ((links_reg & IXGBE_LINKS_SPEED_82599) == | 
|  | 2736 | IXGBE_LINKS_SPEED_10G_82599) | 
|  | 2737 | *speed = IXGBE_LINK_SPEED_10GB_FULL; | 
|  | 2738 | else if ((links_reg & IXGBE_LINKS_SPEED_82599) == | 
| Emil Tantilov | 63d778d | 2011-02-19 08:43:39 +0000 | [diff] [blame] | 2739 | IXGBE_LINKS_SPEED_1G_82599) | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2740 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 
| Emil Tantilov | 63d778d | 2011-02-19 08:43:39 +0000 | [diff] [blame] | 2741 | else if ((links_reg & IXGBE_LINKS_SPEED_82599) == | 
|  | 2742 | IXGBE_LINKS_SPEED_100_82599) | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2743 | *speed = IXGBE_LINK_SPEED_100_FULL; | 
| Emil Tantilov | 63d778d | 2011-02-19 08:43:39 +0000 | [diff] [blame] | 2744 | else | 
|  | 2745 | *speed = IXGBE_LINK_SPEED_UNKNOWN; | 
| Mallikarjuna R Chilakala | 21ce849 | 2010-05-13 17:33:41 +0000 | [diff] [blame] | 2746 |  | 
|  | 2747 | /* if link is down, zero out the current_mode */ | 
|  | 2748 | if (*link_up == false) { | 
|  | 2749 | hw->fc.current_mode = ixgbe_fc_none; | 
|  | 2750 | hw->fc.fc_was_autonegged = false; | 
|  | 2751 | } | 
|  | 2752 |  | 
|  | 2753 | return 0; | 
|  | 2754 | } | 
| Don Skidmore | a391f1d | 2010-11-16 19:27:15 -0800 | [diff] [blame] | 2755 |  | 
|  | 2756 | /** | 
|  | 2757 | *  ixgbe_get_wwn_prefix_generic Get alternative WWNN/WWPN prefix from | 
|  | 2758 | *  the EEPROM | 
|  | 2759 | *  @hw: pointer to hardware structure | 
|  | 2760 | *  @wwnn_prefix: the alternative WWNN prefix | 
|  | 2761 | *  @wwpn_prefix: the alternative WWPN prefix | 
|  | 2762 | * | 
|  | 2763 | *  This function will read the EEPROM from the alternative SAN MAC address | 
|  | 2764 | *  block to check the support for the alternative WWNN/WWPN prefix support. | 
|  | 2765 | **/ | 
|  | 2766 | s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, | 
|  | 2767 | u16 *wwpn_prefix) | 
|  | 2768 | { | 
|  | 2769 | u16 offset, caps; | 
|  | 2770 | u16 alt_san_mac_blk_offset; | 
|  | 2771 |  | 
|  | 2772 | /* clear output first */ | 
|  | 2773 | *wwnn_prefix = 0xFFFF; | 
|  | 2774 | *wwpn_prefix = 0xFFFF; | 
|  | 2775 |  | 
|  | 2776 | /* check if alternative SAN MAC is supported */ | 
|  | 2777 | hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, | 
|  | 2778 | &alt_san_mac_blk_offset); | 
|  | 2779 |  | 
|  | 2780 | if ((alt_san_mac_blk_offset == 0) || | 
|  | 2781 | (alt_san_mac_blk_offset == 0xFFFF)) | 
|  | 2782 | goto wwn_prefix_out; | 
|  | 2783 |  | 
|  | 2784 | /* check capability in alternative san mac address block */ | 
|  | 2785 | offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; | 
|  | 2786 | hw->eeprom.ops.read(hw, offset, &caps); | 
|  | 2787 | if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) | 
|  | 2788 | goto wwn_prefix_out; | 
|  | 2789 |  | 
|  | 2790 | /* get the corresponding prefix for WWNN/WWPN */ | 
|  | 2791 | offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; | 
|  | 2792 | hw->eeprom.ops.read(hw, offset, wwnn_prefix); | 
|  | 2793 |  | 
|  | 2794 | offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; | 
|  | 2795 | hw->eeprom.ops.read(hw, offset, wwpn_prefix); | 
|  | 2796 |  | 
|  | 2797 | wwn_prefix_out: | 
|  | 2798 | return 0; | 
|  | 2799 | } | 
| Greg Rose | a985b6c3 | 2010-11-18 03:02:52 +0000 | [diff] [blame] | 2800 |  | 
|  | 2801 | /** | 
| Emil Tantilov | 0b0c2b3 | 2011-02-26 06:40:16 +0000 | [diff] [blame] | 2802 | *  ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow | 
|  | 2803 | *  control | 
|  | 2804 | *  @hw: pointer to hardware structure | 
|  | 2805 | * | 
|  | 2806 | *  There are several phys that do not support autoneg flow control. This | 
|  | 2807 | *  function check the device id to see if the associated phy supports | 
|  | 2808 | *  autoneg flow control. | 
|  | 2809 | **/ | 
|  | 2810 | static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) | 
|  | 2811 | { | 
|  | 2812 |  | 
|  | 2813 | switch (hw->device_id) { | 
|  | 2814 | case IXGBE_DEV_ID_X540T: | 
|  | 2815 | return 0; | 
|  | 2816 | case IXGBE_DEV_ID_82599_T3_LOM: | 
|  | 2817 | return 0; | 
|  | 2818 | default: | 
|  | 2819 | return IXGBE_ERR_FC_NOT_SUPPORTED; | 
|  | 2820 | } | 
|  | 2821 | } | 
|  | 2822 |  | 
|  | 2823 | /** | 
| Greg Rose | a985b6c3 | 2010-11-18 03:02:52 +0000 | [diff] [blame] | 2824 | *  ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing | 
|  | 2825 | *  @hw: pointer to hardware structure | 
|  | 2826 | *  @enable: enable or disable switch for anti-spoofing | 
|  | 2827 | *  @pf: Physical Function pool - do not enable anti-spoofing for the PF | 
|  | 2828 | * | 
|  | 2829 | **/ | 
|  | 2830 | void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) | 
|  | 2831 | { | 
|  | 2832 | int j; | 
|  | 2833 | int pf_target_reg = pf >> 3; | 
|  | 2834 | int pf_target_shift = pf % 8; | 
|  | 2835 | u32 pfvfspoof = 0; | 
|  | 2836 |  | 
|  | 2837 | if (hw->mac.type == ixgbe_mac_82598EB) | 
|  | 2838 | return; | 
|  | 2839 |  | 
|  | 2840 | if (enable) | 
|  | 2841 | pfvfspoof = IXGBE_SPOOF_MACAS_MASK; | 
|  | 2842 |  | 
|  | 2843 | /* | 
|  | 2844 | * PFVFSPOOF register array is size 8 with 8 bits assigned to | 
|  | 2845 | * MAC anti-spoof enables in each register array element. | 
|  | 2846 | */ | 
|  | 2847 | for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) | 
|  | 2848 | IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); | 
|  | 2849 |  | 
|  | 2850 | /* If not enabling anti-spoofing then done */ | 
|  | 2851 | if (!enable) | 
|  | 2852 | return; | 
|  | 2853 |  | 
|  | 2854 | /* | 
|  | 2855 | * The PF should be allowed to spoof so that it can support | 
|  | 2856 | * emulation mode NICs.  Reset the bit assigned to the PF | 
|  | 2857 | */ | 
|  | 2858 | pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg)); | 
|  | 2859 | pfvfspoof ^= (1 << pf_target_shift); | 
|  | 2860 | IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof); | 
|  | 2861 | } | 
|  | 2862 |  | 
|  | 2863 | /** | 
|  | 2864 | *  ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing | 
|  | 2865 | *  @hw: pointer to hardware structure | 
|  | 2866 | *  @enable: enable or disable switch for VLAN anti-spoofing | 
|  | 2867 | *  @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing | 
|  | 2868 | * | 
|  | 2869 | **/ | 
|  | 2870 | void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) | 
|  | 2871 | { | 
|  | 2872 | int vf_target_reg = vf >> 3; | 
|  | 2873 | int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT; | 
|  | 2874 | u32 pfvfspoof; | 
|  | 2875 |  | 
|  | 2876 | if (hw->mac.type == ixgbe_mac_82598EB) | 
|  | 2877 | return; | 
|  | 2878 |  | 
|  | 2879 | pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); | 
|  | 2880 | if (enable) | 
|  | 2881 | pfvfspoof |= (1 << vf_target_shift); | 
|  | 2882 | else | 
|  | 2883 | pfvfspoof &= ~(1 << vf_target_shift); | 
|  | 2884 | IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); | 
|  | 2885 | } |