ixgbe_mbx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 1999 - 2018 Intel Corporation. */
  3. #include <linux/pci.h>
  4. #include <linux/delay.h>
  5. #include "ixgbe.h"
  6. #include "ixgbe_mbx.h"
  7. /**
  8. * ixgbe_read_mbx - Reads a message from the mailbox
  9. * @hw: pointer to the HW structure
  10. * @msg: The message buffer
  11. * @size: Length of buffer
  12. * @mbx_id: id of mailbox to read
  13. *
  14. * returns SUCCESS if it successfully read message from buffer
  15. **/
  16. s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  17. {
  18. struct ixgbe_mbx_info *mbx = &hw->mbx;
  19. /* limit read to size of mailbox */
  20. if (size > mbx->size)
  21. size = mbx->size;
  22. if (!mbx->ops)
  23. return IXGBE_ERR_MBX;
  24. return mbx->ops->read(hw, msg, size, mbx_id);
  25. }
  26. /**
  27. * ixgbe_write_mbx - Write a message to the mailbox
  28. * @hw: pointer to the HW structure
  29. * @msg: The message buffer
  30. * @size: Length of buffer
  31. * @mbx_id: id of mailbox to write
  32. *
  33. * returns SUCCESS if it successfully copied message into the buffer
  34. **/
  35. s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  36. {
  37. struct ixgbe_mbx_info *mbx = &hw->mbx;
  38. if (size > mbx->size)
  39. return IXGBE_ERR_MBX;
  40. if (!mbx->ops)
  41. return IXGBE_ERR_MBX;
  42. return mbx->ops->write(hw, msg, size, mbx_id);
  43. }
  44. /**
  45. * ixgbe_check_for_msg - checks to see if someone sent us mail
  46. * @hw: pointer to the HW structure
  47. * @mbx_id: id of mailbox to check
  48. *
  49. * returns SUCCESS if the Status bit was found or else ERR_MBX
  50. **/
  51. s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
  52. {
  53. struct ixgbe_mbx_info *mbx = &hw->mbx;
  54. if (!mbx->ops)
  55. return IXGBE_ERR_MBX;
  56. return mbx->ops->check_for_msg(hw, mbx_id);
  57. }
  58. /**
  59. * ixgbe_check_for_ack - checks to see if someone sent us ACK
  60. * @hw: pointer to the HW structure
  61. * @mbx_id: id of mailbox to check
  62. *
  63. * returns SUCCESS if the Status bit was found or else ERR_MBX
  64. **/
  65. s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
  66. {
  67. struct ixgbe_mbx_info *mbx = &hw->mbx;
  68. if (!mbx->ops)
  69. return IXGBE_ERR_MBX;
  70. return mbx->ops->check_for_ack(hw, mbx_id);
  71. }
  72. /**
  73. * ixgbe_check_for_rst - checks to see if other side has reset
  74. * @hw: pointer to the HW structure
  75. * @mbx_id: id of mailbox to check
  76. *
  77. * returns SUCCESS if the Status bit was found or else ERR_MBX
  78. **/
  79. s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
  80. {
  81. struct ixgbe_mbx_info *mbx = &hw->mbx;
  82. if (!mbx->ops)
  83. return IXGBE_ERR_MBX;
  84. return mbx->ops->check_for_rst(hw, mbx_id);
  85. }
  86. /**
  87. * ixgbe_poll_for_msg - Wait for message notification
  88. * @hw: pointer to the HW structure
  89. * @mbx_id: id of mailbox to write
  90. *
  91. * returns SUCCESS if it successfully received a message notification
  92. **/
  93. static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
  94. {
  95. struct ixgbe_mbx_info *mbx = &hw->mbx;
  96. int countdown = mbx->timeout;
  97. if (!countdown || !mbx->ops)
  98. return IXGBE_ERR_MBX;
  99. while (mbx->ops->check_for_msg(hw, mbx_id)) {
  100. countdown--;
  101. if (!countdown)
  102. return IXGBE_ERR_MBX;
  103. udelay(mbx->usec_delay);
  104. }
  105. return 0;
  106. }
  107. /**
  108. * ixgbe_poll_for_ack - Wait for message acknowledgement
  109. * @hw: pointer to the HW structure
  110. * @mbx_id: id of mailbox to write
  111. *
  112. * returns SUCCESS if it successfully received a message acknowledgement
  113. **/
  114. static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
  115. {
  116. struct ixgbe_mbx_info *mbx = &hw->mbx;
  117. int countdown = mbx->timeout;
  118. if (!countdown || !mbx->ops)
  119. return IXGBE_ERR_MBX;
  120. while (mbx->ops->check_for_ack(hw, mbx_id)) {
  121. countdown--;
  122. if (!countdown)
  123. return IXGBE_ERR_MBX;
  124. udelay(mbx->usec_delay);
  125. }
  126. return 0;
  127. }
  128. /**
  129. * ixgbe_read_posted_mbx - Wait for message notification and receive message
  130. * @hw: pointer to the HW structure
  131. * @msg: The message buffer
  132. * @size: Length of buffer
  133. * @mbx_id: id of mailbox to write
  134. *
  135. * returns SUCCESS if it successfully received a message notification and
  136. * copied it into the receive buffer.
  137. **/
  138. static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
  139. u16 mbx_id)
  140. {
  141. struct ixgbe_mbx_info *mbx = &hw->mbx;
  142. s32 ret_val;
  143. if (!mbx->ops)
  144. return IXGBE_ERR_MBX;
  145. ret_val = ixgbe_poll_for_msg(hw, mbx_id);
  146. if (ret_val)
  147. return ret_val;
  148. /* if ack received read message */
  149. return mbx->ops->read(hw, msg, size, mbx_id);
  150. }
  151. /**
  152. * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
  153. * @hw: pointer to the HW structure
  154. * @msg: The message buffer
  155. * @size: Length of buffer
  156. * @mbx_id: id of mailbox to write
  157. *
  158. * returns SUCCESS if it successfully copied message into the buffer and
  159. * received an ack to that message within delay * timeout period
  160. **/
  161. static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
  162. u16 mbx_id)
  163. {
  164. struct ixgbe_mbx_info *mbx = &hw->mbx;
  165. s32 ret_val;
  166. /* exit if either we can't write or there isn't a defined timeout */
  167. if (!mbx->ops || !mbx->timeout)
  168. return IXGBE_ERR_MBX;
  169. /* send msg */
  170. ret_val = mbx->ops->write(hw, msg, size, mbx_id);
  171. if (ret_val)
  172. return ret_val;
  173. /* if msg sent wait until we receive an ack */
  174. return ixgbe_poll_for_ack(hw, mbx_id);
  175. }
  176. static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
  177. {
  178. u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
  179. if (mbvficr & mask) {
  180. IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
  181. return 0;
  182. }
  183. return IXGBE_ERR_MBX;
  184. }
  185. /**
  186. * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
  187. * @hw: pointer to the HW structure
  188. * @vf_number: the VF index
  189. *
  190. * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  191. **/
  192. static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
  193. {
  194. s32 index = IXGBE_MBVFICR_INDEX(vf_number);
  195. u32 vf_bit = vf_number % 16;
  196. if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
  197. index)) {
  198. hw->mbx.stats.reqs++;
  199. return 0;
  200. }
  201. return IXGBE_ERR_MBX;
  202. }
  203. /**
  204. * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
  205. * @hw: pointer to the HW structure
  206. * @vf_number: the VF index
  207. *
  208. * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  209. **/
  210. static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
  211. {
  212. s32 index = IXGBE_MBVFICR_INDEX(vf_number);
  213. u32 vf_bit = vf_number % 16;
  214. if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
  215. index)) {
  216. hw->mbx.stats.acks++;
  217. return 0;
  218. }
  219. return IXGBE_ERR_MBX;
  220. }
  221. /**
  222. * ixgbe_check_for_rst_pf - checks to see if the VF has reset
  223. * @hw: pointer to the HW structure
  224. * @vf_number: the VF index
  225. *
  226. * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  227. **/
  228. static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
  229. {
  230. u32 reg_offset = (vf_number < 32) ? 0 : 1;
  231. u32 vf_shift = vf_number % 32;
  232. u32 vflre = 0;
  233. switch (hw->mac.type) {
  234. case ixgbe_mac_82599EB:
  235. vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
  236. break;
  237. case ixgbe_mac_X540:
  238. case ixgbe_mac_X550:
  239. case ixgbe_mac_X550EM_x:
  240. case ixgbe_mac_x550em_a:
  241. vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
  242. break;
  243. default:
  244. break;
  245. }
  246. if (vflre & BIT(vf_shift)) {
  247. IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), BIT(vf_shift));
  248. hw->mbx.stats.rsts++;
  249. return 0;
  250. }
  251. return IXGBE_ERR_MBX;
  252. }
  253. /**
  254. * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
  255. * @hw: pointer to the HW structure
  256. * @vf_number: the VF index
  257. *
  258. * return SUCCESS if we obtained the mailbox lock
  259. **/
  260. static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
  261. {
  262. u32 p2v_mailbox;
  263. /* Take ownership of the buffer */
  264. IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
  265. /* reserve mailbox for vf use */
  266. p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
  267. if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
  268. return 0;
  269. return IXGBE_ERR_MBX;
  270. }
  271. /**
  272. * ixgbe_write_mbx_pf - Places a message in the mailbox
  273. * @hw: pointer to the HW structure
  274. * @msg: The message buffer
  275. * @size: Length of buffer
  276. * @vf_number: the VF index
  277. *
  278. * returns SUCCESS if it successfully copied message into the buffer
  279. **/
  280. static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  281. u16 vf_number)
  282. {
  283. s32 ret_val;
  284. u16 i;
  285. /* lock the mailbox to prevent pf/vf race condition */
  286. ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
  287. if (ret_val)
  288. return ret_val;
  289. /* flush msg and acks as we are overwriting the message buffer */
  290. ixgbe_check_for_msg_pf(hw, vf_number);
  291. ixgbe_check_for_ack_pf(hw, vf_number);
  292. /* copy the caller specified message to the mailbox memory buffer */
  293. for (i = 0; i < size; i++)
  294. IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
  295. /* Interrupt VF to tell it a message has been sent and release buffer*/
  296. IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
  297. /* update stats */
  298. hw->mbx.stats.msgs_tx++;
  299. return 0;
  300. }
  301. /**
  302. * ixgbe_read_mbx_pf - Read a message from the mailbox
  303. * @hw: pointer to the HW structure
  304. * @msg: The message buffer
  305. * @size: Length of buffer
  306. * @vf_number: the VF index
  307. *
  308. * This function copies a message from the mailbox buffer to the caller's
  309. * memory buffer. The presumption is that the caller knows that there was
  310. * a message due to a VF request so no polling for message is needed.
  311. **/
  312. static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  313. u16 vf_number)
  314. {
  315. s32 ret_val;
  316. u16 i;
  317. /* lock the mailbox to prevent pf/vf race condition */
  318. ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
  319. if (ret_val)
  320. return ret_val;
  321. /* copy the message to the mailbox memory buffer */
  322. for (i = 0; i < size; i++)
  323. msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
  324. /* Acknowledge the message and release buffer */
  325. IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
  326. /* update stats */
  327. hw->mbx.stats.msgs_rx++;
  328. return 0;
  329. }
  330. #ifdef CONFIG_PCI_IOV
  331. /**
  332. * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
  333. * @hw: pointer to the HW structure
  334. *
  335. * Initializes the hw->mbx struct to correct values for pf mailbox
  336. */
  337. void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
  338. {
  339. struct ixgbe_mbx_info *mbx = &hw->mbx;
  340. if (hw->mac.type != ixgbe_mac_82599EB &&
  341. hw->mac.type != ixgbe_mac_X550 &&
  342. hw->mac.type != ixgbe_mac_X550EM_x &&
  343. hw->mac.type != ixgbe_mac_x550em_a &&
  344. hw->mac.type != ixgbe_mac_X540)
  345. return;
  346. mbx->timeout = 0;
  347. mbx->usec_delay = 0;
  348. mbx->stats.msgs_tx = 0;
  349. mbx->stats.msgs_rx = 0;
  350. mbx->stats.reqs = 0;
  351. mbx->stats.acks = 0;
  352. mbx->stats.rsts = 0;
  353. mbx->size = IXGBE_VFMAILBOX_SIZE;
  354. }
  355. #endif /* CONFIG_PCI_IOV */
  356. const struct ixgbe_mbx_operations mbx_ops_generic = {
  357. .read = ixgbe_read_mbx_pf,
  358. .write = ixgbe_write_mbx_pf,
  359. .read_posted = ixgbe_read_posted_mbx,
  360. .write_posted = ixgbe_write_posted_mbx,
  361. .check_for_msg = ixgbe_check_for_msg_pf,
  362. .check_for_ack = ixgbe_check_for_ack_pf,
  363. .check_for_rst = ixgbe_check_for_rst_pf,
  364. };