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