root/drivers/net/ethernet/intel/fm10k/fm10k_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fm10k_get_bus_info_generic
  2. fm10k_get_pcie_msix_count_generic
  3. fm10k_get_invariants_generic
  4. fm10k_start_hw_generic
  5. fm10k_disable_queues_generic
  6. fm10k_stop_hw_generic
  7. fm10k_read_hw_stats_32b
  8. fm10k_read_hw_stats_48b
  9. fm10k_update_hw_base_48b
  10. fm10k_update_hw_stats_tx_q
  11. fm10k_update_hw_stats_rx_q
  12. fm10k_update_hw_stats_q
  13. fm10k_unbind_hw_stats_q
  14. fm10k_get_host_state_generic

   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  **/
  13 s32 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 
 128 static 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  **/
 151 s32 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  **/
 171 s32 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  **/
 185 s32 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  **/
 239 s32 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  *  **/
 253 u32 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  *  **/
 275 static 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  **/
 306 static 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  **/
 328 static 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  **/
 379 static 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  **/
 436 void 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  **/
 456 void 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  **/
 474 s32 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 
 521 out:
 522         *host_ready = !mac->get_host_state;
 523         return ret_val;
 524 }

/* [<][>][^][v][top][bottom][index][help] */