1a551c94aSIdo Barnea/*******************************************************************************
2a551c94aSIdo Barnea
3a551c94aSIdo BarneaCopyright (c) 2001-2015, Intel Corporation
4a551c94aSIdo BarneaAll rights reserved.
5a551c94aSIdo Barnea
6a551c94aSIdo BarneaRedistribution and use in source and binary forms, with or without
7a551c94aSIdo Barneamodification, are permitted provided that the following conditions are met:
8a551c94aSIdo Barnea
9a551c94aSIdo Barnea 1. Redistributions of source code must retain the above copyright notice,
10a551c94aSIdo Barnea    this list of conditions and the following disclaimer.
11a551c94aSIdo Barnea
12a551c94aSIdo Barnea 2. Redistributions in binary form must reproduce the above copyright
13a551c94aSIdo Barnea    notice, this list of conditions and the following disclaimer in the
14a551c94aSIdo Barnea    documentation and/or other materials provided with the distribution.
15a551c94aSIdo Barnea
16a551c94aSIdo Barnea 3. Neither the name of the Intel Corporation nor the names of its
17a551c94aSIdo Barnea    contributors may be used to endorse or promote products derived from
18a551c94aSIdo Barnea    this software without specific prior written permission.
19a551c94aSIdo Barnea
31a551c94aSIdo Barnea
32a551c94aSIdo Barnea***************************************************************************/
33a551c94aSIdo Barnea
34a551c94aSIdo Barnea#include "e1000_api.h"
35a551c94aSIdo Barnea
36a551c94aSIdo Barnea/**
37a551c94aSIdo Barnea *  e1000_calculate_checksum - Calculate checksum for buffer
38a551c94aSIdo Barnea *  @buffer: pointer to EEPROM
39a551c94aSIdo Barnea *  @length: size of EEPROM to calculate a checksum for
40a551c94aSIdo Barnea *
41a551c94aSIdo Barnea *  Calculates the checksum for some buffer on a specified length.  The
42a551c94aSIdo Barnea *  checksum calculated is returned.
43a551c94aSIdo Barnea **/
44a551c94aSIdo Barneau8 e1000_calculate_checksum(u8 *buffer, u32 length)
45a551c94aSIdo Barnea{
46a551c94aSIdo Barnea	u32 i;
47a551c94aSIdo Barnea	u8 sum = 0;
48a551c94aSIdo Barnea
49a551c94aSIdo Barnea	DEBUGFUNC("e1000_calculate_checksum");
50a551c94aSIdo Barnea
51a551c94aSIdo Barnea	if (!buffer)
52a551c94aSIdo Barnea		return 0;
53a551c94aSIdo Barnea
54a551c94aSIdo Barnea	for (i = 0; i < length; i++)
55a551c94aSIdo Barnea		sum += buffer[i];
56a551c94aSIdo Barnea
57a551c94aSIdo Barnea	return (u8) (0 - sum);
58a551c94aSIdo Barnea}
59a551c94aSIdo Barnea
60a551c94aSIdo Barnea/**
61a551c94aSIdo Barnea *  e1000_mng_enable_host_if_generic - Checks host interface is enabled
62a551c94aSIdo Barnea *  @hw: pointer to the HW structure
63a551c94aSIdo Barnea *
64a551c94aSIdo Barnea *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
65a551c94aSIdo Barnea *
66a551c94aSIdo Barnea *  This function checks whether the HOST IF is enabled for command operation
67a551c94aSIdo Barnea *  and also checks whether the previous command is completed.  It busy waits
68a551c94aSIdo Barnea *  in case of previous command is not completed.
69a551c94aSIdo Barnea **/
70a551c94aSIdo Barneas32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
71a551c94aSIdo Barnea{
72a551c94aSIdo Barnea	u32 hicr;
73a551c94aSIdo Barnea	u8 i;
74a551c94aSIdo Barnea
75a551c94aSIdo Barnea	DEBUGFUNC("e1000_mng_enable_host_if_generic");
76a551c94aSIdo Barnea
77a551c94aSIdo Barnea	if (!hw->mac.arc_subsystem_valid) {
78a551c94aSIdo Barnea		DEBUGOUT("ARC subsystem not valid.\n");
79a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
80a551c94aSIdo Barnea	}
81a551c94aSIdo Barnea
82a551c94aSIdo Barnea	/* Check that the host interface is enabled. */
83a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
84a551c94aSIdo Barnea	if (!(hicr & E1000_HICR_EN)) {
85a551c94aSIdo Barnea		DEBUGOUT("E1000_HOST_EN bit disabled.\n");
86a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
87a551c94aSIdo Barnea	}
88a551c94aSIdo Barnea	/* check the previous command is completed */
89a551c94aSIdo Barnea	for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
90a551c94aSIdo Barnea		hicr = E1000_READ_REG(hw, E1000_HICR);
91a551c94aSIdo Barnea		if (!(hicr & E1000_HICR_C))
92a551c94aSIdo Barnea			break;
93a551c94aSIdo Barnea		msec_delay_irq(1);
94a551c94aSIdo Barnea	}
95a551c94aSIdo Barnea
96a551c94aSIdo Barnea	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
97a551c94aSIdo Barnea		DEBUGOUT("Previous command timeout failed .\n");
98a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
99a551c94aSIdo Barnea	}
100a551c94aSIdo Barnea
101a551c94aSIdo Barnea	return E1000_SUCCESS;
102a551c94aSIdo Barnea}
103a551c94aSIdo Barnea
104a551c94aSIdo Barnea/**
105a551c94aSIdo Barnea *  e1000_check_mng_mode_generic - Generic check management mode
106a551c94aSIdo Barnea *  @hw: pointer to the HW structure
107a551c94aSIdo Barnea *
108a551c94aSIdo Barnea *  Reads the firmware semaphore register and returns true (>0) if
109a551c94aSIdo Barnea *  manageability is enabled, else false (0).
110a551c94aSIdo Barnea **/
111a551c94aSIdo Barneabool e1000_check_mng_mode_generic(struct e1000_hw *hw)
112a551c94aSIdo Barnea{
113a551c94aSIdo Barnea	u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
114a551c94aSIdo Barnea
115a551c94aSIdo Barnea	DEBUGFUNC("e1000_check_mng_mode_generic");
116a551c94aSIdo Barnea
117a551c94aSIdo Barnea
118a551c94aSIdo Barnea	return (fwsm & E1000_FWSM_MODE_MASK) ==
119a551c94aSIdo Barnea		(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
120a551c94aSIdo Barnea}
121a551c94aSIdo Barnea
122a551c94aSIdo Barnea/**
123a551c94aSIdo Barnea *  e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
124a551c94aSIdo Barnea *  @hw: pointer to the HW structure
125a551c94aSIdo Barnea *
126a551c94aSIdo Barnea *  Enables packet filtering on transmit packets if manageability is enabled
127a551c94aSIdo Barnea *  and host interface is enabled.
128a551c94aSIdo Barnea **/
129a551c94aSIdo Barneabool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
130a551c94aSIdo Barnea{
131a551c94aSIdo Barnea	struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
132a551c94aSIdo Barnea	u32 *buffer = (u32 *)&hw->mng_cookie;
133a551c94aSIdo Barnea	u32 offset;
134a551c94aSIdo Barnea	s32 ret_val, hdr_csum, csum;
135a551c94aSIdo Barnea	u8 i, len;
136a551c94aSIdo Barnea
137a551c94aSIdo Barnea	DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
138a551c94aSIdo Barnea
139a551c94aSIdo Barnea	hw->mac.tx_pkt_filtering = true;
140a551c94aSIdo Barnea
141a551c94aSIdo Barnea	/* No manageability, no filtering */
142a551c94aSIdo Barnea	if (!hw->mac.ops.check_mng_mode(hw)) {
143a551c94aSIdo Barnea		hw->mac.tx_pkt_filtering = false;
144a551c94aSIdo Barnea		return hw->mac.tx_pkt_filtering;
145a551c94aSIdo Barnea	}
146a551c94aSIdo Barnea
147a551c94aSIdo Barnea	/* If we can't read from the host interface for whatever
148a551c94aSIdo Barnea	 * reason, disable filtering.
149a551c94aSIdo Barnea	 */
150a551c94aSIdo Barnea	ret_val = e1000_mng_enable_host_if_generic(hw);
151a551c94aSIdo Barnea	if (ret_val != E1000_SUCCESS) {
152a551c94aSIdo Barnea		hw->mac.tx_pkt_filtering = false;
153a551c94aSIdo Barnea		return hw->mac.tx_pkt_filtering;
154a551c94aSIdo Barnea	}
155a551c94aSIdo Barnea
156a551c94aSIdo Barnea	/* Read in the header.  Length and offset are in dwords. */
157a551c94aSIdo Barnea	len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
158a551c94aSIdo Barnea	offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
159a551c94aSIdo Barnea	for (i = 0; i < len; i++)
160a551c94aSIdo Barnea		*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
161a551c94aSIdo Barnea							   offset + i);
162a551c94aSIdo Barnea	hdr_csum = hdr->checksum;
163a551c94aSIdo Barnea	hdr->checksum = 0;
164a551c94aSIdo Barnea	csum = e1000_calculate_checksum((u8 *)hdr,
165a551c94aSIdo Barnea					E1000_MNG_DHCP_COOKIE_LENGTH);
166a551c94aSIdo Barnea	/* If either the checksums or signature don't match, then
167a551c94aSIdo Barnea	 * the cookie area isn't considered valid, in which case we
168a551c94aSIdo Barnea	 * take the safe route of assuming Tx filtering is enabled.
169a551c94aSIdo Barnea	 */
170a551c94aSIdo Barnea	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
171a551c94aSIdo Barnea		hw->mac.tx_pkt_filtering = true;
172a551c94aSIdo Barnea		return hw->mac.tx_pkt_filtering;
173a551c94aSIdo Barnea	}
174a551c94aSIdo Barnea
175a551c94aSIdo Barnea	/* Cookie area is valid, make the final check for filtering. */
176a551c94aSIdo Barnea	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
177a551c94aSIdo Barnea		hw->mac.tx_pkt_filtering = false;
178a551c94aSIdo Barnea
179a551c94aSIdo Barnea	return hw->mac.tx_pkt_filtering;
180a551c94aSIdo Barnea}
181a551c94aSIdo Barnea
182a551c94aSIdo Barnea/**
183a551c94aSIdo Barnea *  e1000_mng_write_cmd_header_generic - Writes manageability command header
184a551c94aSIdo Barnea *  @hw: pointer to the HW structure
185a551c94aSIdo Barnea *  @hdr: pointer to the host interface command header
186a551c94aSIdo Barnea *
187a551c94aSIdo Barnea *  Writes the command header after does the checksum calculation.
188a551c94aSIdo Barnea **/
189a551c94aSIdo Barneas32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
190a551c94aSIdo Barnea				      struct e1000_host_mng_command_header *hdr)
191a551c94aSIdo Barnea{
192a551c94aSIdo Barnea	u16 i, length = sizeof(struct e1000_host_mng_command_header);
193a551c94aSIdo Barnea
194a551c94aSIdo Barnea	DEBUGFUNC("e1000_mng_write_cmd_header_generic");
195a551c94aSIdo Barnea
196a551c94aSIdo Barnea	/* Write the whole command header structure with new checksum. */
197a551c94aSIdo Barnea
198a551c94aSIdo Barnea	hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
199a551c94aSIdo Barnea
200a551c94aSIdo Barnea	length >>= 2;
201a551c94aSIdo Barnea	/* Write the relevant command block into the ram area. */
202a551c94aSIdo Barnea	for (i = 0; i < length; i++) {
203a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
204a551c94aSIdo Barnea					    *((u32 *) hdr + i));
205a551c94aSIdo Barnea		E1000_WRITE_FLUSH(hw);
206a551c94aSIdo Barnea	}
207a551c94aSIdo Barnea
208a551c94aSIdo Barnea	return E1000_SUCCESS;
209a551c94aSIdo Barnea}
210a551c94aSIdo Barnea
211a551c94aSIdo Barnea/**
212a551c94aSIdo Barnea *  e1000_mng_host_if_write_generic - Write to the manageability host interface
213a551c94aSIdo Barnea *  @hw: pointer to the HW structure
214a551c94aSIdo Barnea *  @buffer: pointer to the host interface buffer
215a551c94aSIdo Barnea *  @length: size of the buffer
216a551c94aSIdo Barnea *  @offset: location in the buffer to write to
217a551c94aSIdo Barnea *  @sum: sum of the data (not checksum)
218a551c94aSIdo Barnea *
219a551c94aSIdo Barnea *  This function writes the buffer content at the offset given on the host if.
220a551c94aSIdo Barnea *  It also does alignment considerations to do the writes in most efficient
221a551c94aSIdo Barnea *  way.  Also fills up the sum of the buffer in *buffer parameter.
222a551c94aSIdo Barnea **/
223a551c94aSIdo Barneas32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
224a551c94aSIdo Barnea				    u16 length, u16 offset, u8 *sum)
225a551c94aSIdo Barnea{
226a551c94aSIdo Barnea	u8 *tmp;
227a551c94aSIdo Barnea	u8 *bufptr = buffer;
228a551c94aSIdo Barnea	u32 data = 0;
229a551c94aSIdo Barnea	u16 remaining, i, j, prev_bytes;
230a551c94aSIdo Barnea
231a551c94aSIdo Barnea	DEBUGFUNC("e1000_mng_host_if_write_generic");
232a551c94aSIdo Barnea
233a551c94aSIdo Barnea	/* sum = only sum of the data and it is not checksum */
234a551c94aSIdo Barnea
235a551c94aSIdo Barnea	if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
236a551c94aSIdo Barnea		return -E1000_ERR_PARAM;
237a551c94aSIdo Barnea
238a551c94aSIdo Barnea	tmp = (u8 *)&data;
239a551c94aSIdo Barnea	prev_bytes = offset & 0x3;
240a551c94aSIdo Barnea	offset >>= 2;
241a551c94aSIdo Barnea
242a551c94aSIdo Barnea	if (prev_bytes) {
243a551c94aSIdo Barnea		data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
244a551c94aSIdo Barnea		for (j = prev_bytes; j < sizeof(u32); j++) {
245a551c94aSIdo Barnea			*(tmp + j) = *bufptr++;
246a551c94aSIdo Barnea			*sum += *(tmp + j);
247a551c94aSIdo Barnea		}
248a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
249a551c94aSIdo Barnea		length -= j - prev_bytes;
250a551c94aSIdo Barnea		offset++;
251a551c94aSIdo Barnea	}
252a551c94aSIdo Barnea
253a551c94aSIdo Barnea	remaining = length & 0x3;
254a551c94aSIdo Barnea	length -= remaining;
255a551c94aSIdo Barnea
256a551c94aSIdo Barnea	/* Calculate length in DWORDs */
257a551c94aSIdo Barnea	length >>= 2;
258a551c94aSIdo Barnea
259a551c94aSIdo Barnea	/* The device driver writes the relevant command block into the
260a551c94aSIdo Barnea	 * ram area.
261a551c94aSIdo Barnea	 */
262a551c94aSIdo Barnea	for (i = 0; i < length; i++) {
263a551c94aSIdo Barnea		for (j = 0; j < sizeof(u32); j++) {
264a551c94aSIdo Barnea			*(tmp + j) = *bufptr++;
265a551c94aSIdo Barnea			*sum += *(tmp + j);
266a551c94aSIdo Barnea		}
267a551c94aSIdo Barnea
268a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
269a551c94aSIdo Barnea					    data);
270a551c94aSIdo Barnea	}
271a551c94aSIdo Barnea	if (remaining) {
272a551c94aSIdo Barnea		for (j = 0; j < sizeof(u32); j++) {
273a551c94aSIdo Barnea			if (j < remaining)
274a551c94aSIdo Barnea				*(tmp + j) = *bufptr++;
275a551c94aSIdo Barnea			else
276a551c94aSIdo Barnea				*(tmp + j) = 0;
277a551c94aSIdo Barnea
278a551c94aSIdo Barnea			*sum += *(tmp + j);
279a551c94aSIdo Barnea		}
280a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
281a551c94aSIdo Barnea					    data);
282a551c94aSIdo Barnea	}
283a551c94aSIdo Barnea
284a551c94aSIdo Barnea	return E1000_SUCCESS;
285a551c94aSIdo Barnea}
286a551c94aSIdo Barnea
287a551c94aSIdo Barnea/**
288a551c94aSIdo Barnea *  e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
289a551c94aSIdo Barnea *  @hw: pointer to the HW structure
290a551c94aSIdo Barnea *  @buffer: pointer to the host interface
291a551c94aSIdo Barnea *  @length: size of the buffer
292a551c94aSIdo Barnea *
293a551c94aSIdo Barnea *  Writes the DHCP information to the host interface.
294a551c94aSIdo Barnea **/
295a551c94aSIdo Barneas32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
296a551c94aSIdo Barnea				      u16 length)
297a551c94aSIdo Barnea{
298a551c94aSIdo Barnea	struct e1000_host_mng_command_header hdr;
299a551c94aSIdo Barnea	s32 ret_val;
300a551c94aSIdo Barnea	u32 hicr;
301a551c94aSIdo Barnea
302a551c94aSIdo Barnea	DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
303a551c94aSIdo Barnea
304a551c94aSIdo Barnea	hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
305a551c94aSIdo Barnea	hdr.command_length = length;
306a551c94aSIdo Barnea	hdr.reserved1 = 0;
307a551c94aSIdo Barnea	hdr.reserved2 = 0;
308a551c94aSIdo Barnea	hdr.checksum = 0;
309a551c94aSIdo Barnea
310a551c94aSIdo Barnea	/* Enable the host interface */
311a551c94aSIdo Barnea	ret_val = e1000_mng_enable_host_if_generic(hw);
312a551c94aSIdo Barnea	if (ret_val)
313a551c94aSIdo Barnea		return ret_val;
314a551c94aSIdo Barnea
315a551c94aSIdo Barnea	/* Populate the host interface with the contents of "buffer". */
316a551c94aSIdo Barnea	ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
317a551c94aSIdo Barnea						  sizeof(hdr), &(hdr.checksum));
318a551c94aSIdo Barnea	if (ret_val)
319a551c94aSIdo Barnea		return ret_val;
320a551c94aSIdo Barnea
321a551c94aSIdo Barnea	/* Write the manageability command header */
322a551c94aSIdo Barnea	ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
323a551c94aSIdo Barnea	if (ret_val)
324a551c94aSIdo Barnea		return ret_val;
325a551c94aSIdo Barnea
326a551c94aSIdo Barnea	/* Tell the ARC a new command is pending. */
327a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
328a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
329a551c94aSIdo Barnea
330a551c94aSIdo Barnea	return E1000_SUCCESS;
331a551c94aSIdo Barnea}
332a551c94aSIdo Barnea
333a551c94aSIdo Barnea/**
334a551c94aSIdo Barnea *  e1000_enable_mng_pass_thru - Check if management passthrough is needed
335a551c94aSIdo Barnea *  @hw: pointer to the HW structure
336a551c94aSIdo Barnea *
337a551c94aSIdo Barnea *  Verifies the hardware needs to leave interface enabled so that frames can
338a551c94aSIdo Barnea *  be directed to and from the management interface.
339a551c94aSIdo Barnea **/
340a551c94aSIdo Barneabool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
341a551c94aSIdo Barnea{
342a551c94aSIdo Barnea	u32 manc;
343a551c94aSIdo Barnea	u32 fwsm, factps;
344a551c94aSIdo Barnea
345a551c94aSIdo Barnea	DEBUGFUNC("e1000_enable_mng_pass_thru");
346a551c94aSIdo Barnea
347a551c94aSIdo Barnea	if (!hw->mac.asf_firmware_present)
348a551c94aSIdo Barnea		return false;
349a551c94aSIdo Barnea
350a551c94aSIdo Barnea	manc = E1000_READ_REG(hw, E1000_MANC);
351a551c94aSIdo Barnea
352a551c94aSIdo Barnea	if (!(manc & E1000_MANC_RCV_TCO_EN))
353a551c94aSIdo Barnea		return false;
354a551c94aSIdo Barnea
355a551c94aSIdo Barnea	if (hw->mac.has_fwsm) {
356a551c94aSIdo Barnea		fwsm = E1000_READ_REG(hw, E1000_FWSM);
357a551c94aSIdo Barnea		factps = E1000_READ_REG(hw, E1000_FACTPS);
358a551c94aSIdo Barnea
359a551c94aSIdo Barnea		if (!(factps & E1000_FACTPS_MNGCG) &&
360a551c94aSIdo Barnea		    ((fwsm & E1000_FWSM_MODE_MASK) ==
361a551c94aSIdo Barnea		     (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
362a551c94aSIdo Barnea			return true;
363a551c94aSIdo Barnea	} else if ((hw->mac.type == e1000_82574) ||
364a551c94aSIdo Barnea		   (hw->mac.type == e1000_82583)) {
365a551c94aSIdo Barnea		u16 data;
366a551c94aSIdo Barnea		s32 ret_val;
367a551c94aSIdo Barnea
368a551c94aSIdo Barnea		factps = E1000_READ_REG(hw, E1000_FACTPS);
369a551c94aSIdo Barnea		ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
370a551c94aSIdo Barnea		if (ret_val)
371a551c94aSIdo Barnea			return false;
372a551c94aSIdo Barnea
373a551c94aSIdo Barnea		if (!(factps & E1000_FACTPS_MNGCG) &&
374a551c94aSIdo Barnea		    ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
375a551c94aSIdo Barnea		     (e1000_mng_mode_pt << 13)))
376a551c94aSIdo Barnea			return true;
377a551c94aSIdo Barnea	} else if ((manc & E1000_MANC_SMBUS_EN) &&
378a551c94aSIdo Barnea		   !(manc & E1000_MANC_ASF_EN)) {
379a551c94aSIdo Barnea		return true;
380a551c94aSIdo Barnea	}
381a551c94aSIdo Barnea
382a551c94aSIdo Barnea	return false;
383a551c94aSIdo Barnea}
384a551c94aSIdo Barnea
385a551c94aSIdo Barnea/**
386a551c94aSIdo Barnea *  e1000_host_interface_command - Writes buffer to host interface
387a551c94aSIdo Barnea *  @hw: pointer to the HW structure
388a551c94aSIdo Barnea *  @buffer: contains a command to write
389a551c94aSIdo Barnea *  @length: the byte length of the buffer, must be multiple of 4 bytes
390a551c94aSIdo Barnea *
391a551c94aSIdo Barnea *  Writes a buffer to the Host Interface.  Upon success, returns E1000_SUCCESS
392a551c94aSIdo Barnea *  else returns E1000_ERR_HOST_INTERFACE_COMMAND.
393a551c94aSIdo Barnea **/
394a551c94aSIdo Barneas32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
395a551c94aSIdo Barnea{
396a551c94aSIdo Barnea	u32 hicr, i;
397a551c94aSIdo Barnea
398a551c94aSIdo Barnea	DEBUGFUNC("e1000_host_interface_command");
399a551c94aSIdo Barnea
400a551c94aSIdo Barnea	if (!(hw->mac.arc_subsystem_valid)) {
401a551c94aSIdo Barnea		DEBUGOUT("Hardware doesn't support host interface command.\n");
402a551c94aSIdo Barnea		return E1000_SUCCESS;
403a551c94aSIdo Barnea	}
404a551c94aSIdo Barnea
405a551c94aSIdo Barnea	if (!hw->mac.asf_firmware_present) {
406a551c94aSIdo Barnea		DEBUGOUT("Firmware is not present.\n");
407a551c94aSIdo Barnea		return E1000_SUCCESS;
408a551c94aSIdo Barnea	}
409a551c94aSIdo Barnea
410a551c94aSIdo Barnea	if (length == 0 || length & 0x3 ||
411a551c94aSIdo Barnea	    length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
412a551c94aSIdo Barnea		DEBUGOUT("Buffer length failure.\n");
413a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
414a551c94aSIdo Barnea	}
415a551c94aSIdo Barnea
416a551c94aSIdo Barnea	/* Check that the host interface is enabled. */
417a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
418a551c94aSIdo Barnea	if (!(hicr & E1000_HICR_EN)) {
419a551c94aSIdo Barnea		DEBUGOUT("E1000_HOST_EN bit disabled.\n");
420a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
421a551c94aSIdo Barnea	}
422a551c94aSIdo Barnea
423a551c94aSIdo Barnea	/* Calculate length in DWORDs */
424a551c94aSIdo Barnea	length >>= 2;
425a551c94aSIdo Barnea
426a551c94aSIdo Barnea	/* The device driver writes the relevant command block
427a551c94aSIdo Barnea	 * into the ram area.
428a551c94aSIdo Barnea	 */
429a551c94aSIdo Barnea	for (i = 0; i < length; i++)
430a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
431a551c94aSIdo Barnea					    *((u32 *)buffer + i));
432a551c94aSIdo Barnea
433a551c94aSIdo Barnea	/* Setting this bit tells the ARC that a new command is pending. */
434a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
435a551c94aSIdo Barnea
436a551c94aSIdo Barnea	for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
437a551c94aSIdo Barnea		hicr = E1000_READ_REG(hw, E1000_HICR);
438a551c94aSIdo Barnea		if (!(hicr & E1000_HICR_C))
439a551c94aSIdo Barnea			break;
440a551c94aSIdo Barnea		msec_delay(1);
441a551c94aSIdo Barnea	}
442a551c94aSIdo Barnea
443a551c94aSIdo Barnea	/* Check command successful completion. */
444a551c94aSIdo Barnea	if (i == E1000_HI_COMMAND_TIMEOUT ||
445a551c94aSIdo Barnea	    (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
446a551c94aSIdo Barnea		DEBUGOUT("Command has failed with no status valid.\n");
447a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
448a551c94aSIdo Barnea	}
449a551c94aSIdo Barnea
450a551c94aSIdo Barnea	for (i = 0; i < length; i++)
451a551c94aSIdo Barnea		*((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
452a551c94aSIdo Barnea								  E1000_HOST_IF,
453a551c94aSIdo Barnea								  i);
454a551c94aSIdo Barnea
455a551c94aSIdo Barnea	return E1000_SUCCESS;
456a551c94aSIdo Barnea}
457a551c94aSIdo Barnea/**
458a551c94aSIdo Barnea *  e1000_load_firmware - Writes proxy FW code buffer to host interface
459a551c94aSIdo Barnea *                        and execute.
460a551c94aSIdo Barnea *  @hw: pointer to the HW structure
461a551c94aSIdo Barnea *  @buffer: contains a firmware to write
462a551c94aSIdo Barnea *  @length: the byte length of the buffer, must be multiple of 4 bytes
463a551c94aSIdo Barnea *
464a551c94aSIdo Barnea *  Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
465a551c94aSIdo Barnea *  in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
466a551c94aSIdo Barnea **/
467a551c94aSIdo Barneas32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
468a551c94aSIdo Barnea{
469a551c94aSIdo Barnea	u32 hicr, hibba, fwsm, icr, i;
470a551c94aSIdo Barnea
471a551c94aSIdo Barnea	DEBUGFUNC("e1000_load_firmware");
472a551c94aSIdo Barnea
473a551c94aSIdo Barnea	if (hw->mac.type < e1000_i210) {
474a551c94aSIdo Barnea		DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
475a551c94aSIdo Barnea		return -E1000_ERR_CONFIG;
476a551c94aSIdo Barnea	}
477a551c94aSIdo Barnea
478a551c94aSIdo Barnea	/* Check that the host interface is enabled. */
479a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
480a551c94aSIdo Barnea	if (!(hicr & E1000_HICR_EN)) {
481a551c94aSIdo Barnea		DEBUGOUT("E1000_HOST_EN bit disabled.\n");
482a551c94aSIdo Barnea		return -E1000_ERR_CONFIG;
483a551c94aSIdo Barnea	}
484a551c94aSIdo Barnea	if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
485a551c94aSIdo Barnea		DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
486a551c94aSIdo Barnea		return -E1000_ERR_CONFIG;
487a551c94aSIdo Barnea	}
488a551c94aSIdo Barnea
489a551c94aSIdo Barnea	if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
490a551c94aSIdo Barnea		DEBUGOUT("Buffer length failure.\n");
491a551c94aSIdo Barnea		return -E1000_ERR_INVALID_ARGUMENT;
492a551c94aSIdo Barnea	}
493a551c94aSIdo Barnea
494a551c94aSIdo Barnea	/* Clear notification from ROM-FW by reading ICR register */
495a551c94aSIdo Barnea	icr = E1000_READ_REG(hw, E1000_ICR_V2);
496a551c94aSIdo Barnea
497a551c94aSIdo Barnea	/* Reset ROM-FW */
498a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
499a551c94aSIdo Barnea	hicr |= E1000_HICR_FW_RESET_ENABLE;
500a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_HICR, hicr);
501a551c94aSIdo Barnea	hicr |= E1000_HICR_FW_RESET;
502a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_HICR, hicr);
503a551c94aSIdo Barnea	E1000_WRITE_FLUSH(hw);
504a551c94aSIdo Barnea
505a551c94aSIdo Barnea	/* Wait till MAC notifies about its readiness after ROM-FW reset */
506a551c94aSIdo Barnea	for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
507a551c94aSIdo Barnea		icr = E1000_READ_REG(hw, E1000_ICR_V2);
508a551c94aSIdo Barnea		if (icr & E1000_ICR_MNG)
509a551c94aSIdo Barnea			break;
510a551c94aSIdo Barnea		msec_delay(1);
511a551c94aSIdo Barnea	}
512a551c94aSIdo Barnea
513a551c94aSIdo Barnea	/* Check for timeout */
514a551c94aSIdo Barnea	if (i == E1000_HI_COMMAND_TIMEOUT) {
515a551c94aSIdo Barnea		DEBUGOUT("FW reset failed.\n");
516a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
517a551c94aSIdo Barnea	}
518a551c94aSIdo Barnea
519a551c94aSIdo Barnea	/* Wait till MAC is ready to accept new FW code */
520a551c94aSIdo Barnea	for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
521a551c94aSIdo Barnea		fwsm = E1000_READ_REG(hw, E1000_FWSM);
522a551c94aSIdo Barnea		if ((fwsm & E1000_FWSM_FW_VALID) &&
523a551c94aSIdo Barnea		    ((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
524a551c94aSIdo Barnea		    E1000_FWSM_HI_EN_ONLY_MODE))
525a551c94aSIdo Barnea			break;
526a551c94aSIdo Barnea		msec_delay(1);
527a551c94aSIdo Barnea	}
528a551c94aSIdo Barnea
529a551c94aSIdo Barnea	/* Check for timeout */
530a551c94aSIdo Barnea	if (i == E1000_HI_COMMAND_TIMEOUT) {
531a551c94aSIdo Barnea		DEBUGOUT("FW reset failed.\n");
532a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
533a551c94aSIdo Barnea	}
534a551c94aSIdo Barnea
535a551c94aSIdo Barnea	/* Calculate length in DWORDs */
536a551c94aSIdo Barnea	length >>= 2;
537a551c94aSIdo Barnea
538a551c94aSIdo Barnea	/* The device driver writes the relevant FW code block
539a551c94aSIdo Barnea	 * into the ram area in DWORDs via 1kB ram addressing window.
540a551c94aSIdo Barnea	 */
541a551c94aSIdo Barnea	for (i = 0; i < length; i++) {
542a551c94aSIdo Barnea		if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
543a551c94aSIdo Barnea			/* Point to correct 1kB ram window */
544a551c94aSIdo Barnea			hibba = E1000_HI_FW_BASE_ADDRESS +
545a551c94aSIdo Barnea				((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
546a551c94aSIdo Barnea				(i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
547a551c94aSIdo Barnea
548a551c94aSIdo Barnea			E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
549a551c94aSIdo Barnea		}
550a551c94aSIdo Barnea
551a551c94aSIdo Barnea		E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
552a551c94aSIdo Barnea					    i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
553a551c94aSIdo Barnea					    *((u32 *)buffer + i));
554a551c94aSIdo Barnea	}
555a551c94aSIdo Barnea
556a551c94aSIdo Barnea	/* Setting this bit tells the ARC that a new FW is ready to execute. */
557a551c94aSIdo Barnea	hicr = E1000_READ_REG(hw, E1000_HICR);
558a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
559a551c94aSIdo Barnea
560a551c94aSIdo Barnea	for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
561a551c94aSIdo Barnea		hicr = E1000_READ_REG(hw, E1000_HICR);
562a551c94aSIdo Barnea		if (!(hicr & E1000_HICR_C))
563a551c94aSIdo Barnea			break;
564a551c94aSIdo Barnea		msec_delay(1);
565a551c94aSIdo Barnea	}
566a551c94aSIdo Barnea
567a551c94aSIdo Barnea	/* Check for successful FW start. */
568a551c94aSIdo Barnea	if (i == E1000_HI_COMMAND_TIMEOUT) {
569a551c94aSIdo Barnea		DEBUGOUT("New FW did not start within timeout period.\n");
570a551c94aSIdo Barnea		return -E1000_ERR_HOST_INTERFACE_COMMAND;
571a551c94aSIdo Barnea	}
572a551c94aSIdo Barnea
573a551c94aSIdo Barnea	return E1000_SUCCESS;
574a551c94aSIdo Barnea}
575a551c94aSIdo Barnea
576a551c94aSIdo Barnea