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