e1000 - Literally import e1000 driver from FreeBSD
[dragonfly.git] / sys / dev / netif / e1000 / e1000_manage.c
blob2cd85b3a9e8c37212c255984b0b2a521cd91ce26
1 /******************************************************************************
3 Copyright (c) 2001-2010, Intel Corporation
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ******************************************************************************/
33 /*$FreeBSD$*/
35 #include "e1000_api.h"
37 static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
39 /**
40 * e1000_calculate_checksum - Calculate checksum for buffer
41 * @buffer: pointer to EEPROM
42 * @length: size of EEPROM to calculate a checksum for
44 * Calculates the checksum for some buffer on a specified length. The
45 * checksum calculated is returned.
46 **/
47 static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
49 u32 i;
50 u8 sum = 0;
52 DEBUGFUNC("e1000_calculate_checksum");
54 if (!buffer)
55 return 0;
57 for (i = 0; i < length; i++)
58 sum += buffer[i];
60 return (u8) (0 - sum);
63 /**
64 * e1000_mng_enable_host_if_generic - Checks host interface is enabled
65 * @hw: pointer to the HW structure
67 * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
69 * This function checks whether the HOST IF is enabled for command operation
70 * and also checks whether the previous command is completed. It busy waits
71 * in case of previous command is not completed.
72 **/
73 s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
75 u32 hicr;
76 s32 ret_val = E1000_SUCCESS;
77 u8 i;
79 DEBUGFUNC("e1000_mng_enable_host_if_generic");
81 /* Check that the host interface is enabled. */
82 hicr = E1000_READ_REG(hw, E1000_HICR);
83 if ((hicr & E1000_HICR_EN) == 0) {
84 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
85 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
86 goto out;
88 /* check the previous command is completed */
89 for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
90 hicr = E1000_READ_REG(hw, E1000_HICR);
91 if (!(hicr & E1000_HICR_C))
92 break;
93 msec_delay_irq(1);
96 if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
97 DEBUGOUT("Previous command timeout failed .\n");
98 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
99 goto out;
102 out:
103 return ret_val;
107 * e1000_check_mng_mode_generic - Generic check management mode
108 * @hw: pointer to the HW structure
110 * Reads the firmware semaphore register and returns TRUE (>0) if
111 * manageability is enabled, else FALSE (0).
113 bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
115 u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
117 DEBUGFUNC("e1000_check_mng_mode_generic");
120 return (fwsm & E1000_FWSM_MODE_MASK) ==
121 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
125 * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
126 * @hw: pointer to the HW structure
128 * Enables packet filtering on transmit packets if manageability is enabled
129 * and host interface is enabled.
131 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
133 struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
134 u32 *buffer = (u32 *)&hw->mng_cookie;
135 u32 offset;
136 s32 ret_val, hdr_csum, csum;
137 u8 i, len;
139 DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
141 hw->mac.tx_pkt_filtering = TRUE;
143 /* No manageability, no filtering */
144 if (!hw->mac.ops.check_mng_mode(hw)) {
145 hw->mac.tx_pkt_filtering = FALSE;
146 goto out;
150 * If we can't read from the host interface for whatever
151 * reason, disable filtering.
153 ret_val = hw->mac.ops.mng_enable_host_if(hw);
154 if (ret_val != E1000_SUCCESS) {
155 hw->mac.tx_pkt_filtering = FALSE;
156 goto out;
159 /* Read in the header. Length and offset are in dwords. */
160 len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
161 offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
162 for (i = 0; i < len; i++)
163 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
164 offset + i);
165 hdr_csum = hdr->checksum;
166 hdr->checksum = 0;
167 csum = e1000_calculate_checksum((u8 *)hdr,
168 E1000_MNG_DHCP_COOKIE_LENGTH);
170 * If either the checksums or signature don't match, then
171 * the cookie area isn't considered valid, in which case we
172 * take the safe route of assuming Tx filtering is enabled.
174 if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
175 hw->mac.tx_pkt_filtering = TRUE;
176 goto out;
179 /* Cookie area is valid, make the final check for filtering. */
180 if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
181 hw->mac.tx_pkt_filtering = FALSE;
182 goto out;
185 out:
186 return hw->mac.tx_pkt_filtering;
190 * e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
191 * @hw: pointer to the HW structure
192 * @buffer: pointer to the host interface
193 * @length: size of the buffer
195 * Writes the DHCP information to the host interface.
197 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
198 u16 length)
200 struct e1000_host_mng_command_header hdr;
201 s32 ret_val;
202 u32 hicr;
204 DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
206 hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
207 hdr.command_length = length;
208 hdr.reserved1 = 0;
209 hdr.reserved2 = 0;
210 hdr.checksum = 0;
212 /* Enable the host interface */
213 ret_val = hw->mac.ops.mng_enable_host_if(hw);
214 if (ret_val)
215 goto out;
217 /* Populate the host interface with the contents of "buffer". */
218 ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
219 sizeof(hdr), &(hdr.checksum));
220 if (ret_val)
221 goto out;
223 /* Write the manageability command header */
224 ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
225 if (ret_val)
226 goto out;
228 /* Tell the ARC a new command is pending. */
229 hicr = E1000_READ_REG(hw, E1000_HICR);
230 E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
232 out:
233 return ret_val;
237 * e1000_mng_write_cmd_header_generic - Writes manageability command header
238 * @hw: pointer to the HW structure
239 * @hdr: pointer to the host interface command header
241 * Writes the command header after does the checksum calculation.
243 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
244 struct e1000_host_mng_command_header *hdr)
246 u16 i, length = sizeof(struct e1000_host_mng_command_header);
248 DEBUGFUNC("e1000_mng_write_cmd_header_generic");
250 /* Write the whole command header structure with new checksum. */
252 hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
254 length >>= 2;
255 /* Write the relevant command block into the ram area. */
256 for (i = 0; i < length; i++) {
257 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
258 *((u32 *) hdr + i));
259 E1000_WRITE_FLUSH(hw);
262 return E1000_SUCCESS;
266 * e1000_mng_host_if_write_generic - Write to the manageability host interface
267 * @hw: pointer to the HW structure
268 * @buffer: pointer to the host interface buffer
269 * @length: size of the buffer
270 * @offset: location in the buffer to write to
271 * @sum: sum of the data (not checksum)
273 * This function writes the buffer content at the offset given on the host if.
274 * It also does alignment considerations to do the writes in most efficient
275 * way. Also fills up the sum of the buffer in *buffer parameter.
277 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
278 u16 length, u16 offset, u8 *sum)
280 u8 *tmp;
281 u8 *bufptr = buffer;
282 u32 data = 0;
283 s32 ret_val = E1000_SUCCESS;
284 u16 remaining, i, j, prev_bytes;
286 DEBUGFUNC("e1000_mng_host_if_write_generic");
288 /* sum = only sum of the data and it is not checksum */
290 if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
291 ret_val = -E1000_ERR_PARAM;
292 goto out;
295 tmp = (u8 *)&data;
296 prev_bytes = offset & 0x3;
297 offset >>= 2;
299 if (prev_bytes) {
300 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
301 for (j = prev_bytes; j < sizeof(u32); j++) {
302 *(tmp + j) = *bufptr++;
303 *sum += *(tmp + j);
305 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
306 length -= j - prev_bytes;
307 offset++;
310 remaining = length & 0x3;
311 length -= remaining;
313 /* Calculate length in DWORDs */
314 length >>= 2;
317 * The device driver writes the relevant command block into the
318 * ram area.
320 for (i = 0; i < length; i++) {
321 for (j = 0; j < sizeof(u32); j++) {
322 *(tmp + j) = *bufptr++;
323 *sum += *(tmp + j);
326 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
327 data);
329 if (remaining) {
330 for (j = 0; j < sizeof(u32); j++) {
331 if (j < remaining)
332 *(tmp + j) = *bufptr++;
333 else
334 *(tmp + j) = 0;
336 *sum += *(tmp + j);
338 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
341 out:
342 return ret_val;
346 * e1000_enable_mng_pass_thru - Check if management passthrough is needed
347 * @hw: pointer to the HW structure
349 * Verifies the hardware needs to leave interface enabled so that frames can
350 * be directed to and from the management interface.
352 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
354 u32 manc;
355 u32 fwsm, factps;
356 bool ret_val = FALSE;
358 DEBUGFUNC("e1000_enable_mng_pass_thru");
360 if (!hw->mac.asf_firmware_present)
361 goto out;
363 manc = E1000_READ_REG(hw, E1000_MANC);
365 if (!(manc & E1000_MANC_RCV_TCO_EN))
366 goto out;
368 if (hw->mac.arc_subsystem_valid) {
369 fwsm = E1000_READ_REG(hw, E1000_FWSM);
370 factps = E1000_READ_REG(hw, E1000_FACTPS);
372 if (!(factps & E1000_FACTPS_MNGCG) &&
373 ((fwsm & E1000_FWSM_MODE_MASK) ==
374 (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
375 ret_val = TRUE;
376 goto out;
378 } else {
379 if ((manc & E1000_MANC_SMBUS_EN) &&
380 !(manc & E1000_MANC_ASF_EN)) {
381 ret_val = TRUE;
382 goto out;
386 out:
387 return ret_val;