linux/drivers/net/ethernet/intel/fm10k/fm10k_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Intel(R) Ethernet Switch Host Interface Driver
   3 * Copyright(c) 2013 - 2018 Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * The full GNU General Public License is included in this distribution in
  15 * the file called "COPYING".
  16 *
  17 * Contact Information:
  18 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  19 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  20 */
  21
  22#include "fm10k_common.h"
  23
  24/**
  25 *  fm10k_get_bus_info_generic - Generic set PCI bus info
  26 *  @hw: pointer to hardware structure
  27 *
  28 *  Gets the PCI bus info (speed, width, type) then calls helper function to
  29 *  store this data within the fm10k_hw structure.
  30 **/
  31s32 fm10k_get_bus_info_generic(struct fm10k_hw *hw)
  32{
  33        u16 link_cap, link_status, device_cap, device_control;
  34
  35        /* Get the maximum link width and speed from PCIe config space */
  36        link_cap = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_LINK_CAP);
  37
  38        switch (link_cap & FM10K_PCIE_LINK_WIDTH) {
  39        case FM10K_PCIE_LINK_WIDTH_1:
  40                hw->bus_caps.width = fm10k_bus_width_pcie_x1;
  41                break;
  42        case FM10K_PCIE_LINK_WIDTH_2:
  43                hw->bus_caps.width = fm10k_bus_width_pcie_x2;
  44                break;
  45        case FM10K_PCIE_LINK_WIDTH_4:
  46                hw->bus_caps.width = fm10k_bus_width_pcie_x4;
  47                break;
  48        case FM10K_PCIE_LINK_WIDTH_8:
  49                hw->bus_caps.width = fm10k_bus_width_pcie_x8;
  50                break;
  51        default:
  52                hw->bus_caps.width = fm10k_bus_width_unknown;
  53                break;
  54        }
  55
  56        switch (link_cap & FM10K_PCIE_LINK_SPEED) {
  57        case FM10K_PCIE_LINK_SPEED_2500:
  58                hw->bus_caps.speed = fm10k_bus_speed_2500;
  59                break;
  60        case FM10K_PCIE_LINK_SPEED_5000:
  61                hw->bus_caps.speed = fm10k_bus_speed_5000;
  62                break;
  63        case FM10K_PCIE_LINK_SPEED_8000:
  64                hw->bus_caps.speed = fm10k_bus_speed_8000;
  65                break;
  66        default:
  67                hw->bus_caps.speed = fm10k_bus_speed_unknown;
  68                break;
  69        }
  70
  71        /* Get the PCIe maximum payload size for the PCIe function */
  72        device_cap = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_DEV_CAP);
  73
  74        switch (device_cap & FM10K_PCIE_DEV_CAP_PAYLOAD) {
  75        case FM10K_PCIE_DEV_CAP_PAYLOAD_128:
  76                hw->bus_caps.payload = fm10k_bus_payload_128;
  77                break;
  78        case FM10K_PCIE_DEV_CAP_PAYLOAD_256:
  79                hw->bus_caps.payload = fm10k_bus_payload_256;
  80                break;
  81        case FM10K_PCIE_DEV_CAP_PAYLOAD_512:
  82                hw->bus_caps.payload = fm10k_bus_payload_512;
  83                break;
  84        default:
  85                hw->bus_caps.payload = fm10k_bus_payload_unknown;
  86                break;
  87        }
  88
  89        /* Get the negotiated link width and speed from PCIe config space */
  90        link_status = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_LINK_STATUS);
  91
  92        switch (link_status & FM10K_PCIE_LINK_WIDTH) {
  93        case FM10K_PCIE_LINK_WIDTH_1:
  94                hw->bus.width = fm10k_bus_width_pcie_x1;
  95                break;
  96        case FM10K_PCIE_LINK_WIDTH_2:
  97                hw->bus.width = fm10k_bus_width_pcie_x2;
  98                break;
  99        case FM10K_PCIE_LINK_WIDTH_4:
 100                hw->bus.width = fm10k_bus_width_pcie_x4;
 101                break;
 102        case FM10K_PCIE_LINK_WIDTH_8:
 103                hw->bus.width = fm10k_bus_width_pcie_x8;
 104                break;
 105        default:
 106                hw->bus.width = fm10k_bus_width_unknown;
 107                break;
 108        }
 109
 110        switch (link_status & FM10K_PCIE_LINK_SPEED) {
 111        case FM10K_PCIE_LINK_SPEED_2500:
 112                hw->bus.speed = fm10k_bus_speed_2500;
 113                break;
 114        case FM10K_PCIE_LINK_SPEED_5000:
 115                hw->bus.speed = fm10k_bus_speed_5000;
 116                break;
 117        case FM10K_PCIE_LINK_SPEED_8000:
 118                hw->bus.speed = fm10k_bus_speed_8000;
 119                break;
 120        default:
 121                hw->bus.speed = fm10k_bus_speed_unknown;
 122                break;
 123        }
 124
 125        /* Get the negotiated PCIe maximum payload size for the PCIe function */
 126        device_control = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_DEV_CTRL);
 127
 128        switch (device_control & FM10K_PCIE_DEV_CTRL_PAYLOAD) {
 129        case FM10K_PCIE_DEV_CTRL_PAYLOAD_128:
 130                hw->bus.payload = fm10k_bus_payload_128;
 131                break;
 132        case FM10K_PCIE_DEV_CTRL_PAYLOAD_256:
 133                hw->bus.payload = fm10k_bus_payload_256;
 134                break;
 135        case FM10K_PCIE_DEV_CTRL_PAYLOAD_512:
 136                hw->bus.payload = fm10k_bus_payload_512;
 137                break;
 138        default:
 139                hw->bus.payload = fm10k_bus_payload_unknown;
 140                break;
 141        }
 142
 143        return 0;
 144}
 145
 146static u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw)
 147{
 148        u16 msix_count;
 149
 150        /* read in value from MSI-X capability register */
 151        msix_count = fm10k_read_pci_cfg_word(hw, FM10K_PCI_MSIX_MSG_CTRL);
 152        msix_count &= FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK;
 153
 154        /* MSI-X count is zero-based in HW */
 155        msix_count++;
 156
 157        if (msix_count > FM10K_MAX_MSIX_VECTORS)
 158                msix_count = FM10K_MAX_MSIX_VECTORS;
 159
 160        return msix_count;
 161}
 162
 163/**
 164 *  fm10k_get_invariants_generic - Inits constant values
 165 *  @hw: pointer to the hardware structure
 166 *
 167 *  Initialize the common invariants for the device.
 168 **/
 169s32 fm10k_get_invariants_generic(struct fm10k_hw *hw)
 170{
 171        struct fm10k_mac_info *mac = &hw->mac;
 172
 173        /* initialize GLORT state to avoid any false hits */
 174        mac->dglort_map = FM10K_DGLORTMAP_NONE;
 175
 176        /* record maximum number of MSI-X vectors */
 177        mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);
 178
 179        return 0;
 180}
 181
 182/**
 183 *  fm10k_start_hw_generic - Prepare hardware for Tx/Rx
 184 *  @hw: pointer to hardware structure
 185 *
 186 *  This function sets the Tx ready flag to indicate that the Tx path has
 187 *  been initialized.
 188 **/
 189s32 fm10k_start_hw_generic(struct fm10k_hw *hw)
 190{
 191        /* set flag indicating we are beginning Tx */
 192        hw->mac.tx_ready = true;
 193
 194        return 0;
 195}
 196
 197/**
 198 *  fm10k_disable_queues_generic - Stop Tx/Rx queues
 199 *  @hw: pointer to hardware structure
 200 *  @q_cnt: number of queues to be disabled
 201 *
 202 **/
 203s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)
 204{
 205        u32 reg;
 206        u16 i, time;
 207
 208        /* clear tx_ready to prevent any false hits for reset */
 209        hw->mac.tx_ready = false;
 210
 211        if (FM10K_REMOVED(hw->hw_addr))
 212                return 0;
 213
 214        /* clear the enable bit for all rings */
 215        for (i = 0; i < q_cnt; i++) {
 216                reg = fm10k_read_reg(hw, FM10K_TXDCTL(i));
 217                fm10k_write_reg(hw, FM10K_TXDCTL(i),
 218                                reg & ~FM10K_TXDCTL_ENABLE);
 219                reg = fm10k_read_reg(hw, FM10K_RXQCTL(i));
 220                fm10k_write_reg(hw, FM10K_RXQCTL(i),
 221                                reg & ~FM10K_RXQCTL_ENABLE);
 222        }
 223
 224        fm10k_write_flush(hw);
 225        udelay(1);
 226
 227        /* loop through all queues to verify that they are all disabled */
 228        for (i = 0, time = FM10K_QUEUE_DISABLE_TIMEOUT; time;) {
 229                /* if we are at end of rings all rings are disabled */
 230                if (i == q_cnt)
 231                        return 0;
 232
 233                /* if queue enables cleared, then move to next ring pair */
 234                reg = fm10k_read_reg(hw, FM10K_TXDCTL(i));
 235                if (!~reg || !(reg & FM10K_TXDCTL_ENABLE)) {
 236                        reg = fm10k_read_reg(hw, FM10K_RXQCTL(i));
 237                        if (!~reg || !(reg & FM10K_RXQCTL_ENABLE)) {
 238                                i++;
 239                                continue;
 240                        }
 241                }
 242
 243                /* decrement time and wait 1 usec */
 244                time--;
 245                if (time)
 246                        udelay(1);
 247        }
 248
 249        return FM10K_ERR_REQUESTS_PENDING;
 250}
 251
 252/**
 253 *  fm10k_stop_hw_generic - Stop Tx/Rx units
 254 *  @hw: pointer to hardware structure
 255 *
 256 **/
 257s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)
 258{
 259        return fm10k_disable_queues_generic(hw, hw->mac.max_queues);
 260}
 261
 262/**
 263 *  fm10k_read_hw_stats_32b - Reads value of 32-bit registers
 264 *  @hw: pointer to the hardware structure
 265 *  @addr: address of register containing a 32-bit value
 266 *  @stat: pointer to structure holding hw stat information
 267 *
 268 *  Function reads the content of the register and returns the delta
 269 *  between the base and the current value.
 270 *  **/
 271u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,
 272                            struct fm10k_hw_stat *stat)
 273{
 274        u32 delta = fm10k_read_reg(hw, addr) - stat->base_l;
 275
 276        if (FM10K_REMOVED(hw->hw_addr))
 277                stat->base_h = 0;
 278
 279        return delta;
 280}
 281
 282/**
 283 *  fm10k_read_hw_stats_48b - Reads value of 48-bit registers
 284 *  @hw: pointer to the hardware structure
 285 *  @addr: address of register containing the lower 32-bit value
 286 *  @stat: pointer to structure holding hw stat information
 287 *
 288 *  Function reads the content of 2 registers, combined to represent a 48-bit
 289 *  statistical value. Extra processing is required to handle overflowing.
 290 *  Finally, a delta value is returned representing the difference between the
 291 *  values stored in registers and values stored in the statistic counters.
 292 *  **/
 293static u64 fm10k_read_hw_stats_48b(struct fm10k_hw *hw, u32 addr,
 294                                   struct fm10k_hw_stat *stat)
 295{
 296        u32 count_l;
 297        u32 count_h;
 298        u32 count_tmp;
 299        u64 delta;
 300
 301        count_h = fm10k_read_reg(hw, addr + 1);
 302
 303        /* Check for overflow */
 304        do {
 305                count_tmp = count_h;
 306                count_l = fm10k_read_reg(hw, addr);
 307                count_h = fm10k_read_reg(hw, addr + 1);
 308        } while (count_h != count_tmp);
 309
 310        delta = ((u64)(count_h - stat->base_h) << 32) + count_l;
 311        delta -= stat->base_l;
 312
 313        return delta & FM10K_48_BIT_MASK;
 314}
 315
 316/**
 317 *  fm10k_update_hw_base_48b - Updates 48-bit statistic base value
 318 *  @stat: pointer to the hardware statistic structure
 319 *  @delta: value to be updated into the hardware statistic structure
 320 *
 321 *  Function receives a value and determines if an update is required based on
 322 *  a delta calculation. Only the base value will be updated.
 323 **/
 324static void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)
 325{
 326        if (!delta)
 327                return;
 328
 329        /* update lower 32 bits */
 330        delta += stat->base_l;
 331        stat->base_l = (u32)delta;
 332
 333        /* update upper 32 bits */
 334        stat->base_h += (u32)(delta >> 32);
 335}
 336
 337/**
 338 *  fm10k_update_hw_stats_tx_q - Updates TX queue statistics counters
 339 *  @hw: pointer to the hardware structure
 340 *  @q: pointer to the ring of hardware statistics queue
 341 *  @idx: index pointing to the start of the ring iteration
 342 *
 343 *  Function updates the TX queue statistics counters that are related to the
 344 *  hardware.
 345 **/
 346static void fm10k_update_hw_stats_tx_q(struct fm10k_hw *hw,
 347                                       struct fm10k_hw_stats_q *q,
 348                                       u32 idx)
 349{
 350        u32 id_tx, id_tx_prev, tx_packets;
 351        u64 tx_bytes = 0;
 352
 353        /* Retrieve TX Owner Data */
 354        id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
 355
 356        /* Process TX Ring */
 357        do {
 358                tx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPTC(idx),
 359                                                     &q->tx_packets);
 360
 361                if (tx_packets)
 362                        tx_bytes = fm10k_read_hw_stats_48b(hw,
 363                                                           FM10K_QBTC_L(idx),
 364                                                           &q->tx_bytes);
 365
 366                /* Re-Check Owner Data */
 367                id_tx_prev = id_tx;
 368                id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
 369        } while ((id_tx ^ id_tx_prev) & FM10K_TXQCTL_ID_MASK);
 370
 371        /* drop non-ID bits and set VALID ID bit */
 372        id_tx &= FM10K_TXQCTL_ID_MASK;
 373        id_tx |= FM10K_STAT_VALID;
 374
 375        /* update packet counts */
 376        if (q->tx_stats_idx == id_tx) {
 377                q->tx_packets.count += tx_packets;
 378                q->tx_bytes.count += tx_bytes;
 379        }
 380
 381        /* update bases and record ID */
 382        fm10k_update_hw_base_32b(&q->tx_packets, tx_packets);
 383        fm10k_update_hw_base_48b(&q->tx_bytes, tx_bytes);
 384
 385        q->tx_stats_idx = id_tx;
 386}
 387
 388/**
 389 *  fm10k_update_hw_stats_rx_q - Updates RX queue statistics counters
 390 *  @hw: pointer to the hardware structure
 391 *  @q: pointer to the ring of hardware statistics queue
 392 *  @idx: index pointing to the start of the ring iteration
 393 *
 394 *  Function updates the RX queue statistics counters that are related to the
 395 *  hardware.
 396 **/
 397static void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw,
 398                                       struct fm10k_hw_stats_q *q,
 399                                       u32 idx)
 400{
 401        u32 id_rx, id_rx_prev, rx_packets, rx_drops;
 402        u64 rx_bytes = 0;
 403
 404        /* Retrieve RX Owner Data */
 405        id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
 406
 407        /* Process RX Ring */
 408        do {
 409                rx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx),
 410                                                   &q->rx_drops);
 411
 412                rx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPRC(idx),
 413                                                     &q->rx_packets);
 414
 415                if (rx_packets)
 416                        rx_bytes = fm10k_read_hw_stats_48b(hw,
 417                                                           FM10K_QBRC_L(idx),
 418                                                           &q->rx_bytes);
 419
 420                /* Re-Check Owner Data */
 421                id_rx_prev = id_rx;
 422                id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
 423        } while ((id_rx ^ id_rx_prev) & FM10K_RXQCTL_ID_MASK);
 424
 425        /* drop non-ID bits and set VALID ID bit */
 426        id_rx &= FM10K_RXQCTL_ID_MASK;
 427        id_rx |= FM10K_STAT_VALID;
 428
 429        /* update packet counts */
 430        if (q->rx_stats_idx == id_rx) {
 431                q->rx_drops.count += rx_drops;
 432                q->rx_packets.count += rx_packets;
 433                q->rx_bytes.count += rx_bytes;
 434        }
 435
 436        /* update bases and record ID */
 437        fm10k_update_hw_base_32b(&q->rx_drops, rx_drops);
 438        fm10k_update_hw_base_32b(&q->rx_packets, rx_packets);
 439        fm10k_update_hw_base_48b(&q->rx_bytes, rx_bytes);
 440
 441        q->rx_stats_idx = id_rx;
 442}
 443
 444/**
 445 *  fm10k_update_hw_stats_q - Updates queue statistics counters
 446 *  @hw: pointer to the hardware structure
 447 *  @q: pointer to the ring of hardware statistics queue
 448 *  @idx: index pointing to the start of the ring iteration
 449 *  @count: number of queues to iterate over
 450 *
 451 *  Function updates the queue statistics counters that are related to the
 452 *  hardware.
 453 **/
 454void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,
 455                             u32 idx, u32 count)
 456{
 457        u32 i;
 458
 459        for (i = 0; i < count; i++, idx++, q++) {
 460                fm10k_update_hw_stats_tx_q(hw, q, idx);
 461                fm10k_update_hw_stats_rx_q(hw, q, idx);
 462        }
 463}
 464
 465/**
 466 *  fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues
 467 *  @q: pointer to the ring of hardware statistics queue
 468 *  @idx: index pointing to the start of the ring iteration
 469 *  @count: number of queues to iterate over
 470 *
 471 *  Function invalidates the index values for the queues so any updates that
 472 *  may have happened are ignored and the base for the queue stats is reset.
 473 **/
 474void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count)
 475{
 476        u32 i;
 477
 478        for (i = 0; i < count; i++, idx++, q++) {
 479                q->rx_stats_idx = 0;
 480                q->tx_stats_idx = 0;
 481        }
 482}
 483
 484/**
 485 *  fm10k_get_host_state_generic - Returns the state of the host
 486 *  @hw: pointer to hardware structure
 487 *  @host_ready: pointer to boolean value that will record host state
 488 *
 489 *  This function will check the health of the mailbox and Tx queue 0
 490 *  in order to determine if we should report that the link is up or not.
 491 **/
 492s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
 493{
 494        struct fm10k_mbx_info *mbx = &hw->mbx;
 495        struct fm10k_mac_info *mac = &hw->mac;
 496        s32 ret_val = 0;
 497        u32 txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(0));
 498
 499        /* process upstream mailbox in case interrupts were disabled */
 500        mbx->ops.process(hw, mbx);
 501
 502        /* If Tx is no longer enabled link should come down */
 503        if (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))
 504                mac->get_host_state = true;
 505
 506        /* exit if not checking for link, or link cannot be changed */
 507        if (!mac->get_host_state || !(~txdctl))
 508                goto out;
 509
 510        /* if we somehow dropped the Tx enable we should reset */
 511        if (mac->tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {
 512                ret_val = FM10K_ERR_RESET_REQUESTED;
 513                goto out;
 514        }
 515
 516        /* if Mailbox timed out we should request reset */
 517        if (!mbx->timeout) {
 518                ret_val = FM10K_ERR_RESET_REQUESTED;
 519                goto out;
 520        }
 521
 522        /* verify Mailbox is still open */
 523        if (mbx->state != FM10K_STATE_OPEN)
 524                goto out;
 525
 526        /* interface cannot receive traffic without logical ports */
 527        if (mac->dglort_map == FM10K_DGLORTMAP_NONE) {
 528                if (mac->ops.request_lport_map)
 529                        ret_val = mac->ops.request_lport_map(hw);
 530
 531                goto out;
 532        }
 533
 534        /* if we passed all the tests above then the switch is ready and we no
 535         * longer need to check for link
 536         */
 537        mac->get_host_state = false;
 538
 539out:
 540        *host_ready = !mac->get_host_state;
 541        return ret_val;
 542}
 543