diff options
author | Don Skidmore <donald.c.skidmore@intel.com> | 2010-12-02 22:32:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-03 12:39:11 -0500 |
commit | 289700dbc40c78741f17e2304ed4ac0db3c3afd3 (patch) | |
tree | 0584bcfb5253d908723dd75dfb228f76ddaecb9c /drivers/net/ixgbe/ixgbe_common.c | |
parent | dbffcb210f45239ea530e0a71470e48abefe4210 (diff) |
ixgbe: add support for new format of PBA numbers
The new PBA format is stored as a string. This patch allows the
driver to support both the old and new format.
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_common.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.c | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 56052570cac5..cc11e422ce9b 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -196,30 +196,110 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | /** | 198 | /** |
199 | * ixgbe_read_pba_num_generic - Reads part number from EEPROM | 199 | * ixgbe_read_pba_string_generic - Reads part number string from EEPROM |
200 | * @hw: pointer to hardware structure | 200 | * @hw: pointer to hardware structure |
201 | * @pba_num: stores the part number from the EEPROM | 201 | * @pba_num: stores the part number string from the EEPROM |
202 | * @pba_num_size: part number string buffer length | ||
202 | * | 203 | * |
203 | * Reads the part number from the EEPROM. | 204 | * Reads the part number string from the EEPROM. |
204 | **/ | 205 | **/ |
205 | s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) | 206 | s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, |
207 | u32 pba_num_size) | ||
206 | { | 208 | { |
207 | s32 ret_val; | 209 | s32 ret_val; |
208 | u16 data; | 210 | u16 data; |
211 | u16 pba_ptr; | ||
212 | u16 offset; | ||
213 | u16 length; | ||
214 | |||
215 | if (pba_num == NULL) { | ||
216 | hw_dbg(hw, "PBA string buffer was null\n"); | ||
217 | return IXGBE_ERR_INVALID_ARGUMENT; | ||
218 | } | ||
209 | 219 | ||
210 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); | 220 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); |
211 | if (ret_val) { | 221 | if (ret_val) { |
212 | hw_dbg(hw, "NVM Read Error\n"); | 222 | hw_dbg(hw, "NVM Read Error\n"); |
213 | return ret_val; | 223 | return ret_val; |
214 | } | 224 | } |
215 | *pba_num = (u32)(data << 16); | ||
216 | 225 | ||
217 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); | 226 | ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); |
218 | if (ret_val) { | 227 | if (ret_val) { |
219 | hw_dbg(hw, "NVM Read Error\n"); | 228 | hw_dbg(hw, "NVM Read Error\n"); |
220 | return ret_val; | 229 | return ret_val; |
221 | } | 230 | } |
222 | *pba_num |= data; | 231 | |
232 | /* | ||
233 | * if data is not ptr guard the PBA must be in legacy format which | ||
234 | * means pba_ptr is actually our second data word for the PBA number | ||
235 | * and we can decode it into an ascii string | ||
236 | */ | ||
237 | if (data != IXGBE_PBANUM_PTR_GUARD) { | ||
238 | hw_dbg(hw, "NVM PBA number is not stored as string\n"); | ||
239 | |||
240 | /* we will need 11 characters to store the PBA */ | ||
241 | if (pba_num_size < 11) { | ||
242 | hw_dbg(hw, "PBA string buffer too small\n"); | ||
243 | return IXGBE_ERR_NO_SPACE; | ||
244 | } | ||
245 | |||
246 | /* extract hex string from data and pba_ptr */ | ||
247 | pba_num[0] = (data >> 12) & 0xF; | ||
248 | pba_num[1] = (data >> 8) & 0xF; | ||
249 | pba_num[2] = (data >> 4) & 0xF; | ||
250 | pba_num[3] = data & 0xF; | ||
251 | pba_num[4] = (pba_ptr >> 12) & 0xF; | ||
252 | pba_num[5] = (pba_ptr >> 8) & 0xF; | ||
253 | pba_num[6] = '-'; | ||
254 | pba_num[7] = 0; | ||
255 | pba_num[8] = (pba_ptr >> 4) & 0xF; | ||
256 | pba_num[9] = pba_ptr & 0xF; | ||
257 | |||
258 | /* put a null character on the end of our string */ | ||
259 | pba_num[10] = '\0'; | ||
260 | |||
261 | /* switch all the data but the '-' to hex char */ | ||
262 | for (offset = 0; offset < 10; offset++) { | ||
263 | if (pba_num[offset] < 0xA) | ||
264 | pba_num[offset] += '0'; | ||
265 | else if (pba_num[offset] < 0x10) | ||
266 | pba_num[offset] += 'A' - 0xA; | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); | ||
273 | if (ret_val) { | ||
274 | hw_dbg(hw, "NVM Read Error\n"); | ||
275 | return ret_val; | ||
276 | } | ||
277 | |||
278 | if (length == 0xFFFF || length == 0) { | ||
279 | hw_dbg(hw, "NVM PBA number section invalid length\n"); | ||
280 | return IXGBE_ERR_PBA_SECTION; | ||
281 | } | ||
282 | |||
283 | /* check if pba_num buffer is big enough */ | ||
284 | if (pba_num_size < (((u32)length * 2) - 1)) { | ||
285 | hw_dbg(hw, "PBA string buffer too small\n"); | ||
286 | return IXGBE_ERR_NO_SPACE; | ||
287 | } | ||
288 | |||
289 | /* trim pba length from start of string */ | ||
290 | pba_ptr++; | ||
291 | length--; | ||
292 | |||
293 | for (offset = 0; offset < length; offset++) { | ||
294 | ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); | ||
295 | if (ret_val) { | ||
296 | hw_dbg(hw, "NVM Read Error\n"); | ||
297 | return ret_val; | ||
298 | } | ||
299 | pba_num[offset * 2] = (u8)(data >> 8); | ||
300 | pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); | ||
301 | } | ||
302 | pba_num[offset * 2] = '\0'; | ||
223 | 303 | ||
224 | return 0; | 304 | return 0; |
225 | } | 305 | } |