The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/e1000/e1000_manage.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
   39 /**
   40  *  e1000_calculate_checksum - Calculate checksum for buffer
   41  *  @buffer: pointer to EEPROM
   42  *  @length: size of EEPROM to calculate a checksum for
   43  *
   44  *  Calculates the checksum for some buffer on a specified length.  The
   45  *  checksum calculated is returned.
   46  **/
   47 u8 e1000_calculate_checksum(u8 *buffer, u32 length)
   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 
   63 /**
   64  *  e1000_mng_enable_host_if_generic - Checks host interface is enabled
   65  *  @hw: pointer to the HW structure
   66  *
   67  *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
   68  *
   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)
   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");
   82                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
   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");
   89                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
   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;
   96                 msec_delay_irq(1);
   97         }
   98 
   99         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
  100                 DEBUGOUT("Previous command timeout failed .\n");
  101                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  102         }
  103 
  104         return E1000_SUCCESS;
  105 }
  106 
  107 /**
  108  *  e1000_check_mng_mode_generic - Generic check management mode
  109  *  @hw: pointer to the HW structure
  110  *
  111  *  Reads the firmware semaphore register and returns true (>0) if
  112  *  manageability is enabled, else false (0).
  113  **/
  114 bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
  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) ==
  122                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
  123 }
  124 
  125 /**
  126  *  e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
  127  *  @hw: pointer to the HW structure
  128  *
  129  *  Enables packet filtering on transmit packets if manageability is enabled
  130  *  and host interface is enabled.
  131  **/
  132 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
  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          */
  153         ret_val = e1000_mng_enable_host_if_generic(hw);
  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. */
  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);
  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. */
  179         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
  180                 hw->mac.tx_pkt_filtering = false;
  181 
  182         return hw->mac.tx_pkt_filtering;
  183 }
  184 
  185 /**
  186  *  e1000_mng_write_cmd_header_generic - Writes manageability command header
  187  *  @hw: pointer to the HW structure
  188  *  @hdr: pointer to the host interface command header
  189  *
  190  *  Writes the command header after does the checksum calculation.
  191  **/
  192 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
  193                                       struct e1000_host_mng_command_header *hdr)
  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++) {
  206                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
  207                                             *((u32 *) hdr + i));
  208                 E1000_WRITE_FLUSH(hw);
  209         }
  210 
  211         return E1000_SUCCESS;
  212 }
  213 
  214 /**
  215  *  e1000_mng_host_if_write_generic - Write to the manageability host interface
  216  *  @hw: pointer to the HW structure
  217  *  @buffer: pointer to the host interface buffer
  218  *  @length: size of the buffer
  219  *  @offset: location in the buffer to write to
  220  *  @sum: sum of the data (not checksum)
  221  *
  222  *  This function writes the buffer content at the offset given on the host if.
  223  *  It also does alignment considerations to do the writes in most efficient
  224  *  way.  Also fills up the sum of the buffer in *buffer parameter.
  225  **/
  226 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
  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                 }
  251                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
  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 
  271                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
  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                 }
  283                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
  284                                             data);
  285         }
  286 
  287         return E1000_SUCCESS;
  288 }
  289 
  290 /**
  291  *  e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
  292  *  @hw: pointer to the HW structure
  293  *  @buffer: pointer to the host interface
  294  *  @length: size of the buffer
  295  *
  296  *  Writes the DHCP information to the host interface.
  297  **/
  298 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
  299                                       u16 length)
  300 {
  301         struct e1000_host_mng_command_header hdr;
  302         s32 ret_val;
  303         u32 hicr;
  304 
  305         DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
  306 
  307         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
  308         hdr.command_length = length;
  309         hdr.reserved1 = 0;
  310         hdr.reserved2 = 0;
  311         hdr.checksum = 0;
  312 
  313         /* Enable the host interface */
  314         ret_val = e1000_mng_enable_host_if_generic(hw);
  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);
  331         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
  332 
  333         return E1000_SUCCESS;
  334 }
  335 
  336 /**
  337  *  e1000_enable_mng_pass_thru - Check if management passthrough is needed
  338  *  @hw: pointer to the HW structure
  339  *
  340  *  Verifies the hardware needs to leave interface enabled so that frames can
  341  *  be directed to and from the management interface.
  342  **/
  343 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
  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) ==
  364                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
  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 
  388 /**
  389  *  e1000_host_interface_command - Writes buffer to host interface
  390  *  @hw: pointer to the HW structure
  391  *  @buffer: contains a command to write
  392  *  @length: the byte length of the buffer, must be multiple of 4 bytes
  393  *
  394  *  Writes a buffer to the Host Interface.  Upon success, returns E1000_SUCCESS
  395  *  else returns E1000_ERR_HOST_INTERFACE_COMMAND.
  396  **/
  397 s32 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 ||
  414             length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
  415                 DEBUGOUT("Buffer length failure.\n");
  416                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  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");
  423                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  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++)
  433                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
  434                                             *((u32 *)buffer + i));
  435 
  436         /* Setting this bit tells the ARC that a new command is pending. */
  437         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
  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 ||
  448             (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
  449                 DEBUGOUT("Command has failed with no status valid.\n");
  450                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  451         }
  452 
  453         for (i = 0; i < length; i++)
  454                 *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
  455                                                                   E1000_HOST_IF,
  456                                                                   i);
  457 
  458         return E1000_SUCCESS;
  459 }
  460 
  461 /**
  462  *  e1000_load_firmware - Writes proxy FW code buffer to host interface
  463  *                        and execute.
  464  *  @hw: pointer to the HW structure
  465  *  @buffer: contains a firmware to write
  466  *  @length: the byte length of the buffer, must be multiple of 4 bytes
  467  *
  468  *  Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
  469  *  in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
  470  **/
  471 s32 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");
  495                 return -E1000_ERR_INVALID_ARGUMENT;
  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);
  503         hicr |= E1000_HICR_FW_RESET_ENABLE;
  504         E1000_WRITE_REG(hw, E1000_HICR, hicr);
  505         hicr |= E1000_HICR_FW_RESET;
  506         E1000_WRITE_REG(hw, E1000_HICR, hicr);
  507         E1000_WRITE_FLUSH(hw);
  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");
  520                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  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) &&
  527                     ((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
  528                     E1000_FWSM_HI_EN_ONLY_MODE))
  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");
  536                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  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++) {
  546                 if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
  547                         /* Point to correct 1kB ram window */
  548                         hibba = E1000_HI_FW_BASE_ADDRESS +
  549                                 ((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
  550                                 (i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
  551 
  552                         E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
  553                 }
  554 
  555                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
  556                                             i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
  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);
  562         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
  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");
  574                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
  575         }
  576 
  577         return E1000_SUCCESS;
  578 }

Cache object: 6cf9acbe2eae50c423d196efe1723f1a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.