FreeBSD kernel E1000 device code
e1000_manage.c
Go to the documentation of this file.
1/******************************************************************************
2 SPDX-License-Identifier: BSD-3-Clause
3
4 Copyright (c) 2001-2020, Intel Corporation
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 3. Neither the name of the Intel Corporation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32
33******************************************************************************/
34/*$FreeBSD$*/
35
36#include "e1000_api.h"
37#include "e1000_manage.h"
38
48{
49 u32 i;
50 u8 sum = 0;
51
52 DEBUGFUNC("e1000_calculate_checksum");
53
54 if (!buffer)
55 return 0;
56
57 for (i = 0; i < length; i++)
58 sum += buffer[i];
59
60 return (u8) (0 - sum);
61}
62
74{
75 u32 hicr;
76 u8 i;
77
78 DEBUGFUNC("e1000_mng_enable_host_if_generic");
79
80 if (!hw->mac.arc_subsystem_valid) {
81 DEBUGOUT("ARC subsystem not valid.\n");
83 }
84
85 /* Check that the host interface is enabled. */
86 hicr = E1000_READ_REG(hw, E1000_HICR);
87 if (!(hicr & E1000_HICR_EN)) {
88 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
90 }
91 /* check the previous command is completed */
92 for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
93 hicr = E1000_READ_REG(hw, E1000_HICR);
94 if (!(hicr & E1000_HICR_C))
95 break;
97 }
98
100 DEBUGOUT("Previous command timeout failed .\n");
102 }
103
104 return E1000_SUCCESS;
105}
106
115{
116 u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
117
118 DEBUGFUNC("e1000_check_mng_mode_generic");
119
120
121 return (fwsm & E1000_FWSM_MODE_MASK) ==
123}
124
133{
134 struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
135 u32 *buffer = (u32 *)&hw->mng_cookie;
136 u32 offset;
137 s32 ret_val, hdr_csum, csum;
138 u8 i, len;
139
140 DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
141
142 hw->mac.tx_pkt_filtering = true;
143
144 /* No manageability, no filtering */
145 if (!hw->mac.ops.check_mng_mode(hw)) {
146 hw->mac.tx_pkt_filtering = false;
147 return hw->mac.tx_pkt_filtering;
148 }
149
150 /* If we can't read from the host interface for whatever
151 * reason, disable filtering.
152 */
154 if (ret_val != E1000_SUCCESS) {
155 hw->mac.tx_pkt_filtering = false;
156 return hw->mac.tx_pkt_filtering;
157 }
158
159 /* Read in the header. Length and offset are in dwords. */
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,
169 /* If either the checksums or signature don't match, then
170 * the cookie area isn't considered valid, in which case we
171 * take the safe route of assuming Tx filtering is enabled.
172 */
173 if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
174 hw->mac.tx_pkt_filtering = true;
175 return hw->mac.tx_pkt_filtering;
176 }
177
178 /* Cookie area is valid, make the final check for filtering. */
180 hw->mac.tx_pkt_filtering = false;
181
182 return hw->mac.tx_pkt_filtering;
183}
184
194{
195 u16 i, length = sizeof(struct e1000_host_mng_command_header);
196
197 DEBUGFUNC("e1000_mng_write_cmd_header_generic");
198
199 /* Write the whole command header structure with new checksum. */
200
201 hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
202
203 length >>= 2;
204 /* Write the relevant command block into the ram area. */
205 for (i = 0; i < length; i++) {
207 *((u32 *) hdr + i));
209 }
210
211 return E1000_SUCCESS;
212}
213
227 u16 length, u16 offset, u8 *sum)
228{
229 u8 *tmp;
230 u8 *bufptr = buffer;
231 u32 data = 0;
232 u16 remaining, i, j, prev_bytes;
233
234 DEBUGFUNC("e1000_mng_host_if_write_generic");
235
236 /* sum = only sum of the data and it is not checksum */
237
238 if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
239 return -E1000_ERR_PARAM;
240
241 tmp = (u8 *)&data;
242 prev_bytes = offset & 0x3;
243 offset >>= 2;
244
245 if (prev_bytes) {
246 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
247 for (j = prev_bytes; j < sizeof(u32); j++) {
248 *(tmp + j) = *bufptr++;
249 *sum += *(tmp + j);
250 }
252 length -= j - prev_bytes;
253 offset++;
254 }
255
256 remaining = length & 0x3;
257 length -= remaining;
258
259 /* Calculate length in DWORDs */
260 length >>= 2;
261
262 /* The device driver writes the relevant command block into the
263 * ram area.
264 */
265 for (i = 0; i < length; i++) {
266 for (j = 0; j < sizeof(u32); j++) {
267 *(tmp + j) = *bufptr++;
268 *sum += *(tmp + j);
269 }
270
272 data);
273 }
274 if (remaining) {
275 for (j = 0; j < sizeof(u32); j++) {
276 if (j < remaining)
277 *(tmp + j) = *bufptr++;
278 else
279 *(tmp + j) = 0;
280
281 *sum += *(tmp + j);
282 }
284 data);
285 }
286
287 return E1000_SUCCESS;
288}
289
299 u16 length)
300{
302 s32 ret_val;
303 u32 hicr;
304
305 DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
306
308 hdr.command_length = length;
309 hdr.reserved1 = 0;
310 hdr.reserved2 = 0;
311 hdr.checksum = 0;
312
313 /* Enable the host interface */
315 if (ret_val)
316 return ret_val;
317
318 /* Populate the host interface with the contents of "buffer". */
319 ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
320 sizeof(hdr), &(hdr.checksum));
321 if (ret_val)
322 return ret_val;
323
324 /* Write the manageability command header */
325 ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
326 if (ret_val)
327 return ret_val;
328
329 /* Tell the ARC a new command is pending. */
330 hicr = E1000_READ_REG(hw, E1000_HICR);
332
333 return E1000_SUCCESS;
334}
335
344{
345 u32 manc;
346 u32 fwsm, factps;
347
348 DEBUGFUNC("e1000_enable_mng_pass_thru");
349
350 if (!hw->mac.asf_firmware_present)
351 return false;
352
353 manc = E1000_READ_REG(hw, E1000_MANC);
354
355 if (!(manc & E1000_MANC_RCV_TCO_EN))
356 return false;
357
358 if (hw->mac.has_fwsm) {
359 fwsm = E1000_READ_REG(hw, E1000_FWSM);
360 factps = E1000_READ_REG(hw, E1000_FACTPS);
361
362 if (!(factps & E1000_FACTPS_MNGCG) &&
363 ((fwsm & E1000_FWSM_MODE_MASK) ==
365 return true;
366 } else if ((hw->mac.type == e1000_82574) ||
367 (hw->mac.type == e1000_82583)) {
368 u16 data;
369 s32 ret_val;
370
371 factps = E1000_READ_REG(hw, E1000_FACTPS);
372 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
373 if (ret_val)
374 return false;
375
376 if (!(factps & E1000_FACTPS_MNGCG) &&
377 ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
378 (e1000_mng_mode_pt << 13)))
379 return true;
380 } else if ((manc & E1000_MANC_SMBUS_EN) &&
381 !(manc & E1000_MANC_ASF_EN)) {
382 return true;
383 }
384
385 return false;
386}
387
397s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
398{
399 u32 hicr, i;
400
401 DEBUGFUNC("e1000_host_interface_command");
402
403 if (!(hw->mac.arc_subsystem_valid)) {
404 DEBUGOUT("Hardware doesn't support host interface command.\n");
405 return E1000_SUCCESS;
406 }
407
408 if (!hw->mac.asf_firmware_present) {
409 DEBUGOUT("Firmware is not present.\n");
410 return E1000_SUCCESS;
411 }
412
413 if (length == 0 || length & 0x3 ||
415 DEBUGOUT("Buffer length failure.\n");
417 }
418
419 /* Check that the host interface is enabled. */
420 hicr = E1000_READ_REG(hw, E1000_HICR);
421 if (!(hicr & E1000_HICR_EN)) {
422 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
424 }
425
426 /* Calculate length in DWORDs */
427 length >>= 2;
428
429 /* The device driver writes the relevant command block
430 * into the ram area.
431 */
432 for (i = 0; i < length; i++)
434 *((u32 *)buffer + i));
435
436 /* Setting this bit tells the ARC that a new command is pending. */
438
439 for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
440 hicr = E1000_READ_REG(hw, E1000_HICR);
441 if (!(hicr & E1000_HICR_C))
442 break;
443 msec_delay(1);
444 }
445
446 /* Check command successful completion. */
447 if (i == E1000_HI_COMMAND_TIMEOUT ||
449 DEBUGOUT("Command has failed with no status valid.\n");
451 }
452
453 for (i = 0; i < length; i++)
454 *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
456 i);
457
458 return E1000_SUCCESS;
459}
460
471s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
472{
473 u32 hicr, hibba, fwsm, icr, i;
474
475 DEBUGFUNC("e1000_load_firmware");
476
477 if (hw->mac.type < e1000_i210) {
478 DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
479 return -E1000_ERR_CONFIG;
480 }
481
482 /* Check that the host interface is enabled. */
483 hicr = E1000_READ_REG(hw, E1000_HICR);
484 if (!(hicr & E1000_HICR_EN)) {
485 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
486 return -E1000_ERR_CONFIG;
487 }
488 if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
489 DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
490 return -E1000_ERR_CONFIG;
491 }
492
493 if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
494 DEBUGOUT("Buffer length failure.\n");
496 }
497
498 /* Clear notification from ROM-FW by reading ICR register */
499 icr = E1000_READ_REG(hw, E1000_ICR_V2);
500
501 /* Reset ROM-FW */
502 hicr = E1000_READ_REG(hw, E1000_HICR);
504 E1000_WRITE_REG(hw, E1000_HICR, hicr);
505 hicr |= E1000_HICR_FW_RESET;
506 E1000_WRITE_REG(hw, E1000_HICR, hicr);
508
509 /* Wait till MAC notifies about its readiness after ROM-FW reset */
510 for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
511 icr = E1000_READ_REG(hw, E1000_ICR_V2);
512 if (icr & E1000_ICR_MNG)
513 break;
514 msec_delay(1);
515 }
516
517 /* Check for timeout */
518 if (i == E1000_HI_COMMAND_TIMEOUT) {
519 DEBUGOUT("FW reset failed.\n");
521 }
522
523 /* Wait till MAC is ready to accept new FW code */
524 for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
525 fwsm = E1000_READ_REG(hw, E1000_FWSM);
526 if ((fwsm & E1000_FWSM_FW_VALID) &&
529 break;
530 msec_delay(1);
531 }
532
533 /* Check for timeout */
534 if (i == E1000_HI_COMMAND_TIMEOUT) {
535 DEBUGOUT("FW reset failed.\n");
537 }
538
539 /* Calculate length in DWORDs */
540 length >>= 2;
541
542 /* The device driver writes the relevant FW code block
543 * into the ram area in DWORDs via 1kB ram addressing window.
544 */
545 for (i = 0; i < length; i++) {
547 /* Point to correct 1kB ram window */
551
552 E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
553 }
554
557 *((u32 *)buffer + i));
558 }
559
560 /* Setting this bit tells the ARC that a new FW is ready to execute. */
561 hicr = E1000_READ_REG(hw, E1000_HICR);
563
564 for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
565 hicr = E1000_READ_REG(hw, E1000_HICR);
566 if (!(hicr & E1000_HICR_C))
567 break;
568 msec_delay(1);
569 }
570
571 /* Check for successful FW start. */
572 if (i == E1000_HI_COMMAND_TIMEOUT) {
573 DEBUGOUT("New FW did not start within timeout period.\n");
575 }
576
577 return E1000_SUCCESS;
578}
#define E1000_NVM_INIT_CTRL2_MNGM
Definition: e1000_82571.h:57
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_api.c:1340
#define E1000_ERR_PARAM
#define NVM_INIT_CONTROL2_REG
#define E1000_ICR_MNG
#define E1000_MANC_RCV_TCO_EN
#define E1000_MANC_SMBUS_EN
#define E1000_ERR_INVALID_ARGUMENT
#define E1000_ERR_CONFIG
#define E1000_ERR_HOST_INTERFACE_COMMAND
#define E1000_SUCCESS
#define E1000_MANC_ASF_EN
@ e1000_i210
Definition: e1000_hw.h:274
@ e1000_82574
Definition: e1000_hw.h:255
@ e1000_82583
Definition: e1000_hw.h:256
#define E1000_HI_MAX_MNG_DATA_LENGTH
Definition: e1000_hw.h:710
bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
Definition: e1000_manage.c:132
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer, u16 length)
Definition: e1000_manage.c:298
u8 e1000_calculate_checksum(u8 *buffer, u32 length)
Definition: e1000_manage.c:47
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
Definition: e1000_manage.c:73
s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, u16 length, u16 offset, u8 *sum)
Definition: e1000_manage.c:226
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, struct e1000_host_mng_command_header *hdr)
Definition: e1000_manage.c:192
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
Definition: e1000_manage.c:397
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
Definition: e1000_manage.c:343
bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
Definition: e1000_manage.c:114
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
Definition: e1000_manage.c:471
#define E1000_HI_COMMAND_TIMEOUT
Definition: e1000_manage.h:82
#define E1000_MNG_DHCP_COOKIE_OFFSET
Definition: e1000_manage.h:70
#define E1000_FACTPS_MNGCG
Definition: e1000_manage.h:61
#define E1000_MNG_DHCP_COMMAND_TIMEOUT
Definition: e1000_manage.h:71
#define E1000_HI_FW_MAX_LENGTH
Definition: e1000_manage.h:84
#define E1000_HICR_FW_RESET_ENABLE
Definition: e1000_manage.h:91
#define E1000_FWSM_MODE_SHIFT
Definition: e1000_manage.h:64
#define E1000_FWSM_HI_EN_ONLY_MODE
Definition: e1000_manage.h:66
#define E1000_FWSM_FW_VALID
Definition: e1000_manage.h:65
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING
Definition: e1000_manage.h:73
#define E1000_HICR_C
Definition: e1000_manage.h:89
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD
Definition: e1000_manage.h:72
#define E1000_HI_FW_BLOCK_DWORD_LENGTH
Definition: e1000_manage.h:85
@ e1000_mng_mode_pt
Definition: e1000_manage.h:56
#define E1000_FWSM_MODE_MASK
Definition: e1000_manage.h:63
#define E1000_HICR_SV
Definition: e1000_manage.h:90
#define E1000_HICR_MEMORY_BASE_EN
Definition: e1000_manage.h:86
#define E1000_IAMT_SIGNATURE
Definition: e1000_manage.h:95
#define E1000_MNG_DHCP_COOKIE_LENGTH
Definition: e1000_manage.h:69
#define E1000_HI_FW_BASE_ADDRESS
Definition: e1000_manage.h:83
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH
Definition: e1000_manage.h:80
#define E1000_MNG_IAMT_MODE
Definition: e1000_manage.h:68
#define E1000_HICR_FW_RESET
Definition: e1000_manage.h:92
#define E1000_HICR_EN
Definition: e1000_manage.h:87
#define msec_delay(x)
Definition: e1000_osdep.h:103
uint8_t u8
Definition: e1000_osdep.h:124
#define E1000_READ_REG_ARRAY_DWORD
Definition: e1000_osdep.h:211
#define DEBUGFUNC(F)
Definition: e1000_osdep.h:115
#define E1000_WRITE_REG_ARRAY_DWORD
Definition: e1000_osdep.h:212
#define E1000_WRITE_FLUSH(a)
Definition: e1000_osdep.h:177
#define E1000_WRITE_REG(hw, reg, value)
Definition: e1000_osdep.h:196
uint16_t u16
Definition: e1000_osdep.h:123
#define DEBUGOUT(...)
Definition: e1000_osdep.h:109
#define msec_delay_irq(x)
Definition: e1000_osdep.h:104
#define E1000_READ_REG(hw, reg)
Definition: e1000_osdep.h:191
int32_t s32
Definition: e1000_osdep.h:126
uint32_t u32
Definition: e1000_osdep.h:122
#define E1000_ICR_V2
Definition: e1000_regs.h:144
#define E1000_MANC
Definition: e1000_regs.h:509
#define E1000_HICR
Definition: e1000_regs.h:552
#define E1000_HOST_IF
Definition: e1000_regs.h:518
#define E1000_FWSM
Definition: e1000_regs.h:545
#define E1000_HIBBA
Definition: e1000_regs.h:519
#define E1000_FACTPS
Definition: e1000_regs.h:543
struct e1000_mac_info mac
Definition: e1000_hw.h:1028
struct e1000_host_mng_dhcp_cookie mng_cookie
Definition: e1000_hw.h:1034
enum e1000_mac_type type
Definition: e1000_hw.h:815
bool arc_subsystem_valid
Definition: e1000_hw.h:842
bool asf_firmware_present
Definition: e1000_hw.h:843
struct e1000_mac_operations ops
Definition: e1000_hw.h:811
bool tx_pkt_filtering
Definition: e1000_hw.h:851
bool(* check_mng_mode)(struct e1000_hw *)
Definition: e1000_hw.h:727