devices/e1000e/nvm-3.16-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2588 792892ab4806
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2588
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/* Intel PRO/1000 Linux driver
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 * Copyright(c) 1999 - 2014 Intel Corporation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 * This program is free software; you can redistribute it and/or modify it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 * under the terms and conditions of the GNU General Public License,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 * version 2, as published by the Free Software Foundation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 * This program is distributed in the hope it will be useful, but WITHOUT
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
 * more details.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
 * The full GNU General Public License is included in this distribution in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
 * the file called "COPYING".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
 * Contact Information:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
 * Linux NICS <linux.nics@intel.com>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
#include "e1000.h"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
 *  e1000_raise_eec_clk - Raise EEPROM clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 *  @eecd: pointer to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
 *  Enable/Raise the EEPROM clock bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
	*eecd = *eecd | E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
	ew32(EECD, *eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
	udelay(hw->nvm.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 *  e1000_lower_eec_clk - Lower EEPROM clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 *  @eecd: pointer to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 *  Clear/Lower the EEPROM clock bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	*eecd = *eecd & ~E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	ew32(EECD, *eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	udelay(hw->nvm.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
 *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
 *  @data: data to send to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
 *  @count: number of bits to shift out
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
 *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
 *  "data" parameter will be shifted out to the EEPROM one bit at a time.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
 *  In order to do this, "data" must be broken down into bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	struct e1000_nvm_info *nvm = &hw->nvm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	u32 eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	u32 mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	mask = 0x01 << (count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	if (nvm->type == e1000_nvm_eeprom_spi)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
		eecd |= E1000_EECD_DO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	do {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
		eecd &= ~E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
		if (data & mask)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
			eecd |= E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
		udelay(nvm->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
		e1000_raise_eec_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
		e1000_lower_eec_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
		mask >>= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	} while (mask);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	eecd &= ~E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
 *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
 *  @count: number of bits to shift in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
 *  In order to read a register from the EEPROM, we need to shift 'count' bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
 *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
 *  the EEPROM (setting the SK bit), and then reading the value of the data out
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 *  always be clear.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	u16 data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	for (i = 0; i < count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
		data <<= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
		e1000_raise_eec_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
		eecd &= ~E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
		if (eecd & E1000_EECD_DO)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
			data |= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
		e1000_lower_eec_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	return data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
 *  e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 *  @ee_reg: EEPROM flag for polling
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
 *  Polls the EEPROM status bit for either read or write completion based
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
 *  upon the value of 'ee_reg'.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	u32 attempts = 100000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	u32 i, reg = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	for (i = 0; i < attempts; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
		if (ee_reg == E1000_NVM_POLL_READ)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			reg = er32(EERD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
			reg = er32(EEWR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
		if (reg & E1000_NVM_RW_REG_DONE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
		udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
 *  e1000e_acquire_nvm - Generic request for access to EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
 *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
 *  Return successful if access grant bit set, else clear the request for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
 *  EEPROM access and return -E1000_ERR_NVM (-1).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
s32 e1000e_acquire_nvm(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	u32 eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	ew32(EECD, eecd | E1000_EECD_REQ);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	while (timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		if (eecd & E1000_EECD_GNT)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
		udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
		eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
		timeout--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	if (!timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
		eecd &= ~E1000_EECD_REQ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
		e_dbg("Could not acquire NVM grant\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
 *  e1000_standby_nvm - Return EEPROM to standby state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
 *  Return the EEPROM to a standby state.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
static void e1000_standby_nvm(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	struct e1000_nvm_info *nvm = &hw->nvm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	u32 eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	if (nvm->type == e1000_nvm_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
		/* Toggle CS to flush commands */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		eecd |= E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
		udelay(nvm->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
		eecd &= ~E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		udelay(nvm->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 *  e1000_stop_nvm - Terminate EEPROM command
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
 *  Terminates the current command by inverting the EEPROM's chip select pin.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
static void e1000_stop_nvm(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
		/* Pull CS high */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
		eecd |= E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
		e1000_lower_eec_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
 *  e1000e_release_nvm - Release exclusive access to EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
 *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
void e1000e_release_nvm(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	e1000_stop_nvm(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	eecd &= ~E1000_EECD_REQ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
 *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 *  Setups the EEPROM for reading and writing.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	struct e1000_nvm_info *nvm = &hw->nvm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	u32 eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	u8 spi_stat_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	if (nvm->type == e1000_nvm_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		u16 timeout = NVM_MAX_RETRY_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		/* Clear SK and CS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		udelay(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		/* Read "Status Register" repeatedly until the LSB is cleared.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		 * The EEPROM will signal that the command has been completed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		 * by clearing bit 0 of the internal status register.  If it's
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		 * not cleared within 'timeout', then error out.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		while (timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
						 hw->nvm.opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
			udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			e1000_standby_nvm(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
			timeout--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		if (!timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
			e_dbg("SPI NVM Status error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
			return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
 *  e1000e_read_nvm_eerd - Reads EEPROM using EERD register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
 *  @offset: offset of word in the EEPROM to read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
 *  @words: number of words to read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
 *  @data: word read from the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
 *  Reads a 16 bit word from the EEPROM using the EERD register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	struct e1000_nvm_info *nvm = &hw->nvm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	u32 i, eerd = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	s32 ret_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	/* A check for invalid values:  offset too large, too many words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	 * too many words for the offset, and not enough words.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	    (words == 0)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		e_dbg("nvm parameter(s) out of bounds\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	for (i = 0; i < words; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		    E1000_NVM_RW_REG_START;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		ew32(EERD, eerd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
 *  e1000e_write_nvm_spi - Write to EEPROM using SPI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
 *  @offset: offset within the EEPROM to be written to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
 *  @words: number of words to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
 *  @data: 16 bit word(s) to be written to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
 *  Writes data to EEPROM at offset using SPI interface.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
 *  If e1000e_update_nvm_checksum is not called after this function , the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
 *  EEPROM will most likely contain an invalid checksum.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	struct e1000_nvm_info *nvm = &hw->nvm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	s32 ret_val = -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	u16 widx = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	/* A check for invalid values:  offset too large, too many words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	 * and not enough words.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
	    (words == 0)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		e_dbg("nvm parameter(s) out of bounds\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	while (widx < words) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		ret_val = nvm->ops.acquire(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		ret_val = e1000_ready_nvm_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
			nvm->ops.release(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		e1000_standby_nvm(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		/* Send the WRITE ENABLE command (8 bit opcode) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
					 nvm->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		e1000_standby_nvm(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		/* Some SPI eeproms use the 8th address bit embedded in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		 * opcode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		if ((nvm->address_bits == 8) && (offset >= 128))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
			write_opcode |= NVM_A8_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		/* Send the Write command (8-bit opcode + addr) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
					 nvm->address_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		/* Loop to allow for up to whole page write of eeprom */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		while (widx < words) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
			u16 word_out = data[widx];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
			word_out = (word_out >> 8) | (word_out << 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
			e1000_shift_out_eec_bits(hw, word_out, 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
			widx++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
				e1000_standby_nvm(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		nvm->ops.release(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
 *  e1000_read_pba_string_generic - Read device part number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 *  @pba_num: pointer to device part number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
 *  @pba_num_size: size of part number buffer
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 *  Reads the product board assembly (PBA) number from the EEPROM and stores
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 *  the value in pba_num.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
				  u32 pba_num_size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	u16 nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	u16 pba_ptr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	u16 offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	u16 length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	if (pba_num == NULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		e_dbg("PBA string buffer was null\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		return -E1000_ERR_INVALID_ARGUMENT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	/* if nvm_data is not ptr guard the PBA must be in legacy format which
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	 * means pba_ptr is actually our second data word for the PBA number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 * and we can decode it into an ascii string
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	if (nvm_data != NVM_PBA_PTR_GUARD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		e_dbg("NVM PBA number is not stored as string\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		/* make sure callers buffer is big enough to store the PBA */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		if (pba_num_size < E1000_PBANUM_LENGTH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
			e_dbg("PBA string buffer too small\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
			return E1000_ERR_NO_SPACE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		/* extract hex string from data and pba_ptr */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		pba_num[0] = (nvm_data >> 12) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		pba_num[1] = (nvm_data >> 8) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
		pba_num[2] = (nvm_data >> 4) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		pba_num[3] = nvm_data & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		pba_num[4] = (pba_ptr >> 12) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		pba_num[5] = (pba_ptr >> 8) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		pba_num[6] = '-';
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		pba_num[7] = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		pba_num[8] = (pba_ptr >> 4) & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		pba_num[9] = pba_ptr & 0xF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		/* put a null character on the end of our string */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		pba_num[10] = '\0';
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		/* switch all the data but the '-' to hex char */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		for (offset = 0; offset < 10; offset++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
			if (pba_num[offset] < 0xA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
				pba_num[offset] += '0';
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
			else if (pba_num[offset] < 0x10)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
				pba_num[offset] += 'A' - 0xA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	if (length == 0xFFFF || length == 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		e_dbg("NVM PBA number section invalid length\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		return -E1000_ERR_NVM_PBA_SECTION;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	/* check if pba_num buffer is big enough */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	if (pba_num_size < (((u32)length * 2) - 1)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		e_dbg("PBA string buffer too small\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		return -E1000_ERR_NO_SPACE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	/* trim pba length from start of string */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	pba_ptr++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	length--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	for (offset = 0; offset < length; offset++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
			e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		pba_num[offset * 2] = (u8)(nvm_data >> 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	pba_num[offset * 2] = '\0';
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
 *  e1000_read_mac_addr_generic - Read device MAC address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
 *  Reads the device MAC address from the EEPROM and stores the value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
 *  Since devices with two ports use the same EEPROM, we increment the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
 *  last bit in the MAC address for the second port.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	u32 rar_high;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	u32 rar_low;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	u16 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	rar_high = er32(RAH(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	rar_low = er32(RAL(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	for (i = 0; i < ETH_ALEN; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		hw->mac.addr[i] = hw->mac.perm_addr[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
 *  e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
 *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
 *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	u16 checksum = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	u16 i, nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
			e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		checksum += nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	if (checksum != (u16)NVM_SUM) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		e_dbg("NVM Checksum Invalid\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
 *  e1000e_update_nvm_checksum_generic - Update EEPROM checksum
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
 *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
 *  up to the checksum.  Then calculates the EEPROM checksum and writes the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
 *  value to the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	u16 checksum = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	u16 i, nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
			e_dbg("NVM Read Error while updating checksum.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		checksum += nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	checksum = (u16)NVM_SUM - checksum;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		e_dbg("NVM Write Error while updating checksum.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
 *  e1000e_reload_nvm_generic - Reloads EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
 *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
 *  extended control register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
void e1000e_reload_nvm_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	usleep_range(10, 20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
}