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