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