e1000_ich8lan.c revision 169240
1169240Sjfv/*******************************************************************************
2169240Sjfv
3169240Sjfv  Copyright (c) 2001-2007, Intel Corporation
4169240Sjfv  All rights reserved.
5169240Sjfv
6169240Sjfv  Redistribution and use in source and binary forms, with or without
7169240Sjfv  modification, are permitted provided that the following conditions are met:
8169240Sjfv
9169240Sjfv   1. Redistributions of source code must retain the above copyright notice,
10169240Sjfv      this list of conditions and the following disclaimer.
11169240Sjfv
12169240Sjfv   2. Redistributions in binary form must reproduce the above copyright
13169240Sjfv      notice, this list of conditions and the following disclaimer in the
14169240Sjfv      documentation and/or other materials provided with the distribution.
15169240Sjfv
16169240Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17169240Sjfv      contributors may be used to endorse or promote products derived from
18169240Sjfv      this software without specific prior written permission.
19169240Sjfv
20169240Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21169240Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22169240Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23169240Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24169240Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25169240Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26169240Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27169240Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28169240Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29169240Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30169240Sjfv  POSSIBILITY OF SUCH DAMAGE.
31169240Sjfv
32169240Sjfv*******************************************************************************/
33169240Sjfv$FreeBSD: head/sys/dev/em/e1000_ich8lan.c 169240 2007-05-04 00:00:12Z jfv $
34169240Sjfv
35169240Sjfv
36169240Sjfv/* e1000_ich8lan
37169240Sjfv * e1000_ich9lan
38169240Sjfv */
39169240Sjfv
40169240Sjfv#include "e1000_ich8lan.h"
41169240Sjfv
42169240Sjfvvoid e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
43169240Sjfv
44169240SjfvSTATIC s32       e1000_init_phy_params_ich8lan(struct e1000_hw *hw);
45169240SjfvSTATIC s32       e1000_init_nvm_params_ich8lan(struct e1000_hw *hw);
46169240SjfvSTATIC s32       e1000_init_mac_params_ich8lan(struct e1000_hw *hw);
47169240SjfvSTATIC s32       e1000_acquire_swflag_ich8lan(struct e1000_hw *hw);
48169240SjfvSTATIC void      e1000_release_swflag_ich8lan(struct e1000_hw *hw);
49169240SjfvSTATIC boolean_t e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
50169240SjfvSTATIC s32       e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw);
51169240SjfvSTATIC s32       e1000_check_reset_block_ich8lan(struct e1000_hw *hw);
52169240SjfvSTATIC s32       e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw);
53169240SjfvSTATIC s32       e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw);
54169240SjfvSTATIC s32       e1000_get_phy_info_ich8lan(struct e1000_hw *hw);
55169240SjfvSTATIC s32       e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw,
56169240Sjfv                                                 boolean_t active);
57169240SjfvSTATIC s32       e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw,
58169240Sjfv                                                 boolean_t active);
59169240SjfvSTATIC s32       e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
60169240Sjfv                                        u16 words, u16 *data);
61169240SjfvSTATIC s32       e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
62169240Sjfv                                         u16 words, u16 *data);
63169240SjfvSTATIC s32       e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw);
64169240SjfvSTATIC s32       e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw);
65169240SjfvSTATIC s32       e1000_valid_led_default_ich8lan(struct e1000_hw *hw,
66169240Sjfv                                                 u16 *data);
67169240SjfvSTATIC s32       e1000_get_bus_info_ich8lan(struct e1000_hw *hw);
68169240SjfvSTATIC s32       e1000_reset_hw_ich8lan(struct e1000_hw *hw);
69169240SjfvSTATIC s32       e1000_init_hw_ich8lan(struct e1000_hw *hw);
70169240SjfvSTATIC s32       e1000_setup_link_ich8lan(struct e1000_hw *hw);
71169240SjfvSTATIC s32       e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
72169240SjfvSTATIC s32       e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
73169240Sjfv                                                u16 *speed, u16 *duplex);
74169240SjfvSTATIC s32       e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
75169240SjfvSTATIC s32       e1000_led_on_ich8lan(struct e1000_hw *hw);
76169240SjfvSTATIC s32       e1000_led_off_ich8lan(struct e1000_hw *hw);
77169240SjfvSTATIC void      e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
78169240SjfvSTATIC s32       e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
79169240Sjfvstatic s32       e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout);
80169240Sjfvstatic s32       e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw);
81169240Sjfvstatic s32       e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw);
82169240Sjfvstatic void      e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
83169240Sjfvstatic s32       e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
84169240Sjfvstatic s32       e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
85169240Sjfv                                               u8 size, u16* data);
86169240SjfvSTATIC s32       e1000_read_flash_word_ich8lan(struct e1000_hw *hw,
87169240Sjfv                                               u32 offset, u16 *data);
88169240Sjfvstatic s32       e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
89169240Sjfv                                                      u32 offset, u8 byte);
90169240SjfvSTATIC s32       e1000_write_flash_byte_ich8lan(struct e1000_hw *hw,
91169240Sjfv                                                u32 offset, u8 data);
92169240Sjfvstatic s32       e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
93169240Sjfv                                                u8 size, u16 data);
94169240SjfvSTATIC s32	 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
95169240Sjfv
96169240Sjfv/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
97169240Sjfv/* Offset 04h HSFSTS */
98169240Sjfvunion ich8_hws_flash_status {
99169240Sjfv	struct ich8_hsfsts {
100169240Sjfv		u16 flcdone    :1; /* bit 0 Flash Cycle Done */
101169240Sjfv		u16 flcerr     :1; /* bit 1 Flash Cycle Error */
102169240Sjfv		u16 dael       :1; /* bit 2 Direct Access error Log */
103169240Sjfv		u16 berasesz   :2; /* bit 4:3 Sector Erase Size */
104169240Sjfv		u16 flcinprog  :1; /* bit 5 flash cycle in Progress */
105169240Sjfv		u16 reserved1  :2; /* bit 13:6 Reserved */
106169240Sjfv		u16 reserved2  :6; /* bit 13:6 Reserved */
107169240Sjfv		u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
108169240Sjfv		u16 flockdn    :1; /* bit 15 Flash Config Lock-Down */
109169240Sjfv	} hsf_status;
110169240Sjfv	u16 regval;
111169240Sjfv};
112169240Sjfv
113169240Sjfv/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
114169240Sjfv/* Offset 06h FLCTL */
115169240Sjfvunion ich8_hws_flash_ctrl {
116169240Sjfv	struct ich8_hsflctl {
117169240Sjfv		u16 flcgo      :1;   /* 0 Flash Cycle Go */
118169240Sjfv		u16 flcycle    :2;   /* 2:1 Flash Cycle */
119169240Sjfv		u16 reserved   :5;   /* 7:3 Reserved  */
120169240Sjfv		u16 fldbcount  :2;   /* 9:8 Flash Data Byte Count */
121169240Sjfv		u16 flockdn    :6;   /* 15:10 Reserved */
122169240Sjfv	} hsf_ctrl;
123169240Sjfv	u16 regval;
124169240Sjfv};
125169240Sjfv
126169240Sjfv/* ICH Flash Region Access Permissions */
127169240Sjfvunion ich8_hws_flash_regacc {
128169240Sjfv	struct ich8_flracc {
129169240Sjfv		u32 grra      :8; /* 0:7 GbE region Read Access */
130169240Sjfv		u32 grwa      :8; /* 8:15 GbE region Write Access */
131169240Sjfv		u32 gmrag     :8; /* 23:16 GbE Master Read Access Grant */
132169240Sjfv		u32 gmwag     :8; /* 31:24 GbE Master Write Access Grant */
133169240Sjfv	} hsf_flregacc;
134169240Sjfv	u16 regval;
135169240Sjfv};
136169240Sjfv
137169240Sjfvstruct e1000_shadow_ram {
138169240Sjfv	u16  value;
139169240Sjfv	boolean_t modified;
140169240Sjfv};
141169240Sjfv
142169240Sjfvstruct e1000_dev_spec_ich8lan {
143169240Sjfv	boolean_t kmrn_lock_loss_workaround_enabled;
144169240Sjfv	struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS];
145169240Sjfv};
146169240Sjfv
147169240Sjfv/**
148169240Sjfv *  e1000_init_phy_params_ich8lan - Initialize PHY function pointers
149169240Sjfv *  @hw - pointer to the HW structure
150169240Sjfv *
151169240Sjfv *  Initialize family-specific PHY parameters and function pointers.
152169240Sjfv **/
153169240SjfvSTATIC s32
154169240Sjfve1000_init_phy_params_ich8lan(struct e1000_hw *hw)
155169240Sjfv{
156169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
157169240Sjfv	struct e1000_functions *func = &hw->func;
158169240Sjfv	s32 ret_val = E1000_SUCCESS;
159169240Sjfv
160169240Sjfv	DEBUGFUNC("e1000_init_phy_params_ich8lan");
161169240Sjfv
162169240Sjfv	phy->addr                       = 1;
163169240Sjfv	phy->reset_delay_us             = 100;
164169240Sjfv
165169240Sjfv	func->acquire_phy               = e1000_acquire_swflag_ich8lan;
166169240Sjfv	func->check_polarity            = e1000_check_polarity_ife_ich8lan;
167169240Sjfv	func->check_reset_block         = e1000_check_reset_block_ich8lan;
168169240Sjfv	func->force_speed_duplex        = e1000_phy_force_speed_duplex_ich8lan;
169169240Sjfv	func->get_cable_length          = e1000_get_cable_length_igp_2;
170169240Sjfv	func->get_cfg_done              = e1000_get_cfg_done_ich8lan;
171169240Sjfv	func->get_phy_info              = e1000_get_phy_info_ich8lan;
172169240Sjfv	func->read_phy_reg              = e1000_read_phy_reg_igp;
173169240Sjfv	func->release_phy               = e1000_release_swflag_ich8lan;
174169240Sjfv	func->reset_phy                 = e1000_phy_hw_reset_ich8lan;
175169240Sjfv	func->set_d0_lplu_state         = e1000_set_d0_lplu_state_ich8lan;
176169240Sjfv	func->set_d3_lplu_state         = e1000_set_d3_lplu_state_ich8lan;
177169240Sjfv	func->write_phy_reg             = e1000_write_phy_reg_igp;
178169240Sjfv
179169240Sjfv	ret_val = e1000_get_phy_id(hw);
180169240Sjfv	if (ret_val)
181169240Sjfv		goto out;
182169240Sjfv
183169240Sjfv	/* Verify phy id */
184169240Sjfv	switch (phy->id) {
185169240Sjfv	case IGP03E1000_E_PHY_ID:
186169240Sjfv		phy->type = e1000_phy_igp_3;
187169240Sjfv		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
188169240Sjfv		break;
189169240Sjfv	case IFE_E_PHY_ID:
190169240Sjfv	case IFE_PLUS_E_PHY_ID:
191169240Sjfv	case IFE_C_E_PHY_ID:
192169240Sjfv		phy->type = e1000_phy_ife;
193169240Sjfv		phy->autoneg_mask = E1000_ALL_NOT_GIG;
194169240Sjfv		break;
195169240Sjfv	default:
196169240Sjfv		ret_val = -E1000_ERR_PHY;
197169240Sjfv		goto out;
198169240Sjfv	}
199169240Sjfv
200169240Sjfvout:
201169240Sjfv	return ret_val;
202169240Sjfv}
203169240Sjfv
204169240Sjfv/**
205169240Sjfv *  e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
206169240Sjfv *  @hw - pointer to the HW structure
207169240Sjfv *
208169240Sjfv *  Initialize family-specific NVM parameters and function
209169240Sjfv *  pointers.
210169240Sjfv **/
211169240SjfvSTATIC s32
212169240Sjfve1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
213169240Sjfv{
214169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
215169240Sjfv	struct e1000_functions *func = &hw->func;
216169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
217169240Sjfv	u32 gfpreg, sector_base_addr, sector_end_addr;
218169240Sjfv	s32  ret_val = E1000_SUCCESS;
219169240Sjfv	u16 i;
220169240Sjfv
221169240Sjfv	DEBUGFUNC("e1000_init_nvm_params_ich8lan");
222169240Sjfv
223169240Sjfv	/* Can't read flash registers if the register set isn't mapped.
224169240Sjfv	 */
225169240Sjfv	if (!hw->flash_address) {
226169240Sjfv		DEBUGOUT("ERROR: Flash registers not mapped\n");
227169240Sjfv		ret_val = -E1000_ERR_CONFIG;
228169240Sjfv		goto out;
229169240Sjfv	}
230169240Sjfv
231169240Sjfv	nvm->type               = e1000_nvm_flash_sw;
232169240Sjfv
233169240Sjfv	gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
234169240Sjfv
235169240Sjfv	/* sector_X_addr is a "sector"-aligned address (4096 bytes)
236169240Sjfv	 * Add 1 to sector_end_addr since this sector is included in
237169240Sjfv	 * the overall size. */
238169240Sjfv	sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
239169240Sjfv	sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
240169240Sjfv
241169240Sjfv	/* flash_base_addr is byte-aligned */
242169240Sjfv	nvm->flash_base_addr    = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
243169240Sjfv
244169240Sjfv	/* find total size of the NVM, then cut in half since the total
245169240Sjfv	 * size represents two separate NVM banks. */
246169240Sjfv	nvm->flash_bank_size    = (sector_end_addr - sector_base_addr)
247169240Sjfv	                          << FLASH_SECTOR_ADDR_SHIFT;
248169240Sjfv	nvm->flash_bank_size    /= 2;
249169240Sjfv	/* Adjust to word count */
250169240Sjfv	nvm->flash_bank_size    /= sizeof(u16);
251169240Sjfv
252169240Sjfv	nvm->word_size          = E1000_SHADOW_RAM_WORDS;
253169240Sjfv
254169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
255169240Sjfv
256169240Sjfv	if (dev_spec == NULL) {
257169240Sjfv		DEBUGOUT("dev_spec pointer is set to NULL.\n");
258169240Sjfv		ret_val = -E1000_ERR_CONFIG;
259169240Sjfv		goto out;
260169240Sjfv	}
261169240Sjfv
262169240Sjfv	/* Clear shadow ram */
263169240Sjfv	for (i = 0; i < nvm->word_size; i++) {
264169240Sjfv		dev_spec->shadow_ram[i].modified = FALSE;
265169240Sjfv		dev_spec->shadow_ram[i].value    = 0xFFFF;
266169240Sjfv	}
267169240Sjfv
268169240Sjfv	/* Function Pointers */
269169240Sjfv	func->acquire_nvm       = e1000_acquire_swflag_ich8lan;
270169240Sjfv	func->read_nvm          = e1000_read_nvm_ich8lan;
271169240Sjfv	func->release_nvm       = e1000_release_swflag_ich8lan;
272169240Sjfv	func->update_nvm        = e1000_update_nvm_checksum_ich8lan;
273169240Sjfv	func->valid_led_default = e1000_valid_led_default_ich8lan;
274169240Sjfv	func->validate_nvm      = e1000_validate_nvm_checksum_ich8lan;
275169240Sjfv	func->write_nvm         = e1000_write_nvm_ich8lan;
276169240Sjfv
277169240Sjfvout:
278169240Sjfv	return ret_val;
279169240Sjfv}
280169240Sjfv
281169240Sjfv/**
282169240Sjfv *  e1000_init_mac_params_ich8lan - Initialize MAC function pointers
283169240Sjfv *  @hw - pointer to the HW structure
284169240Sjfv *
285169240Sjfv *  Initialize family-specific MAC parameters and function
286169240Sjfv *  pointers.
287169240Sjfv **/
288169240SjfvSTATIC s32
289169240Sjfve1000_init_mac_params_ich8lan(struct e1000_hw *hw)
290169240Sjfv{
291169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
292169240Sjfv	struct e1000_functions *func = &hw->func;
293169240Sjfv	s32 ret_val = E1000_SUCCESS;
294169240Sjfv
295169240Sjfv	DEBUGFUNC("e1000_init_mac_params_ich8lan");
296169240Sjfv
297169240Sjfv	/* Set media type function pointer */
298169240Sjfv	hw->media_type = e1000_media_type_copper;
299169240Sjfv
300169240Sjfv	/* Set mta register count */
301169240Sjfv	mac->mta_reg_count = 32;
302169240Sjfv	/* Set rar entry count */
303169240Sjfv	mac->rar_entry_count = E1000_ICH_RAR_ENTRIES;
304169240Sjfv	if (mac->type == e1000_ich8lan)
305169240Sjfv		mac->rar_entry_count--;
306169240Sjfv	/* Set if part includes ASF firmware */
307169240Sjfv	mac->asf_firmware_present = TRUE;
308169240Sjfv	/* Set if manageability features are enabled. */
309169240Sjfv	mac->arc_subsystem_valid = TRUE;
310169240Sjfv
311169240Sjfv	/* Function pointers */
312169240Sjfv
313169240Sjfv	/* bus type/speed/width */
314169240Sjfv	func->get_bus_info = e1000_get_bus_info_ich8lan;
315169240Sjfv	/* reset */
316169240Sjfv	func->reset_hw = e1000_reset_hw_ich8lan;
317169240Sjfv	/* hw initialization */
318169240Sjfv	func->init_hw = e1000_init_hw_ich8lan;
319169240Sjfv	/* link setup */
320169240Sjfv	func->setup_link = e1000_setup_link_ich8lan;
321169240Sjfv	/* physical interface setup */
322169240Sjfv	func->setup_physical_interface = e1000_setup_copper_link_ich8lan;
323169240Sjfv	/* check for link */
324169240Sjfv	func->check_for_link = e1000_check_for_copper_link_generic;
325169240Sjfv	/* check management mode */
326169240Sjfv	func->check_mng_mode = e1000_check_mng_mode_ich8lan;
327169240Sjfv	/* link info */
328169240Sjfv	func->get_link_up_info = e1000_get_link_up_info_ich8lan;
329169240Sjfv	/* multicast address update */
330169240Sjfv	func->mc_addr_list_update = e1000_mc_addr_list_update_generic;
331169240Sjfv	/* setting MTA */
332169240Sjfv	func->mta_set = e1000_mta_set_generic;
333169240Sjfv	/* blink LED */
334169240Sjfv	func->blink_led = e1000_blink_led_generic;
335169240Sjfv	/* setup LED */
336169240Sjfv	func->setup_led = e1000_setup_led_generic;
337169240Sjfv	/* cleanup LED */
338169240Sjfv	func->cleanup_led = e1000_cleanup_led_ich8lan;
339169240Sjfv	/* turn on/off LED */
340169240Sjfv	func->led_on = e1000_led_on_ich8lan;
341169240Sjfv	func->led_off = e1000_led_off_ich8lan;
342169240Sjfv	/* remove device */
343169240Sjfv	func->remove_device = e1000_remove_device_generic;
344169240Sjfv	/* clear hardware counters */
345169240Sjfv	func->clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan;
346169240Sjfv
347169240Sjfv	hw->dev_spec_size = sizeof(struct e1000_dev_spec_ich8lan);
348169240Sjfv
349169240Sjfv	/* Device-specific structure allocation */
350169240Sjfv	ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
351169240Sjfv	if (ret_val)
352169240Sjfv		goto out;
353169240Sjfv
354169240Sjfv	/* Enable PCS Lock-loss workaround for ICH8 */
355169240Sjfv	if (mac->type == e1000_ich8lan)
356169240Sjfv		e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, TRUE);
357169240Sjfv
358169240Sjfv
359169240Sjfvout:
360169240Sjfv	return ret_val;
361169240Sjfv}
362169240Sjfv
363169240Sjfv/**
364169240Sjfv *  e1000_init_function_pointers_ich8lan - Initialize ICH8 function pointers
365169240Sjfv *  @hw - pointer to the HW structure
366169240Sjfv *
367169240Sjfv *  Initialize family-specific function pointers for PHY, MAC, and NVM.
368169240Sjfv **/
369169240Sjfvvoid
370169240Sjfve1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
371169240Sjfv{
372169240Sjfv	DEBUGFUNC("e1000_init_function_pointers_ich8lan");
373169240Sjfv
374169240Sjfv	hw->func.init_mac_params = e1000_init_mac_params_ich8lan;
375169240Sjfv	hw->func.init_nvm_params = e1000_init_nvm_params_ich8lan;
376169240Sjfv	hw->func.init_phy_params = e1000_init_phy_params_ich8lan;
377169240Sjfv}
378169240Sjfv
379169240Sjfv/**
380169240Sjfv *  e1000_acquire_swflag_ich8lan - Acquire software control flag
381169240Sjfv *  @hw - pointer to the HW structure
382169240Sjfv *
383169240Sjfv *  Acquires the software control flag for performing NVM and PHY
384169240Sjfv *  operations.  This is a function pointer entry point only called by
385169240Sjfv *  read/write routines for the PHY and NVM parts.
386169240Sjfv **/
387169240SjfvSTATIC s32
388169240Sjfve1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
389169240Sjfv{
390169240Sjfv	u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
391169240Sjfv	s32 ret_val = E1000_SUCCESS;
392169240Sjfv
393169240Sjfv	DEBUGFUNC("e1000_acquire_swflag_ich8lan");
394169240Sjfv
395169240Sjfv	while (timeout) {
396169240Sjfv		extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
397169240Sjfv		extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
398169240Sjfv		E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
399169240Sjfv
400169240Sjfv		extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
401169240Sjfv		if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
402169240Sjfv			break;
403169240Sjfv		msec_delay_irq(1);
404169240Sjfv		timeout--;
405169240Sjfv	}
406169240Sjfv
407169240Sjfv	if (!timeout) {
408169240Sjfv		DEBUGOUT("FW or HW has locked the resource for too long.\n");
409169240Sjfv		ret_val = -E1000_ERR_CONFIG;
410169240Sjfv		goto out;
411169240Sjfv	}
412169240Sjfv
413169240Sjfvout:
414169240Sjfv	return ret_val;
415169240Sjfv}
416169240Sjfv
417169240Sjfv/**
418169240Sjfv *  e1000_release_swflag_ich8lan - Release software control flag
419169240Sjfv *  @hw - pointer to the HW structure
420169240Sjfv *
421169240Sjfv *  Releases the software control flag for performing NVM and PHY operations.
422169240Sjfv *  This is a function pointer entry point only called by read/write
423169240Sjfv *  routines for the PHY and NVM parts.
424169240Sjfv **/
425169240SjfvSTATIC void
426169240Sjfve1000_release_swflag_ich8lan(struct e1000_hw *hw)
427169240Sjfv{
428169240Sjfv	u32 extcnf_ctrl;
429169240Sjfv
430169240Sjfv	DEBUGFUNC("e1000_release_swflag_ich8lan");
431169240Sjfv
432169240Sjfv	extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
433169240Sjfv	extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
434169240Sjfv	E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
435169240Sjfv
436169240Sjfv	return;
437169240Sjfv}
438169240Sjfv
439169240Sjfv/**
440169240Sjfv *  e1000_check_mng_mode_ich8lan - Checks management mode
441169240Sjfv *  @hw - pointer to the HW structure
442169240Sjfv *
443169240Sjfv *  This checks if the adapter has manageability enabled.
444169240Sjfv *  This is a function pointer entry point only called by read/write
445169240Sjfv *  routines for the PHY and NVM parts.
446169240Sjfv **/
447169240SjfvSTATIC boolean_t
448169240Sjfve1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
449169240Sjfv{
450169240Sjfv	u32 fwsm;
451169240Sjfv
452169240Sjfv	DEBUGFUNC("e1000_check_mng_mode_ich8lan");
453169240Sjfv
454169240Sjfv	fwsm = E1000_READ_REG(hw, E1000_FWSM);
455169240Sjfv
456169240Sjfv	return ((fwsm & E1000_FWSM_MODE_MASK) ==
457169240Sjfv	        (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
458169240Sjfv}
459169240Sjfv
460169240Sjfv/**
461169240Sjfv *  e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
462169240Sjfv *  @hw - pointer to the HW structure
463169240Sjfv *
464169240Sjfv *  Checks if firmware is blocking the reset of the PHY.
465169240Sjfv *  This is a function pointer entry point only called by
466169240Sjfv *  reset routines.
467169240Sjfv **/
468169240SjfvSTATIC s32
469169240Sjfve1000_check_reset_block_ich8lan(struct e1000_hw *hw)
470169240Sjfv{
471169240Sjfv	u32 fwsm;
472169240Sjfv
473169240Sjfv	DEBUGFUNC("e1000_check_reset_block_ich8lan");
474169240Sjfv
475169240Sjfv	fwsm = E1000_READ_REG(hw, E1000_FWSM);
476169240Sjfv
477169240Sjfv	return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS
478169240Sjfv	                                        : E1000_BLK_PHY_RESET;
479169240Sjfv}
480169240Sjfv
481169240Sjfv/**
482169240Sjfv *  e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex
483169240Sjfv *  @hw - pointer to the HW structure
484169240Sjfv *
485169240Sjfv *  Forces the speed and duplex settings of the PHY.
486169240Sjfv *  This is a function pointer entry point only called by
487169240Sjfv *  PHY setup routines.
488169240Sjfv **/
489169240SjfvSTATIC s32
490169240Sjfve1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
491169240Sjfv{
492169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
493169240Sjfv	s32 ret_val;
494169240Sjfv	u16 data;
495169240Sjfv	boolean_t link;
496169240Sjfv
497169240Sjfv	DEBUGFUNC("e1000_phy_force_speed_duplex_ich8lan");
498169240Sjfv
499169240Sjfv	if (phy->type != e1000_phy_ife) {
500169240Sjfv		ret_val = e1000_phy_force_speed_duplex_igp(hw);
501169240Sjfv		goto out;
502169240Sjfv	}
503169240Sjfv
504169240Sjfv	ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &data);
505169240Sjfv	if (ret_val)
506169240Sjfv		goto out;
507169240Sjfv
508169240Sjfv	e1000_phy_force_speed_duplex_setup(hw, &data);
509169240Sjfv
510169240Sjfv	ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, data);
511169240Sjfv	if (ret_val)
512169240Sjfv		goto out;
513169240Sjfv
514169240Sjfv	/* Disable MDI-X support for 10/100 */
515169240Sjfv	ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
516169240Sjfv	if (ret_val)
517169240Sjfv		goto out;
518169240Sjfv
519169240Sjfv	data &= ~IFE_PMC_AUTO_MDIX;
520169240Sjfv	data &= ~IFE_PMC_FORCE_MDIX;
521169240Sjfv
522169240Sjfv	ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, data);
523169240Sjfv	if (ret_val)
524169240Sjfv		goto out;
525169240Sjfv
526169240Sjfv	DEBUGOUT1("IFE PMC: %X\n", data);
527169240Sjfv
528169240Sjfv	usec_delay(1);
529169240Sjfv
530169240Sjfv	if (phy->wait_for_link) {
531169240Sjfv		DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
532169240Sjfv
533169240Sjfv		ret_val = e1000_phy_has_link_generic(hw,
534169240Sjfv		                                     PHY_FORCE_LIMIT,
535169240Sjfv		                                     100000,
536169240Sjfv		                                     &link);
537169240Sjfv		if (ret_val)
538169240Sjfv			goto out;
539169240Sjfv
540169240Sjfv		if (!link) {
541169240Sjfv			DEBUGOUT("Link taking longer than expected.\n");
542169240Sjfv		}
543169240Sjfv
544169240Sjfv		/* Try once more */
545169240Sjfv		ret_val = e1000_phy_has_link_generic(hw,
546169240Sjfv		                                     PHY_FORCE_LIMIT,
547169240Sjfv		                                     100000,
548169240Sjfv		                                     &link);
549169240Sjfv		if (ret_val)
550169240Sjfv			goto out;
551169240Sjfv	}
552169240Sjfv
553169240Sjfvout:
554169240Sjfv	return ret_val;
555169240Sjfv}
556169240Sjfv
557169240Sjfv/**
558169240Sjfv *  e1000_phy_hw_reset_ich8lan - Performs a PHY reset
559169240Sjfv *  @hw - pointer to the HW structure
560169240Sjfv *
561169240Sjfv *  Resets the PHY
562169240Sjfv *  This is a function pointer entry point called by drivers
563169240Sjfv *  or other shared routines.
564169240Sjfv **/
565169240SjfvSTATIC s32
566169240Sjfve1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
567169240Sjfv{
568169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
569169240Sjfv	u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
570169240Sjfv	s32 ret_val;
571169240Sjfv	u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT;
572169240Sjfv	u16 word_addr, reg_data, reg_addr, phy_page = 0;
573169240Sjfv
574169240Sjfv	DEBUGFUNC("e1000_phy_hw_reset_ich8lan");
575169240Sjfv
576169240Sjfv	ret_val = e1000_phy_hw_reset_generic(hw);
577169240Sjfv	if (ret_val)
578169240Sjfv		goto out;
579169240Sjfv
580169240Sjfv	/* Initialize the PHY from the NVM on ICH platforms.  This
581169240Sjfv	 * is needed due to an issue where the NVM configuration is
582169240Sjfv	 * not properly autoloaded after power transitions.
583169240Sjfv	 * Therefore, after each PHY reset, we will load the
584169240Sjfv	 * configuration data out of the NVM manually.
585169240Sjfv	 */
586169240Sjfv	if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) {
587169240Sjfv		/* Check if SW needs configure the PHY */
588169240Sjfv		if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
589169240Sjfv		    (hw->device_id == E1000_DEV_ID_ICH8_IGP_M))
590169240Sjfv			sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
591169240Sjfv		else
592169240Sjfv			sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
593169240Sjfv
594169240Sjfv		data = E1000_READ_REG(hw, E1000_FEXTNVM);
595169240Sjfv		if (!(data & sw_cfg_mask))
596169240Sjfv			goto out;
597169240Sjfv
598169240Sjfv		/* Wait for basic configuration completes before proceeding*/
599169240Sjfv		do {
600169240Sjfv			data = E1000_READ_REG(hw, E1000_STATUS);
601169240Sjfv			data &= E1000_STATUS_LAN_INIT_DONE;
602169240Sjfv			usec_delay(100);
603169240Sjfv		} while ((!data) && --loop);
604169240Sjfv
605169240Sjfv		/* If basic configuration is incomplete before the above loop
606169240Sjfv		 * count reaches 0, loading the configuration from NVM will
607169240Sjfv		 * leave the PHY in a bad state possibly resulting in no link.
608169240Sjfv		 */
609169240Sjfv		if (loop == 0) {
610169240Sjfv			DEBUGOUT("LAN_INIT_DONE not set, increase timeout\n");
611169240Sjfv		}
612169240Sjfv
613169240Sjfv		/* Clear the Init Done bit for the next init event */
614169240Sjfv		data = E1000_READ_REG(hw, E1000_STATUS);
615169240Sjfv		data &= ~E1000_STATUS_LAN_INIT_DONE;
616169240Sjfv		E1000_WRITE_REG(hw, E1000_STATUS, data);
617169240Sjfv
618169240Sjfv		/* Make sure HW does not configure LCD from PHY
619169240Sjfv		 * extended configuration before SW configuration */
620169240Sjfv		data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
621169240Sjfv		if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
622169240Sjfv			goto out;
623169240Sjfv
624169240Sjfv		cnf_size = E1000_READ_REG(hw, E1000_EXTCNF_SIZE);
625169240Sjfv		cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
626169240Sjfv		cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
627169240Sjfv		if (!cnf_size)
628169240Sjfv			goto out;
629169240Sjfv
630169240Sjfv		cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
631169240Sjfv		cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
632169240Sjfv
633169240Sjfv		/* Configure LCD from extended configuration
634169240Sjfv		 * region. */
635169240Sjfv
636169240Sjfv		/* cnf_base_addr is in DWORD */
637169240Sjfv		word_addr = (u16)(cnf_base_addr << 1);
638169240Sjfv
639169240Sjfv		for (i = 0; i < cnf_size; i++) {
640169240Sjfv			ret_val = e1000_read_nvm(hw,
641169240Sjfv			                        (word_addr + i * 2),
642169240Sjfv			                        1,
643169240Sjfv			                        &reg_data);
644169240Sjfv			if (ret_val)
645169240Sjfv				goto out;
646169240Sjfv
647169240Sjfv			ret_val = e1000_read_nvm(hw,
648169240Sjfv			                        (word_addr + i * 2 + 1),
649169240Sjfv			                        1,
650169240Sjfv			                        &reg_addr);
651169240Sjfv			if (ret_val)
652169240Sjfv				goto out;
653169240Sjfv
654169240Sjfv			/* Save off the PHY page for future writes. */
655169240Sjfv			if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
656169240Sjfv				phy_page = reg_data;
657169240Sjfv				continue;
658169240Sjfv			}
659169240Sjfv
660169240Sjfv			reg_addr |= phy_page;
661169240Sjfv
662169240Sjfv			ret_val = e1000_write_phy_reg(hw,
663169240Sjfv			                             (u32)reg_addr,
664169240Sjfv			                             reg_data);
665169240Sjfv			if (ret_val)
666169240Sjfv				goto out;
667169240Sjfv		}
668169240Sjfv	}
669169240Sjfv
670169240Sjfvout:
671169240Sjfv	return ret_val;
672169240Sjfv}
673169240Sjfv
674169240Sjfv/**
675169240Sjfv *  e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info
676169240Sjfv *  @hw - pointer to the HW structure
677169240Sjfv *
678169240Sjfv *  Wrapper for calling the get_phy_info routines for the appropriate phy type.
679169240Sjfv *  This is a function pointer entry point called by drivers
680169240Sjfv *  or other shared routines.
681169240Sjfv **/
682169240SjfvSTATIC s32
683169240Sjfve1000_get_phy_info_ich8lan(struct e1000_hw *hw)
684169240Sjfv{
685169240Sjfv	s32 ret_val = -E1000_ERR_PHY_TYPE;
686169240Sjfv
687169240Sjfv	DEBUGFUNC("e1000_get_phy_info_ich8lan");
688169240Sjfv
689169240Sjfv	switch (hw->phy.type) {
690169240Sjfv	case e1000_phy_ife:
691169240Sjfv		ret_val = e1000_get_phy_info_ife_ich8lan(hw);
692169240Sjfv		break;
693169240Sjfv	case e1000_phy_igp_3:
694169240Sjfv		ret_val = e1000_get_phy_info_igp(hw);
695169240Sjfv		break;
696169240Sjfv	default:
697169240Sjfv		break;
698169240Sjfv	}
699169240Sjfv
700169240Sjfv	return ret_val;
701169240Sjfv}
702169240Sjfv
703169240Sjfv/**
704169240Sjfv *  e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states
705169240Sjfv *  @hw - pointer to the HW structure
706169240Sjfv *
707169240Sjfv *  Populates "phy" structure with various feature states.
708169240Sjfv *  This function is only called by other family-specific
709169240Sjfv *  routines.
710169240Sjfv **/
711169240Sjfvstatic s32
712169240Sjfve1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
713169240Sjfv{
714169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
715169240Sjfv	s32 ret_val;
716169240Sjfv	u16 data;
717169240Sjfv	boolean_t link;
718169240Sjfv
719169240Sjfv	DEBUGFUNC("e1000_get_phy_info_ife_ich8lan");
720169240Sjfv
721169240Sjfv	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
722169240Sjfv	if (ret_val)
723169240Sjfv		goto out;
724169240Sjfv
725169240Sjfv	if (!link) {
726169240Sjfv		DEBUGOUT("Phy info is only valid if link is up\n");
727169240Sjfv		ret_val = -E1000_ERR_CONFIG;
728169240Sjfv		goto out;
729169240Sjfv	}
730169240Sjfv
731169240Sjfv	ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data);
732169240Sjfv	if (ret_val)
733169240Sjfv		goto out;
734169240Sjfv	phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE)
735169240Sjfv	                           ? FALSE : TRUE;
736169240Sjfv
737169240Sjfv	if (phy->polarity_correction) {
738169240Sjfv		ret_val = e1000_check_polarity_ife_ich8lan(hw);
739169240Sjfv		if (ret_val)
740169240Sjfv			goto out;
741169240Sjfv	} else {
742169240Sjfv		/* Polarity is forced */
743169240Sjfv		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
744169240Sjfv		                      ? e1000_rev_polarity_reversed
745169240Sjfv		                      : e1000_rev_polarity_normal;
746169240Sjfv	}
747169240Sjfv
748169240Sjfv	ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
749169240Sjfv	if (ret_val)
750169240Sjfv		goto out;
751169240Sjfv
752169240Sjfv	phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? TRUE : FALSE;
753169240Sjfv
754169240Sjfv	/* The following parameters are undefined for 10/100 operation. */
755169240Sjfv	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
756169240Sjfv	phy->local_rx = e1000_1000t_rx_status_undefined;
757169240Sjfv	phy->remote_rx = e1000_1000t_rx_status_undefined;
758169240Sjfv
759169240Sjfvout:
760169240Sjfv	return ret_val;
761169240Sjfv}
762169240Sjfv
763169240Sjfv/**
764169240Sjfv *  e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
765169240Sjfv *  @hw - pointer to the HW structure
766169240Sjfv *
767169240Sjfv *  Polarity is determined on the polarity reveral feature being enabled.
768169240Sjfv *  This function is only called by other family-specific
769169240Sjfv *  routines.
770169240Sjfv **/
771169240SjfvSTATIC s32
772169240Sjfve1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
773169240Sjfv{
774169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
775169240Sjfv	s32 ret_val;
776169240Sjfv	u16 phy_data, offset, mask;
777169240Sjfv
778169240Sjfv	DEBUGFUNC("e1000_check_polarity_ife_ich8lan");
779169240Sjfv
780169240Sjfv	/* Polarity is determined based on the reversal feature
781169240Sjfv	 * being enabled.
782169240Sjfv	 */
783169240Sjfv	if (phy->polarity_correction) {
784169240Sjfv		offset	= IFE_PHY_EXTENDED_STATUS_CONTROL;
785169240Sjfv		mask	= IFE_PESC_POLARITY_REVERSED;
786169240Sjfv	} else {
787169240Sjfv		offset	= IFE_PHY_SPECIAL_CONTROL;
788169240Sjfv		mask	= IFE_PSC_FORCE_POLARITY;
789169240Sjfv	}
790169240Sjfv
791169240Sjfv	ret_val = e1000_read_phy_reg(hw, offset, &phy_data);
792169240Sjfv
793169240Sjfv	if (!ret_val)
794169240Sjfv		phy->cable_polarity = (phy_data & mask)
795169240Sjfv		                      ? e1000_rev_polarity_reversed
796169240Sjfv		                      : e1000_rev_polarity_normal;
797169240Sjfv
798169240Sjfv	return ret_val;
799169240Sjfv}
800169240Sjfv
801169240Sjfv/**
802169240Sjfv *  e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
803169240Sjfv *  @hw - pointer to the HW structure
804169240Sjfv *  @active - TRUE to enable LPLU, FALSE to disable
805169240Sjfv *
806169240Sjfv *  Sets the LPLU D0 state according to the active flag.  When
807169240Sjfv *  activating LPLU this function also disables smart speed
808169240Sjfv *  and vice versa.  LPLU will not be activated unless the
809169240Sjfv *  device autonegotiation advertisement meets standards of
810169240Sjfv *  either 10 or 10/100 or 10/100/1000 at all duplexes.
811169240Sjfv *  This is a function pointer entry point only called by
812169240Sjfv *  PHY setup routines.
813169240Sjfv **/
814169240SjfvSTATIC s32
815169240Sjfve1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active)
816169240Sjfv{
817169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
818169240Sjfv	u32 phy_ctrl;
819169240Sjfv	s32 ret_val = E1000_SUCCESS;
820169240Sjfv	u16 data;
821169240Sjfv
822169240Sjfv	DEBUGFUNC("e1000_set_d0_lplu_state_ich8lan");
823169240Sjfv
824169240Sjfv	if (phy->type != e1000_phy_igp_3)
825169240Sjfv		goto out;
826169240Sjfv
827169240Sjfv	phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
828169240Sjfv
829169240Sjfv	if (active) {
830169240Sjfv		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
831169240Sjfv		E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
832169240Sjfv
833169240Sjfv		/* Call gig speed drop workaround on LPLU before accessing
834169240Sjfv		 * any PHY registers */
835169240Sjfv		if ((hw->mac.type == e1000_ich8lan) &&
836169240Sjfv		    (hw->phy.type == e1000_phy_igp_3))
837169240Sjfv			e1000_gig_downshift_workaround_ich8lan(hw);
838169240Sjfv
839169240Sjfv		/* When LPLU is enabled, we should disable SmartSpeed */
840169240Sjfv		ret_val = e1000_read_phy_reg(hw,
841169240Sjfv		                            IGP01E1000_PHY_PORT_CONFIG,
842169240Sjfv		                            &data);
843169240Sjfv		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
844169240Sjfv		ret_val = e1000_write_phy_reg(hw,
845169240Sjfv		                             IGP01E1000_PHY_PORT_CONFIG,
846169240Sjfv		                             data);
847169240Sjfv		if (ret_val)
848169240Sjfv			goto out;
849169240Sjfv	} else {
850169240Sjfv		phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
851169240Sjfv		E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
852169240Sjfv
853169240Sjfv		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
854169240Sjfv		 * during Dx states where the power conservation is most
855169240Sjfv		 * important.  During driver activity we should enable
856169240Sjfv		 * SmartSpeed, so performance is maintained. */
857169240Sjfv		if (phy->smart_speed == e1000_smart_speed_on) {
858169240Sjfv			ret_val = e1000_read_phy_reg(hw,
859169240Sjfv			                            IGP01E1000_PHY_PORT_CONFIG,
860169240Sjfv			                            &data);
861169240Sjfv			if (ret_val)
862169240Sjfv				goto out;
863169240Sjfv
864169240Sjfv			data |= IGP01E1000_PSCFR_SMART_SPEED;
865169240Sjfv			ret_val = e1000_write_phy_reg(hw,
866169240Sjfv			                             IGP01E1000_PHY_PORT_CONFIG,
867169240Sjfv			                             data);
868169240Sjfv			if (ret_val)
869169240Sjfv				goto out;
870169240Sjfv		} else if (phy->smart_speed == e1000_smart_speed_off) {
871169240Sjfv			ret_val = e1000_read_phy_reg(hw,
872169240Sjfv			                            IGP01E1000_PHY_PORT_CONFIG,
873169240Sjfv			                            &data);
874169240Sjfv			if (ret_val)
875169240Sjfv				goto out;
876169240Sjfv
877169240Sjfv			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
878169240Sjfv			ret_val = e1000_write_phy_reg(hw,
879169240Sjfv			                             IGP01E1000_PHY_PORT_CONFIG,
880169240Sjfv			                             data);
881169240Sjfv			if (ret_val)
882169240Sjfv				goto out;
883169240Sjfv		}
884169240Sjfv	}
885169240Sjfv
886169240Sjfvout:
887169240Sjfv	return ret_val;
888169240Sjfv}
889169240Sjfv
890169240Sjfv/**
891169240Sjfv *  e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state
892169240Sjfv *  @hw - pointer to the HW structure
893169240Sjfv *  @active - TRUE to enable LPLU, FALSE to disable
894169240Sjfv *
895169240Sjfv *  Sets the LPLU D3 state according to the active flag.  When
896169240Sjfv *  activating LPLU this function also disables smart speed
897169240Sjfv *  and vice versa.  LPLU will not be activated unless the
898169240Sjfv *  device autonegotiation advertisement meets standards of
899169240Sjfv *  either 10 or 10/100 or 10/100/1000 at all duplexes.
900169240Sjfv *  This is a function pointer entry point only called by
901169240Sjfv *  PHY setup routines.
902169240Sjfv **/
903169240SjfvSTATIC s32
904169240Sjfve1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active)
905169240Sjfv{
906169240Sjfv	struct e1000_phy_info *phy = &hw->phy;
907169240Sjfv	u32 phy_ctrl;
908169240Sjfv	s32 ret_val = E1000_SUCCESS;
909169240Sjfv	u16 data;
910169240Sjfv
911169240Sjfv	DEBUGFUNC("e1000_set_d3_lplu_state_ich8lan");
912169240Sjfv
913169240Sjfv	phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
914169240Sjfv
915169240Sjfv	if (!active) {
916169240Sjfv		phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
917169240Sjfv		E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
918169240Sjfv		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
919169240Sjfv		 * during Dx states where the power conservation is most
920169240Sjfv		 * important.  During driver activity we should enable
921169240Sjfv		 * SmartSpeed, so performance is maintained. */
922169240Sjfv		if (phy->smart_speed == e1000_smart_speed_on) {
923169240Sjfv			ret_val = e1000_read_phy_reg(hw,
924169240Sjfv			                            IGP01E1000_PHY_PORT_CONFIG,
925169240Sjfv			                            &data);
926169240Sjfv			if (ret_val)
927169240Sjfv				goto out;
928169240Sjfv
929169240Sjfv			data |= IGP01E1000_PSCFR_SMART_SPEED;
930169240Sjfv			ret_val = e1000_write_phy_reg(hw,
931169240Sjfv			                             IGP01E1000_PHY_PORT_CONFIG,
932169240Sjfv			                             data);
933169240Sjfv			if (ret_val)
934169240Sjfv				goto out;
935169240Sjfv		} else if (phy->smart_speed == e1000_smart_speed_off) {
936169240Sjfv			ret_val = e1000_read_phy_reg(hw,
937169240Sjfv			                            IGP01E1000_PHY_PORT_CONFIG,
938169240Sjfv			                            &data);
939169240Sjfv			if (ret_val)
940169240Sjfv				goto out;
941169240Sjfv
942169240Sjfv			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
943169240Sjfv			ret_val = e1000_write_phy_reg(hw,
944169240Sjfv			                             IGP01E1000_PHY_PORT_CONFIG,
945169240Sjfv			                             data);
946169240Sjfv			if (ret_val)
947169240Sjfv				goto out;
948169240Sjfv		}
949169240Sjfv	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
950169240Sjfv	           (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
951169240Sjfv	           (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
952169240Sjfv		phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
953169240Sjfv		E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
954169240Sjfv
955169240Sjfv		/* Call gig speed drop workaround on LPLU before accessing
956169240Sjfv		 * any PHY registers */
957169240Sjfv		if ((hw->mac.type == e1000_ich8lan) &&
958169240Sjfv		    (hw->phy.type == e1000_phy_igp_3))
959169240Sjfv			e1000_gig_downshift_workaround_ich8lan(hw);
960169240Sjfv
961169240Sjfv		/* When LPLU is enabled, we should disable SmartSpeed */
962169240Sjfv		ret_val = e1000_read_phy_reg(hw,
963169240Sjfv		                            IGP01E1000_PHY_PORT_CONFIG,
964169240Sjfv		                            &data);
965169240Sjfv		if (ret_val)
966169240Sjfv			goto out;
967169240Sjfv
968169240Sjfv		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
969169240Sjfv		ret_val = e1000_write_phy_reg(hw,
970169240Sjfv		                             IGP01E1000_PHY_PORT_CONFIG,
971169240Sjfv		                             data);
972169240Sjfv	}
973169240Sjfv
974169240Sjfvout:
975169240Sjfv	return ret_val;
976169240Sjfv}
977169240Sjfv
978169240Sjfv/**
979169240Sjfv *  e1000_read_nvm_ich8lan - Read word(s) from the NVM
980169240Sjfv *  @hw - pointer to the HW structure
981169240Sjfv *  @offset - The offset (in bytes) of the word(s) to read.
982169240Sjfv *  @words - Size of data to read in words
983169240Sjfv *  @data - Pointer to the word(s) to read at offset.
984169240Sjfv *
985169240Sjfv *  Reads a word(s) from the NVM using the flash access registers.
986169240Sjfv **/
987169240SjfvSTATIC s32
988169240Sjfve1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
989169240Sjfv{
990169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
991169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
992169240Sjfv	u32 act_offset;
993169240Sjfv	s32 ret_val = E1000_SUCCESS;
994169240Sjfv	u16 i, word;
995169240Sjfv
996169240Sjfv	DEBUGFUNC("e1000_read_nvm_ich8lan");
997169240Sjfv
998169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
999169240Sjfv
1000169240Sjfv	if (dev_spec == NULL) {
1001169240Sjfv		DEBUGOUT("dev_spec pointer is set to NULL.\n");
1002169240Sjfv		ret_val = -E1000_ERR_CONFIG;
1003169240Sjfv		goto out;
1004169240Sjfv	}
1005169240Sjfv
1006169240Sjfv	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
1007169240Sjfv	    (words == 0)) {
1008169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
1009169240Sjfv		ret_val = -E1000_ERR_NVM;
1010169240Sjfv		goto out;
1011169240Sjfv	}
1012169240Sjfv
1013169240Sjfv	ret_val = e1000_acquire_nvm(hw);
1014169240Sjfv	if (ret_val)
1015169240Sjfv		goto out;
1016169240Sjfv
1017169240Sjfv	/* Start with the bank offset, then add the relative offset. */
1018169240Sjfv	act_offset = (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL)
1019169240Sjfv		     ? nvm->flash_bank_size
1020169240Sjfv		     : 0;
1021169240Sjfv	act_offset += offset;
1022169240Sjfv
1023169240Sjfv	for (i = 0; i < words; i++) {
1024169240Sjfv		if ((dev_spec->shadow_ram != NULL) &&
1025169240Sjfv		    (dev_spec->shadow_ram[offset+i].modified == TRUE)) {
1026169240Sjfv			data[i] = dev_spec->shadow_ram[offset+i].value;
1027169240Sjfv		} else {
1028169240Sjfv			ret_val = e1000_read_flash_word_ich8lan(hw,
1029169240Sjfv			                                        act_offset + i,
1030169240Sjfv			                                        &word);
1031169240Sjfv			if (ret_val)
1032169240Sjfv				break;
1033169240Sjfv			data[i] = word;
1034169240Sjfv		}
1035169240Sjfv	}
1036169240Sjfv
1037169240Sjfv	e1000_release_nvm(hw);
1038169240Sjfv
1039169240Sjfvout:
1040169240Sjfv	return ret_val;
1041169240Sjfv}
1042169240Sjfv
1043169240Sjfv/**
1044169240Sjfv *  e1000_flash_cycle_init_ich8lan - Initialize flash
1045169240Sjfv *  @hw - pointer to the HW structure
1046169240Sjfv *
1047169240Sjfv *  This function does initial flash setup so that a new read/write/erase cycle
1048169240Sjfv *  can be started.
1049169240Sjfv **/
1050169240Sjfvstatic s32
1051169240Sjfve1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
1052169240Sjfv{
1053169240Sjfv	union ich8_hws_flash_status hsfsts;
1054169240Sjfv	s32 ret_val = -E1000_ERR_NVM;
1055169240Sjfv	s32 i = 0;
1056169240Sjfv
1057169240Sjfv	DEBUGFUNC("e1000_flash_cycle_init_ich8lan");
1058169240Sjfv
1059169240Sjfv	hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
1060169240Sjfv
1061169240Sjfv	/* Check if the flash descriptor is valid */
1062169240Sjfv	if (hsfsts.hsf_status.fldesvalid == 0) {
1063169240Sjfv		DEBUGOUT("Flash descriptor invalid.  "
1064169240Sjfv		         "SW Sequencing must be used.");
1065169240Sjfv		goto out;
1066169240Sjfv	}
1067169240Sjfv
1068169240Sjfv	/* Clear FCERR and DAEL in hw status by writing 1 */
1069169240Sjfv	hsfsts.hsf_status.flcerr = 1;
1070169240Sjfv	hsfsts.hsf_status.dael = 1;
1071169240Sjfv
1072169240Sjfv	E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
1073169240Sjfv
1074169240Sjfv	/* Either we should have a hardware SPI cycle in progress
1075169240Sjfv	 * bit to check against, in order to start a new cycle or
1076169240Sjfv	 * FDONE bit should be changed in the hardware so that it
1077169240Sjfv	 * is 1 after harware reset, which can then be used as an
1078169240Sjfv	 * indication whether a cycle is in progress or has been
1079169240Sjfv	 * completed.
1080169240Sjfv	 */
1081169240Sjfv
1082169240Sjfv	if (hsfsts.hsf_status.flcinprog == 0) {
1083169240Sjfv		/* There is no cycle running at present,
1084169240Sjfv		 * so we can start a cycle */
1085169240Sjfv		/* Begin by setting Flash Cycle Done. */
1086169240Sjfv		hsfsts.hsf_status.flcdone = 1;
1087169240Sjfv		E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
1088169240Sjfv		ret_val = E1000_SUCCESS;
1089169240Sjfv	} else {
1090169240Sjfv		/* otherwise poll for sometime so the current
1091169240Sjfv		 * cycle has a chance to end before giving up. */
1092169240Sjfv		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
1093169240Sjfv			hsfsts.regval = E1000_READ_FLASH_REG16(hw,
1094169240Sjfv			                                      ICH_FLASH_HSFSTS);
1095169240Sjfv			if (hsfsts.hsf_status.flcinprog == 0) {
1096169240Sjfv				ret_val = E1000_SUCCESS;
1097169240Sjfv				break;
1098169240Sjfv			}
1099169240Sjfv			usec_delay(1);
1100169240Sjfv		}
1101169240Sjfv		if (ret_val == E1000_SUCCESS) {
1102169240Sjfv			/* Successful in waiting for previous cycle to timeout,
1103169240Sjfv			 * now set the Flash Cycle Done. */
1104169240Sjfv			hsfsts.hsf_status.flcdone = 1;
1105169240Sjfv			E1000_WRITE_FLASH_REG16(hw,
1106169240Sjfv			                        ICH_FLASH_HSFSTS,
1107169240Sjfv			                        hsfsts.regval);
1108169240Sjfv		} else {
1109169240Sjfv			DEBUGOUT("Flash controller busy, cannot get access");
1110169240Sjfv		}
1111169240Sjfv	}
1112169240Sjfv
1113169240Sjfvout:
1114169240Sjfv	return ret_val;
1115169240Sjfv}
1116169240Sjfv
1117169240Sjfv/**
1118169240Sjfv *  e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase)
1119169240Sjfv *  @hw - pointer to the HW structure
1120169240Sjfv *  @timeout - maximum time to wait for completion
1121169240Sjfv *
1122169240Sjfv *  This function starts a flash cycle and waits for its completion.
1123169240Sjfv **/
1124169240Sjfvstatic s32
1125169240Sjfve1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
1126169240Sjfv{
1127169240Sjfv	union ich8_hws_flash_ctrl hsflctl;
1128169240Sjfv	union ich8_hws_flash_status hsfsts;
1129169240Sjfv	s32 ret_val = -E1000_ERR_NVM;
1130169240Sjfv	u32 i = 0;
1131169240Sjfv
1132169240Sjfv	DEBUGFUNC("e1000_flash_cycle_ich8lan");
1133169240Sjfv
1134169240Sjfv	/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
1135169240Sjfv	hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
1136169240Sjfv	hsflctl.hsf_ctrl.flcgo = 1;
1137169240Sjfv	E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
1138169240Sjfv
1139169240Sjfv	/* wait till FDONE bit is set to 1 */
1140169240Sjfv	do {
1141169240Sjfv		hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
1142169240Sjfv		if (hsfsts.hsf_status.flcdone == 1)
1143169240Sjfv			break;
1144169240Sjfv		usec_delay(1);
1145169240Sjfv	} while (i++ < timeout);
1146169240Sjfv
1147169240Sjfv	if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
1148169240Sjfv		ret_val = E1000_SUCCESS;
1149169240Sjfv
1150169240Sjfv	return ret_val;
1151169240Sjfv}
1152169240Sjfv
1153169240Sjfv/**
1154169240Sjfv *  e1000_read_flash_word_ich8lan - Read word from flash
1155169240Sjfv *  @hw - pointer to the HW structure
1156169240Sjfv *  @offset - offset to data location
1157169240Sjfv *  @data - pointer to the location for storing the data
1158169240Sjfv *
1159169240Sjfv *  Reads the flash word at offset into data.  Offset is converted
1160169240Sjfv *  to bytes before read.
1161169240Sjfv **/
1162169240SjfvSTATIC s32
1163169240Sjfve1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, u16 *data)
1164169240Sjfv{
1165169240Sjfv	s32 ret_val;
1166169240Sjfv
1167169240Sjfv	DEBUGFUNC("e1000_read_flash_word_ich8lan");
1168169240Sjfv
1169169240Sjfv	if (data == NULL) {
1170169240Sjfv		ret_val = -E1000_ERR_NVM;
1171169240Sjfv		goto out;
1172169240Sjfv	}
1173169240Sjfv
1174169240Sjfv	/* Must convert offset into bytes. */
1175169240Sjfv	offset <<= 1;
1176169240Sjfv
1177169240Sjfv	ret_val = e1000_read_flash_data_ich8lan(hw, offset, 2, data);
1178169240Sjfv
1179169240Sjfvout:
1180169240Sjfv	return ret_val;
1181169240Sjfv}
1182169240Sjfv
1183169240Sjfv/**
1184169240Sjfv *  e1000_read_flash_data_ich8lan - Read byte or word from NVM
1185169240Sjfv *  @hw - pointer to the HW structure
1186169240Sjfv *  @offset - The offset (in bytes) of the byte or word to read.
1187169240Sjfv *  @size - Size of data to read, 1=byte 2=word
1188169240Sjfv *  @data - Pointer to the word to store the value read.
1189169240Sjfv *
1190169240Sjfv *  Reads a byte or word from the NVM using the flash access registers.
1191169240Sjfv **/
1192169240Sjfvstatic s32
1193169240Sjfve1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
1194169240Sjfv                              u8 size, u16* data)
1195169240Sjfv{
1196169240Sjfv	union ich8_hws_flash_status hsfsts;
1197169240Sjfv	union ich8_hws_flash_ctrl hsflctl;
1198169240Sjfv	u32 flash_linear_addr;
1199169240Sjfv	u32 flash_data = 0;
1200169240Sjfv	s32 ret_val = -E1000_ERR_NVM;
1201169240Sjfv	u8 count = 0;
1202169240Sjfv
1203169240Sjfv	DEBUGFUNC("e1000_read_flash_data_ich8lan");
1204169240Sjfv
1205169240Sjfv	if (size < 1  || size > 2 || data == 0x0 ||
1206169240Sjfv	    offset > ICH_FLASH_LINEAR_ADDR_MASK)
1207169240Sjfv		goto out;
1208169240Sjfv
1209169240Sjfv	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
1210169240Sjfv	                    hw->nvm.flash_base_addr;
1211169240Sjfv
1212169240Sjfv	do {
1213169240Sjfv		usec_delay(1);
1214169240Sjfv		/* Steps */
1215169240Sjfv		ret_val = e1000_flash_cycle_init_ich8lan(hw);
1216169240Sjfv		if (ret_val != E1000_SUCCESS)
1217169240Sjfv			break;
1218169240Sjfv
1219169240Sjfv		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
1220169240Sjfv		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
1221169240Sjfv		hsflctl.hsf_ctrl.fldbcount = size - 1;
1222169240Sjfv		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
1223169240Sjfv		E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
1224169240Sjfv
1225169240Sjfv		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
1226169240Sjfv
1227169240Sjfv		ret_val = e1000_flash_cycle_ich8lan(hw,
1228169240Sjfv		                                ICH_FLASH_READ_COMMAND_TIMEOUT);
1229169240Sjfv
1230169240Sjfv		/* Check if FCERR is set to 1, if set to 1, clear it
1231169240Sjfv		 * and try the whole sequence a few more times, else
1232169240Sjfv		 * read in (shift in) the Flash Data0, the order is
1233169240Sjfv		 * least significant byte first msb to lsb */
1234169240Sjfv		if (ret_val == E1000_SUCCESS) {
1235169240Sjfv			flash_data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0);
1236169240Sjfv			if (size == 1) {
1237169240Sjfv				*data = (u8)(flash_data & 0x000000FF);
1238169240Sjfv			} else if (size == 2) {
1239169240Sjfv				*data = (u16)(flash_data & 0x0000FFFF);
1240169240Sjfv			}
1241169240Sjfv			break;
1242169240Sjfv		} else {
1243169240Sjfv			/* If we've gotten here, then things are probably
1244169240Sjfv			 * completely hosed, but if the error condition is
1245169240Sjfv			 * detected, it won't hurt to give it another try...
1246169240Sjfv			 * ICH_FLASH_CYCLE_REPEAT_COUNT times.
1247169240Sjfv			 */
1248169240Sjfv			hsfsts.regval = E1000_READ_FLASH_REG16(hw,
1249169240Sjfv			                                      ICH_FLASH_HSFSTS);
1250169240Sjfv			if (hsfsts.hsf_status.flcerr == 1) {
1251169240Sjfv				/* Repeat for some time before giving up. */
1252169240Sjfv				continue;
1253169240Sjfv			} else if (hsfsts.hsf_status.flcdone == 0) {
1254169240Sjfv				DEBUGOUT("Timeout error - flash cycle "
1255169240Sjfv				         "did not complete.");
1256169240Sjfv				break;
1257169240Sjfv			}
1258169240Sjfv		}
1259169240Sjfv	} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
1260169240Sjfv
1261169240Sjfvout:
1262169240Sjfv	return ret_val;
1263169240Sjfv}
1264169240Sjfv
1265169240Sjfv/**
1266169240Sjfv *  e1000_write_nvm_ich8lan - Write word(s) to the NVM
1267169240Sjfv *  @hw - pointer to the HW structure
1268169240Sjfv *  @offset - The offset (in bytes) of the word(s) to write.
1269169240Sjfv *  @words - Size of data to write in words
1270169240Sjfv *  @data - Pointer to the word(s) to write at offset.
1271169240Sjfv *
1272169240Sjfv *  Writes a byte or word to the NVM using the flash access registers.
1273169240Sjfv **/
1274169240SjfvSTATIC s32
1275169240Sjfve1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
1276169240Sjfv{
1277169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
1278169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
1279169240Sjfv	s32 ret_val = E1000_SUCCESS;
1280169240Sjfv	u16 i;
1281169240Sjfv
1282169240Sjfv	DEBUGFUNC("e1000_write_nvm_ich8lan");
1283169240Sjfv
1284169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
1285169240Sjfv
1286169240Sjfv	if (dev_spec == NULL) {
1287169240Sjfv		DEBUGOUT("dev_spec pointer is set to NULL.\n");
1288169240Sjfv		ret_val = -E1000_ERR_CONFIG;
1289169240Sjfv		goto out;
1290169240Sjfv	}
1291169240Sjfv
1292169240Sjfv	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
1293169240Sjfv	    (words == 0)) {
1294169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
1295169240Sjfv		ret_val = -E1000_ERR_NVM;
1296169240Sjfv		goto out;
1297169240Sjfv	}
1298169240Sjfv
1299169240Sjfv	ret_val = e1000_acquire_nvm(hw);
1300169240Sjfv	if (ret_val)
1301169240Sjfv		goto out;
1302169240Sjfv
1303169240Sjfv	for (i = 0; i < words; i++) {
1304169240Sjfv		dev_spec->shadow_ram[offset+i].modified = TRUE;
1305169240Sjfv		dev_spec->shadow_ram[offset+i].value = data[i];
1306169240Sjfv	}
1307169240Sjfv
1308169240Sjfv	e1000_release_nvm(hw);
1309169240Sjfv
1310169240Sjfvout:
1311169240Sjfv	return ret_val;
1312169240Sjfv}
1313169240Sjfv
1314169240Sjfv/**
1315169240Sjfv *  e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM
1316169240Sjfv *  @hw - pointer to the HW structure
1317169240Sjfv *
1318169240Sjfv *  The NVM checksum is updated by calling the generic update_nvm_checksum,
1319169240Sjfv *  which writes the checksum to the shadow ram.  The changes in the shadow
1320169240Sjfv *  ram are then committed to the EEPROM by processing each bank at a time
1321169240Sjfv *  checking for the modified bit and writing only the pending changes.
1322169240Sjfv *  After a succesful commit, the shadow ram is cleared and is ready for
1323169240Sjfv *  future writes.
1324169240Sjfv **/
1325169240SjfvSTATIC s32
1326169240Sjfve1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1327169240Sjfv{
1328169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
1329169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
1330169240Sjfv	u32 i, act_offset, new_bank_offset, old_bank_offset;
1331169240Sjfv	s32 ret_val;
1332169240Sjfv	u16 data;
1333169240Sjfv
1334169240Sjfv	DEBUGFUNC("e1000_update_nvm_checksum_ich8lan");
1335169240Sjfv
1336169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
1337169240Sjfv
1338169240Sjfv	ret_val = e1000_update_nvm_checksum_generic(hw);
1339169240Sjfv	if (ret_val)
1340169240Sjfv		goto out;
1341169240Sjfv
1342169240Sjfv	if (nvm->type != e1000_nvm_flash_sw)
1343169240Sjfv		goto out;
1344169240Sjfv
1345169240Sjfv	ret_val = e1000_acquire_nvm(hw);
1346169240Sjfv	if (ret_val)
1347169240Sjfv		goto out;
1348169240Sjfv
1349169240Sjfv	/* We're writing to the opposite bank so if we're on bank 1,
1350169240Sjfv	 * write to bank 0 etc.  We also need to erase the segment that
1351169240Sjfv	 * is going to be written */
1352169240Sjfv	if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL)) {
1353169240Sjfv		new_bank_offset = nvm->flash_bank_size;
1354169240Sjfv		old_bank_offset = 0;
1355169240Sjfv		e1000_erase_flash_bank_ich8lan(hw, 1);
1356169240Sjfv	} else {
1357169240Sjfv		old_bank_offset = nvm->flash_bank_size;
1358169240Sjfv		new_bank_offset = 0;
1359169240Sjfv		e1000_erase_flash_bank_ich8lan(hw, 0);
1360169240Sjfv	}
1361169240Sjfv
1362169240Sjfv	for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
1363169240Sjfv		/* Determine whether to write the value stored
1364169240Sjfv		 * in the other NVM bank or a modified value stored
1365169240Sjfv		 * in the shadow RAM */
1366169240Sjfv		if (dev_spec->shadow_ram[i].modified == TRUE) {
1367169240Sjfv			data = dev_spec->shadow_ram[i].value;
1368169240Sjfv		} else {
1369169240Sjfv			e1000_read_flash_word_ich8lan(hw,
1370169240Sjfv			                              i + old_bank_offset,
1371169240Sjfv			                              &data);
1372169240Sjfv		}
1373169240Sjfv
1374169240Sjfv		/* If the word is 0x13, then make sure the signature bits
1375169240Sjfv		 * (15:14) are 11b until the commit has completed.
1376169240Sjfv		 * This will allow us to write 10b which indicates the
1377169240Sjfv		 * signature is valid.  We want to do this after the write
1378169240Sjfv		 * has completed so that we don't mark the segment valid
1379169240Sjfv		 * while the write is still in progress */
1380169240Sjfv		if (i == E1000_ICH_NVM_SIG_WORD)
1381169240Sjfv			data |= E1000_ICH_NVM_SIG_MASK;
1382169240Sjfv
1383169240Sjfv		/* Convert offset to bytes. */
1384169240Sjfv		act_offset = (i + new_bank_offset) << 1;
1385169240Sjfv
1386169240Sjfv		usec_delay(100);
1387169240Sjfv		/* Write the bytes to the new bank. */
1388169240Sjfv		ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
1389169240Sjfv		                                               act_offset,
1390169240Sjfv		                                               (u8)data);
1391169240Sjfv		if (ret_val)
1392169240Sjfv			break;
1393169240Sjfv
1394169240Sjfv		usec_delay(100);
1395169240Sjfv		ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
1396169240Sjfv		                                          act_offset + 1,
1397169240Sjfv		                                          (u8)(data >> 8));
1398169240Sjfv		if (ret_val)
1399169240Sjfv			break;
1400169240Sjfv	}
1401169240Sjfv
1402169240Sjfv	/* Don't bother writing the segment valid bits if sector
1403169240Sjfv	 * programming failed. */
1404169240Sjfv	if (ret_val) {
1405169240Sjfv		DEBUGOUT("Flash commit failed.\n");
1406169240Sjfv		e1000_release_nvm(hw);
1407169240Sjfv		goto out;
1408169240Sjfv	}
1409169240Sjfv
1410169240Sjfv	/* Finally validate the new segment by setting bit 15:14
1411169240Sjfv	 * to 10b in word 0x13 , this can be done without an
1412169240Sjfv	 * erase as well since these bits are 11 to start with
1413169240Sjfv	 * and we need to change bit 14 to 0b */
1414169240Sjfv	act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
1415169240Sjfv	e1000_read_flash_word_ich8lan(hw, act_offset, &data);
1416169240Sjfv	data &= 0xBFFF;
1417169240Sjfv	ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
1418169240Sjfv	                                               act_offset * 2 + 1,
1419169240Sjfv	                                               (u8)(data >> 8));
1420169240Sjfv	if (ret_val) {
1421169240Sjfv		e1000_release_nvm(hw);
1422169240Sjfv		goto out;
1423169240Sjfv	}
1424169240Sjfv
1425169240Sjfv	/* And invalidate the previously valid segment by setting
1426169240Sjfv	 * its signature word (0x13) high_byte to 0b. This can be
1427169240Sjfv	 * done without an erase because flash erase sets all bits
1428169240Sjfv	 * to 1's. We can write 1's to 0's without an erase */
1429169240Sjfv	act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
1430169240Sjfv	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
1431169240Sjfv	if (ret_val) {
1432169240Sjfv		e1000_release_nvm(hw);
1433169240Sjfv		goto out;
1434169240Sjfv	}
1435169240Sjfv
1436169240Sjfv	/* Great!  Everything worked, we can now clear the cached entries. */
1437169240Sjfv	for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
1438169240Sjfv		dev_spec->shadow_ram[i].modified = FALSE;
1439169240Sjfv		dev_spec->shadow_ram[i].value = 0xFFFF;
1440169240Sjfv	}
1441169240Sjfv
1442169240Sjfv	e1000_release_nvm(hw);
1443169240Sjfv
1444169240Sjfv	/* Reload the EEPROM, or else modifications will not appear
1445169240Sjfv	 * until after the next adapter reset.
1446169240Sjfv	 */
1447169240Sjfv	e1000_reload_nvm(hw);
1448169240Sjfv	msec_delay(10);
1449169240Sjfv
1450169240Sjfvout:
1451169240Sjfv	return ret_val;
1452169240Sjfv}
1453169240Sjfv
1454169240Sjfv/**
1455169240Sjfv *  e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum
1456169240Sjfv *  @hw - pointer to the HW structure
1457169240Sjfv *
1458169240Sjfv *  Check to see if checksum needs to be fixed by reading bit 6 in word 0x19.
1459169240Sjfv *  If the bit is 0, that the EEPROM had been modified, but the checksum was not
1460169240Sjfv *  calculated, in which case we need to calculate the checksum and set bit 6.
1461169240Sjfv **/
1462169240SjfvSTATIC s32
1463169240Sjfve1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
1464169240Sjfv{
1465169240Sjfv	s32 ret_val = E1000_SUCCESS;
1466169240Sjfv	u16 data;
1467169240Sjfv
1468169240Sjfv	DEBUGFUNC("e1000_validate_nvm_checksum_ich8lan");
1469169240Sjfv
1470169240Sjfv	/* Read 0x19 and check bit 6.  If this bit is 0, the checksum
1471169240Sjfv	 * needs to be fixed.  This bit is an indication that the NVM
1472169240Sjfv	 * was prepared by OEM software and did not calculate the
1473169240Sjfv	 * checksum...a likely scenario.
1474169240Sjfv	 */
1475169240Sjfv	ret_val = e1000_read_nvm(hw, 0x19, 1, &data);
1476169240Sjfv	if (ret_val)
1477169240Sjfv		goto out;
1478169240Sjfv
1479169240Sjfv	if ((data & 0x40) == 0) {
1480169240Sjfv		data |= 0x40;
1481169240Sjfv		ret_val = e1000_write_nvm(hw, 0x19, 1, &data);
1482169240Sjfv		if (ret_val)
1483169240Sjfv			goto out;
1484169240Sjfv		ret_val = e1000_update_nvm_checksum(hw);
1485169240Sjfv		if (ret_val)
1486169240Sjfv			goto out;
1487169240Sjfv	}
1488169240Sjfv
1489169240Sjfv	ret_val = e1000_validate_nvm_checksum_generic(hw);
1490169240Sjfv
1491169240Sjfvout:
1492169240Sjfv	return ret_val;
1493169240Sjfv}
1494169240Sjfv
1495169240Sjfv/**
1496169240Sjfv *  e1000_write_flash_data_ich8lan - Writes bytes to the NVM
1497169240Sjfv *  @hw - pointer to the HW structure
1498169240Sjfv *  @offset - The offset (in bytes) of the byte/word to read.
1499169240Sjfv *  @size - Size of data to read, 1=byte 2=word
1500169240Sjfv *  @data - The byte(s) to write to the NVM.
1501169240Sjfv *
1502169240Sjfv *  Writes one/two bytes to the NVM using the flash access registers.
1503169240Sjfv **/
1504169240Sjfvstatic s32
1505169240Sjfve1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
1506169240Sjfv                               u8 size, u16 data)
1507169240Sjfv{
1508169240Sjfv	union ich8_hws_flash_status hsfsts;
1509169240Sjfv	union ich8_hws_flash_ctrl hsflctl;
1510169240Sjfv	u32 flash_linear_addr;
1511169240Sjfv	u32 flash_data = 0;
1512169240Sjfv	s32 ret_val = -E1000_ERR_NVM;
1513169240Sjfv	u8 count = 0;
1514169240Sjfv
1515169240Sjfv	DEBUGFUNC("e1000_write_ich8_data");
1516169240Sjfv
1517169240Sjfv	if (size < 1 || size > 2 || data > size * 0xff ||
1518169240Sjfv	    offset > ICH_FLASH_LINEAR_ADDR_MASK)
1519169240Sjfv		goto out;
1520169240Sjfv
1521169240Sjfv	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
1522169240Sjfv	                    hw->nvm.flash_base_addr;
1523169240Sjfv
1524169240Sjfv	do {
1525169240Sjfv		usec_delay(1);
1526169240Sjfv		/* Steps */
1527169240Sjfv		ret_val = e1000_flash_cycle_init_ich8lan(hw);
1528169240Sjfv		if (ret_val != E1000_SUCCESS)
1529169240Sjfv			break;
1530169240Sjfv
1531169240Sjfv		hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
1532169240Sjfv		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
1533169240Sjfv		hsflctl.hsf_ctrl.fldbcount = size -1;
1534169240Sjfv		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
1535169240Sjfv		E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
1536169240Sjfv
1537169240Sjfv		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
1538169240Sjfv
1539169240Sjfv		if (size == 1)
1540169240Sjfv			flash_data = (u32)data & 0x00FF;
1541169240Sjfv		else
1542169240Sjfv			flash_data = (u32)data;
1543169240Sjfv
1544169240Sjfv		E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FDATA0, flash_data);
1545169240Sjfv
1546169240Sjfv		/* check if FCERR is set to 1 , if set to 1, clear it
1547169240Sjfv		 * and try the whole sequence a few more times else done */
1548169240Sjfv		ret_val = e1000_flash_cycle_ich8lan(hw,
1549169240Sjfv		                               ICH_FLASH_WRITE_COMMAND_TIMEOUT);
1550169240Sjfv		if (ret_val == E1000_SUCCESS) {
1551169240Sjfv			break;
1552169240Sjfv		} else {
1553169240Sjfv			/* If we're here, then things are most likely
1554169240Sjfv			 * completely hosed, but if the error condition
1555169240Sjfv			 * is detected, it won't hurt to give it another
1556169240Sjfv			 * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
1557169240Sjfv			 */
1558169240Sjfv			hsfsts.regval = E1000_READ_FLASH_REG16(hw,
1559169240Sjfv			                                      ICH_FLASH_HSFSTS);
1560169240Sjfv			if (hsfsts.hsf_status.flcerr == 1) {
1561169240Sjfv				/* Repeat for some time before giving up. */
1562169240Sjfv				continue;
1563169240Sjfv			} else if (hsfsts.hsf_status.flcdone == 0) {
1564169240Sjfv				DEBUGOUT("Timeout error - flash cycle "
1565169240Sjfv				         "did not complete.");
1566169240Sjfv				break;
1567169240Sjfv			}
1568169240Sjfv		}
1569169240Sjfv	} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
1570169240Sjfv
1571169240Sjfvout:
1572169240Sjfv	return ret_val;
1573169240Sjfv}
1574169240Sjfv
1575169240Sjfv/**
1576169240Sjfv *  e1000_write_flash_byte_ich8lan - Write a single byte to NVM
1577169240Sjfv *  @hw - pointer to the HW structure
1578169240Sjfv *  @offset - The index of the byte to read.
1579169240Sjfv *  @data - The byte to write to the NVM.
1580169240Sjfv *
1581169240Sjfv *  Writes a single byte to the NVM using the flash access registers.
1582169240Sjfv **/
1583169240SjfvSTATIC s32
1584169240Sjfve1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 data)
1585169240Sjfv{
1586169240Sjfv	u16 word = (u16)data;
1587169240Sjfv
1588169240Sjfv	DEBUGFUNC("e1000_write_flash_byte_ich8lan");
1589169240Sjfv
1590169240Sjfv	return e1000_write_flash_data_ich8lan(hw, offset, 1, word);
1591169240Sjfv}
1592169240Sjfv
1593169240Sjfv/**
1594169240Sjfv *  e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
1595169240Sjfv *  @hw - pointer to the HW structure
1596169240Sjfv *  @offset - The offset of the byte to write.
1597169240Sjfv *  @byte - The byte to write to the NVM.
1598169240Sjfv *
1599169240Sjfv *  Writes a single byte to the NVM using the flash access registers.
1600169240Sjfv *  Goes through a retry algorithm before giving up.
1601169240Sjfv **/
1602169240Sjfvstatic s32
1603169240Sjfve1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 byte)
1604169240Sjfv{
1605169240Sjfv	s32 ret_val;
1606169240Sjfv	u16 program_retries;
1607169240Sjfv
1608169240Sjfv	DEBUGFUNC("e1000_retry_write_flash_byte_ich8lan");
1609169240Sjfv
1610169240Sjfv	ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
1611169240Sjfv	if (ret_val)
1612169240Sjfv		goto out;
1613169240Sjfv
1614169240Sjfv	usec_delay(100);
1615169240Sjfv
1616169240Sjfv	for (program_retries = 0; program_retries < 100; program_retries++) {
1617169240Sjfv		DEBUGOUT2("Retrying Byte %2.2X at offset %u\n", byte, offset);
1618169240Sjfv		usec_delay(100);
1619169240Sjfv		ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
1620169240Sjfv		if (ret_val == E1000_SUCCESS)
1621169240Sjfv			break;
1622169240Sjfv	}
1623169240Sjfv	if (program_retries == 100) {
1624169240Sjfv		ret_val = -E1000_ERR_NVM;
1625169240Sjfv		goto out;
1626169240Sjfv	}
1627169240Sjfv
1628169240Sjfvout:
1629169240Sjfv	return ret_val;
1630169240Sjfv}
1631169240Sjfv
1632169240Sjfv/**
1633169240Sjfv *  e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM
1634169240Sjfv *  @hw - pointer to the HW structure
1635169240Sjfv *  @bank - 0 for first bank, 1 for second bank, etc.
1636169240Sjfv *
1637169240Sjfv *  Erases the bank specified. Each bank is a 4k block. Banks are 0 based.
1638169240Sjfv *  bank N is 4096 * N + flash_reg_addr.
1639169240Sjfv **/
1640169240SjfvSTATIC s32
1641169240Sjfve1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
1642169240Sjfv{
1643169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
1644169240Sjfv	union ich8_hws_flash_status hsfsts;
1645169240Sjfv	union ich8_hws_flash_ctrl hsflctl;
1646169240Sjfv	u32 flash_linear_addr;
1647169240Sjfv	u32 flash_bank_size = nvm->flash_bank_size * 2; /* bank size is in 16bit words - adjust to bytes */
1648169240Sjfv	s32  ret_val = E1000_SUCCESS;
1649169240Sjfv	s32  count = 0;
1650169240Sjfv	s32  j, iteration, sector_size;
1651169240Sjfv
1652169240Sjfv	DEBUGFUNC("e1000_erase_flash_bank_ich8lan");
1653169240Sjfv
1654169240Sjfv	hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
1655169240Sjfv
1656169240Sjfv	/* Determine HW Sector size: Read BERASE bits of hw flash status
1657169240Sjfv	 * register */
1658169240Sjfv	/* 00: The Hw sector is 256 bytes, hence we need to erase 16
1659169240Sjfv	 *     consecutive sectors.  The start index for the nth Hw sector
1660169240Sjfv	 *     can be calculated as = bank * 4096 + n * 256
1661169240Sjfv	 * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
1662169240Sjfv	 *     The start index for the nth Hw sector can be calculated
1663169240Sjfv	 *     as = bank * 4096
1664169240Sjfv	 * 10: The Hw sector is 8K bytes, nth sector = bank * 8192
1665169240Sjfv	 *     (ich9 only, otherwise error condition)
1666169240Sjfv	 * 11: The Hw sector is 64K bytes, nth sector = bank * 65536
1667169240Sjfv	 */
1668169240Sjfv	switch (hsfsts.hsf_status.berasesz) {
1669169240Sjfv	case 0:
1670169240Sjfv		/* Hw sector size 256 */
1671169240Sjfv		sector_size = ICH_FLASH_SEG_SIZE_256;
1672169240Sjfv		iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256;
1673169240Sjfv		break;
1674169240Sjfv	case 1:
1675169240Sjfv		sector_size = ICH_FLASH_SEG_SIZE_4K;
1676169240Sjfv		iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K;
1677169240Sjfv		break;
1678169240Sjfv	case 2:
1679169240Sjfv		if (hw->mac.type == e1000_ich9lan) {
1680169240Sjfv			sector_size = ICH_FLASH_SEG_SIZE_8K;
1681169240Sjfv			iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K;
1682169240Sjfv		} else {
1683169240Sjfv			ret_val = -E1000_ERR_NVM;
1684169240Sjfv			goto out;
1685169240Sjfv		}
1686169240Sjfv		break;
1687169240Sjfv	case 3:
1688169240Sjfv		sector_size = ICH_FLASH_SEG_SIZE_64K;
1689169240Sjfv		iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K;
1690169240Sjfv		break;
1691169240Sjfv	default:
1692169240Sjfv		ret_val = -E1000_ERR_NVM;
1693169240Sjfv		goto out;
1694169240Sjfv	}
1695169240Sjfv
1696169240Sjfv	/* Start with the base address, then add the sector offset. */
1697169240Sjfv	flash_linear_addr = hw->nvm.flash_base_addr;
1698169240Sjfv	flash_linear_addr += (bank) ? (sector_size * iteration) : 0;
1699169240Sjfv
1700169240Sjfv	for (j = 0; j < iteration ; j++) {
1701169240Sjfv		do {
1702169240Sjfv			/* Steps */
1703169240Sjfv			ret_val = e1000_flash_cycle_init_ich8lan(hw);
1704169240Sjfv			if (ret_val)
1705169240Sjfv				goto out;
1706169240Sjfv
1707169240Sjfv			/* Write a value 11 (block Erase) in Flash
1708169240Sjfv			 * Cycle field in hw flash control */
1709169240Sjfv			hsflctl.regval = E1000_READ_FLASH_REG16(hw,
1710169240Sjfv			                                      ICH_FLASH_HSFCTL);
1711169240Sjfv			hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
1712169240Sjfv			E1000_WRITE_FLASH_REG16(hw,
1713169240Sjfv			                        ICH_FLASH_HSFCTL,
1714169240Sjfv			                        hsflctl.regval);
1715169240Sjfv
1716169240Sjfv			/* Write the last 24 bits of an index within the
1717169240Sjfv			 * block into Flash Linear address field in Flash
1718169240Sjfv			 * Address.
1719169240Sjfv			 */
1720169240Sjfv			flash_linear_addr += (j * sector_size);
1721169240Sjfv			E1000_WRITE_FLASH_REG(hw,
1722169240Sjfv			                      ICH_FLASH_FADDR,
1723169240Sjfv			                      flash_linear_addr);
1724169240Sjfv
1725169240Sjfv			ret_val = e1000_flash_cycle_ich8lan(hw,
1726169240Sjfv			                       ICH_FLASH_ERASE_COMMAND_TIMEOUT);
1727169240Sjfv			if (ret_val == E1000_SUCCESS) {
1728169240Sjfv				break;
1729169240Sjfv			} else {
1730169240Sjfv				/* Check if FCERR is set to 1.  If 1,
1731169240Sjfv				 * clear it and try the whole sequence
1732169240Sjfv				 * a few more times else Done */
1733169240Sjfv				hsfsts.regval = E1000_READ_FLASH_REG16(hw,
1734169240Sjfv				                              ICH_FLASH_HSFSTS);
1735169240Sjfv				if (hsfsts.hsf_status.flcerr == 1) {
1736169240Sjfv					/* repeat for some time before
1737169240Sjfv					 * giving up */
1738169240Sjfv					continue;
1739169240Sjfv				} else if (hsfsts.hsf_status.flcdone == 0)
1740169240Sjfv					goto out;
1741169240Sjfv			}
1742169240Sjfv		} while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT);
1743169240Sjfv	}
1744169240Sjfv
1745169240Sjfvout:
1746169240Sjfv	return ret_val;
1747169240Sjfv}
1748169240Sjfv
1749169240Sjfv/**
1750169240Sjfv *  e1000_valid_led_default_ich8lan - Set the default LED settings
1751169240Sjfv *  @hw - pointer to the HW structure
1752169240Sjfv *  @data - Pointer to the LED settings
1753169240Sjfv *
1754169240Sjfv *  Reads the LED default settings from the NVM to data.  If the NVM LED
1755169240Sjfv *  settings is all 0's or F's, set the LED default to a valid LED default
1756169240Sjfv *  setting.
1757169240Sjfv **/
1758169240SjfvSTATIC s32
1759169240Sjfve1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
1760169240Sjfv{
1761169240Sjfv	s32 ret_val;
1762169240Sjfv
1763169240Sjfv	DEBUGFUNC("e1000_valid_led_default_ich8lan");
1764169240Sjfv
1765169240Sjfv	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
1766169240Sjfv	if (ret_val) {
1767169240Sjfv		DEBUGOUT("NVM Read Error\n");
1768169240Sjfv		goto out;
1769169240Sjfv	}
1770169240Sjfv
1771169240Sjfv	if (*data == ID_LED_RESERVED_0000 ||
1772169240Sjfv	    *data == ID_LED_RESERVED_FFFF)
1773169240Sjfv		*data = ID_LED_DEFAULT_ICH8LAN;
1774169240Sjfv
1775169240Sjfvout:
1776169240Sjfv	return ret_val;
1777169240Sjfv}
1778169240Sjfv
1779169240Sjfv/**
1780169240Sjfv *  e1000_get_bus_info_ich8lan - Get/Set the bus type and width
1781169240Sjfv *  @hw - pointer to the HW structure
1782169240Sjfv *
1783169240Sjfv *  ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
1784169240Sjfv *  register, so the the bus width is hard coded.
1785169240Sjfv **/
1786169240SjfvSTATIC s32
1787169240Sjfve1000_get_bus_info_ich8lan(struct e1000_hw *hw)
1788169240Sjfv{
1789169240Sjfv	struct e1000_bus_info *bus = &hw->bus;
1790169240Sjfv	s32 ret_val;
1791169240Sjfv
1792169240Sjfv	DEBUGFUNC("e1000_get_bus_info_ich8lan");
1793169240Sjfv
1794169240Sjfv	ret_val = e1000_get_bus_info_pcie_generic(hw);
1795169240Sjfv
1796169240Sjfv	/* ICH devices are "PCI Express"-ish.  They have
1797169240Sjfv	 * a configuration space, but do not contain
1798169240Sjfv	 * PCI Express Capability registers, so bus width
1799169240Sjfv	 * must be hardcoded.
1800169240Sjfv	 */
1801169240Sjfv	if (bus->width == e1000_bus_width_unknown)
1802169240Sjfv		bus->width = e1000_bus_width_pcie_x1;
1803169240Sjfv
1804169240Sjfv	return ret_val;
1805169240Sjfv}
1806169240Sjfv
1807169240Sjfv/**
1808169240Sjfv *  e1000_reset_hw_ich8lan - Reset the hardware
1809169240Sjfv *  @hw - pointer to the HW structure
1810169240Sjfv *
1811169240Sjfv *  Does a full reset of the hardware which includes a reset of the PHY and
1812169240Sjfv *  MAC.
1813169240Sjfv **/
1814169240SjfvSTATIC s32
1815169240Sjfve1000_reset_hw_ich8lan(struct e1000_hw *hw)
1816169240Sjfv{
1817169240Sjfv	u32 ctrl, icr, kab;
1818169240Sjfv	s32 ret_val;
1819169240Sjfv
1820169240Sjfv	DEBUGFUNC("e1000_reset_hw_ich8lan");
1821169240Sjfv
1822169240Sjfv	/* Prevent the PCI-E bus from sticking if there is no TLP connection
1823169240Sjfv	 * on the last TLP read/write transaction when MAC is reset.
1824169240Sjfv	 */
1825169240Sjfv	ret_val = e1000_disable_pcie_master_generic(hw);
1826169240Sjfv	if (ret_val) {
1827169240Sjfv		DEBUGOUT("PCI-E Master disable polling has failed.\n");
1828169240Sjfv	}
1829169240Sjfv
1830169240Sjfv	DEBUGOUT("Masking off all interrupts\n");
1831169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
1832169240Sjfv
1833169240Sjfv	/* Disable the Transmit and Receive units.  Then delay to allow
1834169240Sjfv	 * any pending transactions to complete before we hit the MAC
1835169240Sjfv	 * with the global reset.
1836169240Sjfv	 */
1837169240Sjfv	E1000_WRITE_REG(hw, E1000_RCTL, 0);
1838169240Sjfv	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
1839169240Sjfv	E1000_WRITE_FLUSH(hw);
1840169240Sjfv
1841169240Sjfv	msec_delay(10);
1842169240Sjfv
1843169240Sjfv	/* Workaround for ICH8 bit corruption issue in FIFO memory */
1844169240Sjfv	if (hw->mac.type == e1000_ich8lan) {
1845169240Sjfv		/* Set Tx and Rx buffer allocation to 8k apiece. */
1846169240Sjfv		E1000_WRITE_REG(hw, E1000_PBA, E1000_PBA_8K);
1847169240Sjfv		/* Set Packet Buffer Size to 16k. */
1848169240Sjfv		E1000_WRITE_REG(hw, E1000_PBS, E1000_PBS_16K);
1849169240Sjfv	}
1850169240Sjfv
1851169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
1852169240Sjfv
1853169240Sjfv	if (!e1000_check_reset_block(hw) && !hw->phy.reset_disable) {
1854169240Sjfv		/* PHY HW reset requires MAC CORE reset at the same
1855169240Sjfv		 * time to make sure the interface between MAC and the
1856169240Sjfv		 * external PHY is reset.
1857169240Sjfv		 */
1858169240Sjfv		ctrl |= E1000_CTRL_PHY_RST;
1859169240Sjfv	}
1860169240Sjfv	ret_val = e1000_acquire_swflag_ich8lan(hw);
1861169240Sjfv	DEBUGOUT("Issuing a global reset to ich8lan");
1862169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST));
1863169240Sjfv	msec_delay(20);
1864169240Sjfv
1865169240Sjfv	ret_val = e1000_get_auto_rd_done_generic(hw);
1866169240Sjfv	if (ret_val) {
1867169240Sjfv		/*
1868169240Sjfv		 * When auto config read does not complete, do not
1869169240Sjfv		 * return with an error. This can happen in situations
1870169240Sjfv		 * where there is no eeprom and prevents getting link.
1871169240Sjfv		 */
1872169240Sjfv		DEBUGOUT("Auto Read Done did not complete\n");
1873169240Sjfv	}
1874169240Sjfv
1875169240Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
1876169240Sjfv	icr = E1000_READ_REG(hw, E1000_ICR);
1877169240Sjfv
1878169240Sjfv	kab = E1000_READ_REG(hw, E1000_KABGTXD);
1879169240Sjfv	kab |= E1000_KABGTXD_BGSQLBIAS;
1880169240Sjfv	E1000_WRITE_REG(hw, E1000_KABGTXD, kab);
1881169240Sjfv
1882169240Sjfv	return ret_val;
1883169240Sjfv}
1884169240Sjfv
1885169240Sjfv/**
1886169240Sjfv *  e1000_init_hw_ich8lan - Initialize the hardware
1887169240Sjfv *  @hw - pointer to the HW structure
1888169240Sjfv *
1889169240Sjfv *  Prepares the hardware for transmit and receive by doing the following:
1890169240Sjfv *   - initialize hardware bits
1891169240Sjfv *   - initialize LED identification
1892169240Sjfv *   - setup receive address registers
1893169240Sjfv *   - setup flow control
1894169240Sjfv *   - setup transmit discriptors
1895169240Sjfv *   - clear statistics
1896169240Sjfv **/
1897169240SjfvSTATIC s32
1898169240Sjfve1000_init_hw_ich8lan(struct e1000_hw *hw)
1899169240Sjfv{
1900169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
1901169240Sjfv	u32 ctrl_ext, txdctl, snoop;
1902169240Sjfv	s32 ret_val;
1903169240Sjfv	u16 i;
1904169240Sjfv
1905169240Sjfv	DEBUGFUNC("e1000_init_hw_ich8lan");
1906169240Sjfv
1907169240Sjfv	e1000_initialize_hw_bits_ich8lan(hw);
1908169240Sjfv
1909169240Sjfv	/* Initialize identification LED */
1910169240Sjfv	ret_val = e1000_id_led_init_generic(hw);
1911169240Sjfv	if (ret_val) {
1912169240Sjfv		DEBUGOUT("Error initializing identification LED\n");
1913169240Sjfv		goto out;
1914169240Sjfv	}
1915169240Sjfv
1916169240Sjfv	/* Setup the receive address. */
1917169240Sjfv	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
1918169240Sjfv
1919169240Sjfv	/* Zero out the Multicast HASH table */
1920169240Sjfv	DEBUGOUT("Zeroing the MTA\n");
1921169240Sjfv	for (i = 0; i < mac->mta_reg_count; i++)
1922169240Sjfv		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
1923169240Sjfv
1924169240Sjfv	/* Setup link and flow control */
1925169240Sjfv	ret_val = e1000_setup_link(hw);
1926169240Sjfv
1927169240Sjfv	/* Set the transmit descriptor write-back policy for both queues */
1928169240Sjfv	txdctl = E1000_READ_REG(hw, E1000_TXDCTL);
1929169240Sjfv	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
1930169240Sjfv		 E1000_TXDCTL_FULL_TX_DESC_WB;
1931169240Sjfv	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
1932169240Sjfv	         E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
1933169240Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl);
1934169240Sjfv	txdctl = E1000_READ_REG(hw, E1000_TXDCTL1);
1935169240Sjfv	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
1936169240Sjfv		 E1000_TXDCTL_FULL_TX_DESC_WB;
1937169240Sjfv	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
1938169240Sjfv	         E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
1939169240Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL1, txdctl);
1940169240Sjfv
1941169240Sjfv	/* ICH8 has opposite polarity of no_snoop bits.
1942169240Sjfv	 * By default, we should use snoop behavior. */
1943169240Sjfv	if (mac->type == e1000_ich8lan)
1944169240Sjfv		snoop = PCIE_ICH8_SNOOP_ALL;
1945169240Sjfv	else
1946169240Sjfv		snoop = (u32)~(PCIE_NO_SNOOP_ALL);
1947169240Sjfv	e1000_set_pcie_no_snoop_generic(hw, snoop);
1948169240Sjfv
1949169240Sjfv	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1950169240Sjfv	ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
1951169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1952169240Sjfv
1953169240Sjfv	/* Clear all of the statistics registers (clear on read).  It is
1954169240Sjfv	 * important that we do this after we have tried to establish link
1955169240Sjfv	 * because the symbol error count will increment wildly if there
1956169240Sjfv	 * is no link.
1957169240Sjfv	 */
1958169240Sjfv	e1000_clear_hw_cntrs_ich8lan(hw);
1959169240Sjfv
1960169240Sjfvout:
1961169240Sjfv	return ret_val;
1962169240Sjfv}
1963169240Sjfv/**
1964169240Sjfv *  e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits
1965169240Sjfv *  @hw - pointer to the HW structure
1966169240Sjfv *
1967169240Sjfv *  Sets/Clears required hardware bits necessary for correctly setting up the
1968169240Sjfv *  hardware for transmit and receive.
1969169240Sjfv **/
1970169240Sjfvstatic void
1971169240Sjfve1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
1972169240Sjfv{
1973169240Sjfv	u32 reg;
1974169240Sjfv
1975169240Sjfv	DEBUGFUNC("e1000_initialize_hw_bits_ich8lan");
1976169240Sjfv
1977169240Sjfv	if (hw->mac.disable_hw_init_bits)
1978169240Sjfv		goto out;
1979169240Sjfv
1980169240Sjfv	/* Extended Device Control */
1981169240Sjfv	reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
1982169240Sjfv	reg |= (1 << 22);
1983169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
1984169240Sjfv
1985169240Sjfv	/* Transmit Descriptor Control 0 */
1986169240Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL);
1987169240Sjfv	reg |= (1 << 22);
1988169240Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL, reg);
1989169240Sjfv
1990169240Sjfv	/* Transmit Descriptor Control 1 */
1991169240Sjfv	reg = E1000_READ_REG(hw, E1000_TXDCTL1);
1992169240Sjfv	reg |= (1 << 22);
1993169240Sjfv	E1000_WRITE_REG(hw, E1000_TXDCTL1, reg);
1994169240Sjfv
1995169240Sjfv	/* Transmit Arbitration Control 0 */
1996169240Sjfv	reg = E1000_READ_REG(hw, E1000_TARC0);
1997169240Sjfv	if (hw->mac.type == e1000_ich8lan)
1998169240Sjfv		reg |= (1 << 28) | (1 << 29);
1999169240Sjfv	reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27);
2000169240Sjfv	E1000_WRITE_REG(hw, E1000_TARC0, reg);
2001169240Sjfv
2002169240Sjfv	/* Transmit Arbitration Control 1 */
2003169240Sjfv	reg = E1000_READ_REG(hw, E1000_TARC1);
2004169240Sjfv	if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR)
2005169240Sjfv		reg &= ~(1 << 28);
2006169240Sjfv	else
2007169240Sjfv		reg |= (1 << 28);
2008169240Sjfv	reg |= (1 << 24) | (1 << 26) | (1 << 30);
2009169240Sjfv	E1000_WRITE_REG(hw, E1000_TARC1, reg);
2010169240Sjfv
2011169240Sjfv	/* Device Status */
2012169240Sjfv	if (hw->mac.type == e1000_ich8lan) {
2013169240Sjfv		reg = E1000_READ_REG(hw, E1000_STATUS);
2014169240Sjfv		reg &= ~(1 << 31);
2015169240Sjfv		E1000_WRITE_REG(hw, E1000_STATUS, reg);
2016169240Sjfv	}
2017169240Sjfv
2018169240Sjfvout:
2019169240Sjfv	return;
2020169240Sjfv}
2021169240Sjfv
2022169240Sjfv/**
2023169240Sjfv *  e1000_setup_link_ich8lan - Setup flow control and link settings
2024169240Sjfv *  @hw - pointer to the HW structure
2025169240Sjfv *
2026169240Sjfv *  Determines which flow control settings to use, then configures flow
2027169240Sjfv *  control.  Calls the appropriate media-specific link configuration
2028169240Sjfv *  function.  Assuming the adapter has a valid link partner, a valid link
2029169240Sjfv *  should be established.  Assumes the hardware has previously been reset
2030169240Sjfv *  and the transmitter and receiver are not enabled.
2031169240Sjfv **/
2032169240SjfvSTATIC s32
2033169240Sjfve1000_setup_link_ich8lan(struct e1000_hw *hw)
2034169240Sjfv{
2035169240Sjfv	struct e1000_mac_info *mac = &hw->mac;
2036169240Sjfv	struct e1000_functions *func = &hw->func;
2037169240Sjfv	s32 ret_val = E1000_SUCCESS;
2038169240Sjfv
2039169240Sjfv	DEBUGFUNC("e1000_setup_link_ich8lan");
2040169240Sjfv
2041169240Sjfv	if (e1000_check_reset_block(hw))
2042169240Sjfv		goto out;
2043169240Sjfv
2044169240Sjfv	/* ICH parts do not have a word in the NVM to determine
2045169240Sjfv	 * the default flow control setting, so we explicitly
2046169240Sjfv	 * set it to full.
2047169240Sjfv	 */
2048169240Sjfv	if (mac->fc == e1000_fc_default)
2049169240Sjfv		mac->fc = e1000_fc_full;
2050169240Sjfv
2051169240Sjfv	mac->original_fc = mac->fc;
2052169240Sjfv
2053169240Sjfv	DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc);
2054169240Sjfv
2055169240Sjfv	/* Continue to configure the copper link. */
2056169240Sjfv	ret_val = func->setup_physical_interface(hw);
2057169240Sjfv	if (ret_val)
2058169240Sjfv		goto out;
2059169240Sjfv
2060169240Sjfv	E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time);
2061169240Sjfv
2062169240Sjfv	ret_val = e1000_set_fc_watermarks_generic(hw);
2063169240Sjfv
2064169240Sjfvout:
2065169240Sjfv	return ret_val;
2066169240Sjfv}
2067169240Sjfv
2068169240Sjfv/**
2069169240Sjfv *  e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface
2070169240Sjfv *  @hw - pointer to the HW structure
2071169240Sjfv *
2072169240Sjfv *  Configures the kumeran interface to the PHY to wait the appropriate time
2073169240Sjfv *  when polling the PHY, then call the generic setup_copper_link to finish
2074169240Sjfv *  configuring the copper link.
2075169240Sjfv **/
2076169240SjfvSTATIC s32
2077169240Sjfve1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
2078169240Sjfv{
2079169240Sjfv	u32 ctrl;
2080169240Sjfv	s32 ret_val;
2081169240Sjfv	u16 reg_data;
2082169240Sjfv
2083169240Sjfv	DEBUGFUNC("e1000_setup_copper_link_ich8lan");
2084169240Sjfv
2085169240Sjfv	ctrl = E1000_READ_REG(hw, E1000_CTRL);
2086169240Sjfv	ctrl |= E1000_CTRL_SLU;
2087169240Sjfv	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
2088169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
2089169240Sjfv
2090169240Sjfv	/* Set the mac to wait the maximum time between each iteration
2091169240Sjfv	 * and increase the max iterations when polling the phy;
2092169240Sjfv	 * this fixes erroneous timeouts at 10Mbps. */
2093169240Sjfv	ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
2094169240Sjfv	if (ret_val)
2095169240Sjfv		goto out;
2096169240Sjfv	ret_val = e1000_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
2097169240Sjfv	if (ret_val)
2098169240Sjfv		goto out;
2099169240Sjfv	reg_data |= 0x3F;
2100169240Sjfv	ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
2101169240Sjfv	if (ret_val)
2102169240Sjfv		goto out;
2103169240Sjfv
2104169240Sjfv	if (hw->phy.type == e1000_phy_igp_3) {
2105169240Sjfv		ret_val = e1000_copper_link_setup_igp(hw);
2106169240Sjfv		if (ret_val)
2107169240Sjfv			goto out;
2108169240Sjfv	}
2109169240Sjfv
2110169240Sjfv	ret_val = e1000_setup_copper_link_generic(hw);
2111169240Sjfv
2112169240Sjfvout:
2113169240Sjfv	return ret_val;
2114169240Sjfv}
2115169240Sjfv
2116169240Sjfv/**
2117169240Sjfv *  e1000_get_link_up_info_ich8lan - Get current link speed and duplex
2118169240Sjfv *  @hw - pointer to the HW structure
2119169240Sjfv *  @speed - pointer to store current link speed
2120169240Sjfv *  @duplex - pointer to store the current link duplex
2121169240Sjfv *
2122169240Sjfv *  Calls the generic get_speed_and_duplex to retreive the current link
2123169240Sjfv *  information and then calls the Kumeran lock loss workaround for links at
2124169240Sjfv *  gigabit speeds.
2125169240Sjfv **/
2126169240SjfvSTATIC s32
2127169240Sjfve1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, u16 *duplex)
2128169240Sjfv{
2129169240Sjfv	s32 ret_val;
2130169240Sjfv
2131169240Sjfv	DEBUGFUNC("e1000_get_link_up_info_ich8lan");
2132169240Sjfv
2133169240Sjfv	ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex);
2134169240Sjfv	if (ret_val)
2135169240Sjfv		goto out;
2136169240Sjfv
2137169240Sjfv	if ((hw->mac.type == e1000_ich8lan) &&
2138169240Sjfv	    (hw->phy.type == e1000_phy_igp_3) &&
2139169240Sjfv	    (*speed == SPEED_1000)) {
2140169240Sjfv		ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw);
2141169240Sjfv	}
2142169240Sjfv
2143169240Sjfvout:
2144169240Sjfv	return ret_val;
2145169240Sjfv}
2146169240Sjfv
2147169240Sjfv/**
2148169240Sjfv *  e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround
2149169240Sjfv *  @hw - pointer to the HW structure
2150169240Sjfv *
2151169240Sjfv *  Work-around for 82566 Kumeran PCS lock loss:
2152169240Sjfv *  On link status change (i.e. PCI reset, speed change) and link is up and
2153169240Sjfv *  speed is gigabit-
2154169240Sjfv *    0) if workaround is optionally disabled do nothing
2155169240Sjfv *    1) wait 1ms for Kumeran link to come up
2156169240Sjfv *    2) check Kumeran Diagnostic register PCS lock loss bit
2157169240Sjfv *    3) if not set the link is locked (all is good), otherwise...
2158169240Sjfv *    4) reset the PHY
2159169240Sjfv *    5) repeat up to 10 times
2160169240Sjfv *  Note: this is only called for IGP3 copper when speed is 1gb.
2161169240Sjfv **/
2162169240Sjfvstatic s32
2163169240Sjfve1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
2164169240Sjfv{
2165169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
2166169240Sjfv	u32 phy_ctrl;
2167169240Sjfv	s32 ret_val = E1000_SUCCESS;
2168169240Sjfv	u16 i, data;
2169169240Sjfv	boolean_t link;
2170169240Sjfv
2171169240Sjfv	DEBUGFUNC("e1000_kmrn_lock_loss_workaround_ich8lan");
2172169240Sjfv
2173169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
2174169240Sjfv
2175169240Sjfv	if (dev_spec == NULL) {
2176169240Sjfv		DEBUGOUT("dev_spec pointer is set to NULL.\n");
2177169240Sjfv		ret_val = -E1000_ERR_CONFIG;
2178169240Sjfv		goto out;
2179169240Sjfv	}
2180169240Sjfv
2181169240Sjfv	if (dev_spec->kmrn_lock_loss_workaround_enabled == FALSE)
2182169240Sjfv		goto out;
2183169240Sjfv
2184169240Sjfv	/* Make sure link is up before proceeding.  If not just return.
2185169240Sjfv	 * Attempting this while link is negotiating fouled up link
2186169240Sjfv	 * stability */
2187169240Sjfv	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
2188169240Sjfv	if (!link) {
2189169240Sjfv		ret_val = E1000_SUCCESS;
2190169240Sjfv		goto out;
2191169240Sjfv	}
2192169240Sjfv
2193169240Sjfv	for (i = 0; i < 10; i++) {
2194169240Sjfv		/* read once to clear */
2195169240Sjfv		ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &data);
2196169240Sjfv		if (ret_val)
2197169240Sjfv			goto out;
2198169240Sjfv		/* and again to get new status */
2199169240Sjfv		ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &data);
2200169240Sjfv		if (ret_val)
2201169240Sjfv			goto out;
2202169240Sjfv
2203169240Sjfv		/* check for PCS lock */
2204169240Sjfv		if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS)) {
2205169240Sjfv			ret_val = E1000_SUCCESS;
2206169240Sjfv			goto out;
2207169240Sjfv		}
2208169240Sjfv
2209169240Sjfv		/* Issue PHY reset */
2210169240Sjfv		e1000_phy_hw_reset(hw);
2211169240Sjfv		msec_delay_irq(5);
2212169240Sjfv	}
2213169240Sjfv	/* Disable GigE link negotiation */
2214169240Sjfv	phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
2215169240Sjfv	phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE |
2216169240Sjfv	             E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
2217169240Sjfv	E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
2218169240Sjfv
2219169240Sjfv	/* Call gig speed drop workaround on Giga disable before accessing
2220169240Sjfv	 * any PHY registers */
2221169240Sjfv	e1000_gig_downshift_workaround_ich8lan(hw);
2222169240Sjfv
2223169240Sjfv	/* unable to acquire PCS lock */
2224169240Sjfv	ret_val = -E1000_ERR_PHY;
2225169240Sjfv
2226169240Sjfvout:
2227169240Sjfv	return ret_val;
2228169240Sjfv}
2229169240Sjfv
2230169240Sjfv/**
2231169240Sjfv *  e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state
2232169240Sjfv *  @hw - pointer to the HW structure
2233169240Sjfv *  @state - boolean value used to set the current Kumaran workaround state
2234169240Sjfv *
2235169240Sjfv *  If ICH8, set the current Kumeran workaround state (enabled - TRUE
2236169240Sjfv *  /disabled - FALSE).
2237169240Sjfv **/
2238169240Sjfvvoid
2239169240Sjfve1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
2240169240Sjfv                                            boolean_t state)
2241169240Sjfv{
2242169240Sjfv	struct e1000_dev_spec_ich8lan *dev_spec;
2243169240Sjfv
2244169240Sjfv	DEBUGFUNC("e1000_set_kmrn_lock_loss_workaround_ich8lan");
2245169240Sjfv
2246169240Sjfv	if (hw->mac.type != e1000_ich8lan) {
2247169240Sjfv		DEBUGOUT("Workaround applies to ICH8 only.\n");
2248169240Sjfv		goto out;
2249169240Sjfv	}
2250169240Sjfv
2251169240Sjfv	dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec;
2252169240Sjfv
2253169240Sjfv	if (dev_spec == NULL) {
2254169240Sjfv		DEBUGOUT("dev_spec pointer is set to NULL.\n");
2255169240Sjfv		goto out;
2256169240Sjfv	}
2257169240Sjfv
2258169240Sjfv	dev_spec->kmrn_lock_loss_workaround_enabled = state;
2259169240Sjfv
2260169240Sjfvout:
2261169240Sjfv	return;
2262169240Sjfv}
2263169240Sjfv
2264169240Sjfv/**
2265169240Sjfv *  e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3
2266169240Sjfv *  @hw - pointer to the HW structure
2267169240Sjfv *
2268169240Sjfv *  Workaround for 82566 power-down on D3 entry:
2269169240Sjfv *    1) disable gigabit link
2270169240Sjfv *    2) write VR power-down enable
2271169240Sjfv *    3) read it back
2272169240Sjfv *  Continue if successful, else issue LCD reset and repeat
2273169240Sjfv **/
2274169240Sjfvvoid
2275169240Sjfve1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
2276169240Sjfv{
2277169240Sjfv	u32 reg;
2278169240Sjfv	u16 data;
2279169240Sjfv	u8  retry = 0;
2280169240Sjfv
2281169240Sjfv	DEBUGFUNC("e1000_igp3_phy_powerdown_workaround_ich8lan");
2282169240Sjfv
2283169240Sjfv	if (hw->phy.type != e1000_phy_igp_3)
2284169240Sjfv		goto out;
2285169240Sjfv
2286169240Sjfv	/* Try the workaround twice (if needed) */
2287169240Sjfv	do {
2288169240Sjfv		/* Disable link */
2289169240Sjfv		reg = E1000_READ_REG(hw, E1000_PHY_CTRL);
2290169240Sjfv		reg |= (E1000_PHY_CTRL_GBE_DISABLE |
2291169240Sjfv		        E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
2292169240Sjfv		E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg);
2293169240Sjfv
2294169240Sjfv		/* Call gig speed drop workaround on Giga disable before
2295169240Sjfv		 * accessing any PHY registers */
2296169240Sjfv		if (hw->mac.type == e1000_ich8lan)
2297169240Sjfv			e1000_gig_downshift_workaround_ich8lan(hw);
2298169240Sjfv
2299169240Sjfv		/* Write VR power-down enable */
2300169240Sjfv		e1000_read_phy_reg(hw, IGP3_VR_CTRL, &data);
2301169240Sjfv		data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
2302169240Sjfv		e1000_write_phy_reg(hw,
2303169240Sjfv		                   IGP3_VR_CTRL,
2304169240Sjfv		                   data | IGP3_VR_CTRL_MODE_SHUTDOWN);
2305169240Sjfv
2306169240Sjfv		/* Read it back and test */
2307169240Sjfv		e1000_read_phy_reg(hw, IGP3_VR_CTRL, &data);
2308169240Sjfv		if ((data & IGP3_VR_CTRL_MODE_SHUTDOWN) || retry)
2309169240Sjfv			break;
2310169240Sjfv
2311169240Sjfv		/* Issue PHY reset and repeat at most one more time */
2312169240Sjfv		reg = E1000_READ_REG(hw, E1000_CTRL);
2313169240Sjfv		E1000_WRITE_REG(hw, E1000_CTRL, reg | E1000_CTRL_PHY_RST);
2314169240Sjfv		retry++;
2315169240Sjfv	} while (retry);
2316169240Sjfv
2317169240Sjfvout:
2318169240Sjfv	return;
2319169240Sjfv}
2320169240Sjfv
2321169240Sjfv/**
2322169240Sjfv *  e1000_gig_downshift_workaround_ich8lan - WoL from S5 stops working
2323169240Sjfv *  @hw - pointer to the HW structure
2324169240Sjfv *
2325169240Sjfv *  Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
2326169240Sjfv *  LPLU, Giga disable, MDIC PHY reset):
2327169240Sjfv *    1) Set Kumeran Near-end loopback
2328169240Sjfv *    2) Clear Kumeran Near-end loopback
2329169240Sjfv *  Should only be called for ICH8[m] devices with IGP_3 Phy.
2330169240Sjfv **/
2331169240Sjfvvoid
2332169240Sjfve1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
2333169240Sjfv{
2334169240Sjfv	s32 ret_val = E1000_SUCCESS;
2335169240Sjfv	u16 reg_data;
2336169240Sjfv
2337169240Sjfv	DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan");
2338169240Sjfv
2339169240Sjfv	if ((hw->mac.type != e1000_ich8lan) ||
2340169240Sjfv	    (hw->phy.type != e1000_phy_igp_3))
2341169240Sjfv		goto out;
2342169240Sjfv
2343169240Sjfv	ret_val = e1000_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
2344169240Sjfv				      &reg_data);
2345169240Sjfv	if (ret_val)
2346169240Sjfv		goto out;
2347169240Sjfv	reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK;
2348169240Sjfv	ret_val = e1000_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
2349169240Sjfv	                               reg_data);
2350169240Sjfv	if (ret_val)
2351169240Sjfv		goto out;
2352169240Sjfv	reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK;
2353169240Sjfv	ret_val = e1000_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
2354169240Sjfv				       reg_data);
2355169240Sjfvout:
2356169240Sjfv	return;
2357169240Sjfv}
2358169240Sjfv
2359169240Sjfv/**
2360169240Sjfv *  e1000_cleanup_led_ich8lan - Restore the default LED operation
2361169240Sjfv *  @hw - pointer to the HW structure
2362169240Sjfv *
2363169240Sjfv *  Return the LED back to the default configuration.
2364169240Sjfv **/
2365169240SjfvSTATIC s32
2366169240Sjfve1000_cleanup_led_ich8lan(struct e1000_hw *hw)
2367169240Sjfv{
2368169240Sjfv	s32 ret_val = E1000_SUCCESS;
2369169240Sjfv
2370169240Sjfv	DEBUGFUNC("e1000_cleanup_led_ich8lan");
2371169240Sjfv
2372169240Sjfv	if (hw->phy.type == e1000_phy_ife)
2373169240Sjfv		ret_val = e1000_write_phy_reg(hw,
2374169240Sjfv		                                IFE_PHY_SPECIAL_CONTROL_LED,
2375169240Sjfv		                                0);
2376169240Sjfv	else
2377169240Sjfv		E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default);
2378169240Sjfv
2379169240Sjfv	return ret_val;
2380169240Sjfv}
2381169240Sjfv
2382169240Sjfv/**
2383169240Sjfv *  e1000_led_on_ich8lan - Turn LED's on
2384169240Sjfv *  @hw - pointer to the HW structure
2385169240Sjfv *
2386169240Sjfv *  Turn on the LED's.
2387169240Sjfv **/
2388169240SjfvSTATIC s32
2389169240Sjfve1000_led_on_ich8lan(struct e1000_hw *hw)
2390169240Sjfv{
2391169240Sjfv	s32 ret_val = E1000_SUCCESS;
2392169240Sjfv
2393169240Sjfv	DEBUGFUNC("e1000_led_on_ich8lan");
2394169240Sjfv
2395169240Sjfv	if (hw->phy.type == e1000_phy_ife)
2396169240Sjfv		ret_val = e1000_write_phy_reg(hw,
2397169240Sjfv		                IFE_PHY_SPECIAL_CONTROL_LED,
2398169240Sjfv		                (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
2399169240Sjfv	else
2400169240Sjfv		E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2);
2401169240Sjfv
2402169240Sjfv	return ret_val;
2403169240Sjfv}
2404169240Sjfv
2405169240Sjfv/**
2406169240Sjfv *  e1000_led_off_ich8lan - Turn LED's off
2407169240Sjfv *  @hw - pointer to the HW structure
2408169240Sjfv *
2409169240Sjfv *  Turn off the LED's.
2410169240Sjfv **/
2411169240SjfvSTATIC s32
2412169240Sjfve1000_led_off_ich8lan(struct e1000_hw *hw)
2413169240Sjfv{
2414169240Sjfv	s32 ret_val = E1000_SUCCESS;
2415169240Sjfv
2416169240Sjfv	DEBUGFUNC("e1000_led_off_ich8lan");
2417169240Sjfv
2418169240Sjfv	if (hw->phy.type == e1000_phy_ife)
2419169240Sjfv		ret_val = e1000_write_phy_reg(hw,
2420169240Sjfv		               IFE_PHY_SPECIAL_CONTROL_LED,
2421169240Sjfv		               (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
2422169240Sjfv	else
2423169240Sjfv		E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1);
2424169240Sjfv
2425169240Sjfv	return ret_val;
2426169240Sjfv}
2427169240Sjfv
2428169240Sjfv/**
2429169240Sjfv *  e1000_get_cfg_done_ich8lan - Read config done bit
2430169240Sjfv *  @hw - pointer to the HW structure
2431169240Sjfv *
2432169240Sjfv *  Read the management control register for the config done bit for
2433169240Sjfv *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
2434169240Sjfv *  to read the config done bit, so an error is *ONLY* logged and returns
2435169240Sjfv *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
2436169240Sjfv *  would not be able to be reset or change link.
2437169240Sjfv **/
2438169240SjfvSTATIC s32
2439169240Sjfve1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
2440169240Sjfv{
2441169240Sjfv	e1000_get_cfg_done_generic(hw);
2442169240Sjfv
2443169240Sjfv	/* If EEPROM is not marked present, init the IGP 3 PHY manually */
2444169240Sjfv	if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
2445169240Sjfv	    (hw->phy.type == e1000_phy_igp_3)) {
2446169240Sjfv		e1000_phy_init_script_igp3(hw);
2447169240Sjfv	}
2448169240Sjfv
2449169240Sjfv	return E1000_SUCCESS;
2450169240Sjfv}
2451169240Sjfv
2452169240Sjfv/**
2453169240Sjfv *  e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
2454169240Sjfv *  @hw - pointer to the HW structure
2455169240Sjfv *
2456169240Sjfv *  Clears hardware counters specific to the silicon family and calls
2457169240Sjfv *  clear_hw_cntrs_generic to clear all general purpose counters.
2458169240Sjfv **/
2459169240SjfvSTATIC void
2460169240Sjfve1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
2461169240Sjfv{
2462169240Sjfv	volatile u32 temp;
2463169240Sjfv
2464169240Sjfv	DEBUGFUNC("e1000_clear_hw_cntrs_ich8lan");
2465169240Sjfv
2466169240Sjfv	e1000_clear_hw_cntrs_base_generic(hw);
2467169240Sjfv
2468169240Sjfv	temp = E1000_READ_REG(hw, E1000_ALGNERRC);
2469169240Sjfv	temp = E1000_READ_REG(hw, E1000_RXERRC);
2470169240Sjfv	temp = E1000_READ_REG(hw, E1000_TNCRS);
2471169240Sjfv	temp = E1000_READ_REG(hw, E1000_CEXTERR);
2472169240Sjfv	temp = E1000_READ_REG(hw, E1000_TSCTC);
2473169240Sjfv	temp = E1000_READ_REG(hw, E1000_TSCTFC);
2474169240Sjfv
2475169240Sjfv	temp = E1000_READ_REG(hw, E1000_MGTPRC);
2476169240Sjfv	temp = E1000_READ_REG(hw, E1000_MGTPDC);
2477169240Sjfv	temp = E1000_READ_REG(hw, E1000_MGTPTC);
2478169240Sjfv
2479169240Sjfv	temp = E1000_READ_REG(hw, E1000_IAC);
2480169240Sjfv	temp = E1000_READ_REG(hw, E1000_ICRXOC);
2481169240Sjfv}
2482169240Sjfv
2483