fm10k_common.c 15 KB

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