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