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