i40e_common.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*******************************************************************************
  2. *
  3. * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
  4. * Copyright(c) 2013 Intel Corporation.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * The full GNU General Public License is included in this distribution in
  16. * the file called "COPYING".
  17. *
  18. * Contact Information:
  19. * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  20. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  21. *
  22. ******************************************************************************/
  23. #include "i40e_type.h"
  24. #include "i40e_adminq.h"
  25. #include "i40e_prototype.h"
  26. #include "i40e_virtchnl.h"
  27. /**
  28. * i40e_set_mac_type - Sets MAC type
  29. * @hw: pointer to the HW structure
  30. *
  31. * This function sets the mac type of the adapter based on the
  32. * vendor ID and device ID stored in the hw structure.
  33. **/
  34. i40e_status i40e_set_mac_type(struct i40e_hw *hw)
  35. {
  36. i40e_status status = 0;
  37. if (hw->vendor_id == PCI_VENDOR_ID_INTEL) {
  38. switch (hw->device_id) {
  39. case I40E_DEV_ID_SFP_XL710:
  40. case I40E_DEV_ID_SFP_X710:
  41. case I40E_DEV_ID_QEMU:
  42. case I40E_DEV_ID_KX_A:
  43. case I40E_DEV_ID_KX_B:
  44. case I40E_DEV_ID_KX_C:
  45. case I40E_DEV_ID_KX_D:
  46. case I40E_DEV_ID_QSFP_A:
  47. case I40E_DEV_ID_QSFP_B:
  48. case I40E_DEV_ID_QSFP_C:
  49. hw->mac.type = I40E_MAC_XL710;
  50. break;
  51. case I40E_DEV_ID_VF:
  52. case I40E_DEV_ID_VF_HV:
  53. hw->mac.type = I40E_MAC_VF;
  54. break;
  55. default:
  56. hw->mac.type = I40E_MAC_GENERIC;
  57. break;
  58. }
  59. } else {
  60. status = I40E_ERR_DEVICE_NOT_SUPPORTED;
  61. }
  62. hw_dbg(hw, "i40e_set_mac_type found mac: %d, returns: %d\n",
  63. hw->mac.type, status);
  64. return status;
  65. }
  66. /**
  67. * i40evf_debug_aq
  68. * @hw: debug mask related to admin queue
  69. * @mask: debug mask
  70. * @desc: pointer to admin queue descriptor
  71. * @buffer: pointer to command buffer
  72. *
  73. * Dumps debug log about adminq command with descriptor contents.
  74. **/
  75. void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
  76. void *buffer)
  77. {
  78. struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
  79. u8 *aq_buffer = (u8 *)buffer;
  80. u32 data[4];
  81. u32 i = 0;
  82. if ((!(mask & hw->debug_mask)) || (desc == NULL))
  83. return;
  84. i40e_debug(hw, mask,
  85. "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
  86. aq_desc->opcode, aq_desc->flags, aq_desc->datalen,
  87. aq_desc->retval);
  88. i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
  89. aq_desc->cookie_high, aq_desc->cookie_low);
  90. i40e_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n",
  91. aq_desc->params.internal.param0,
  92. aq_desc->params.internal.param1);
  93. i40e_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n",
  94. aq_desc->params.external.addr_high,
  95. aq_desc->params.external.addr_low);
  96. if ((buffer != NULL) && (aq_desc->datalen != 0)) {
  97. memset(data, 0, sizeof(data));
  98. i40e_debug(hw, mask, "AQ CMD Buffer:\n");
  99. for (i = 0; i < le16_to_cpu(aq_desc->datalen); i++) {
  100. data[((i % 16) / 4)] |=
  101. ((u32)aq_buffer[i]) << (8 * (i % 4));
  102. if ((i % 16) == 15) {
  103. i40e_debug(hw, mask,
  104. "\t0x%04X %08X %08X %08X %08X\n",
  105. i - 15, data[0], data[1], data[2],
  106. data[3]);
  107. memset(data, 0, sizeof(data));
  108. }
  109. }
  110. if ((i % 16) != 0)
  111. i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n",
  112. i - (i % 16), data[0], data[1], data[2],
  113. data[3]);
  114. }
  115. }
  116. /**
  117. * i40evf_check_asq_alive
  118. * @hw: pointer to the hw struct
  119. *
  120. * Returns true if Queue is enabled else false.
  121. **/
  122. bool i40evf_check_asq_alive(struct i40e_hw *hw)
  123. {
  124. return !!(rd32(hw, hw->aq.asq.len) & I40E_PF_ATQLEN_ATQENABLE_MASK);
  125. }
  126. /**
  127. * i40evf_aq_queue_shutdown
  128. * @hw: pointer to the hw struct
  129. * @unloading: is the driver unloading itself
  130. *
  131. * Tell the Firmware that we're shutting down the AdminQ and whether
  132. * or not the driver is unloading as well.
  133. **/
  134. i40e_status i40evf_aq_queue_shutdown(struct i40e_hw *hw,
  135. bool unloading)
  136. {
  137. struct i40e_aq_desc desc;
  138. struct i40e_aqc_queue_shutdown *cmd =
  139. (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
  140. i40e_status status;
  141. i40evf_fill_default_direct_cmd_desc(&desc,
  142. i40e_aqc_opc_queue_shutdown);
  143. if (unloading)
  144. cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING);
  145. status = i40evf_asq_send_command(hw, &desc, NULL, 0, NULL);
  146. return status;
  147. }
  148. /**
  149. * i40e_aq_send_msg_to_pf
  150. * @hw: pointer to the hardware structure
  151. * @v_opcode: opcodes for VF-PF communication
  152. * @v_retval: return error code
  153. * @msg: pointer to the msg buffer
  154. * @msglen: msg length
  155. * @cmd_details: pointer to command details
  156. *
  157. * Send message to PF driver using admin queue. By default, this message
  158. * is sent asynchronously, i.e. i40evf_asq_send_command() does not wait for
  159. * completion before returning.
  160. **/
  161. i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
  162. enum i40e_virtchnl_ops v_opcode,
  163. i40e_status v_retval,
  164. u8 *msg, u16 msglen,
  165. struct i40e_asq_cmd_details *cmd_details)
  166. {
  167. struct i40e_aq_desc desc;
  168. i40e_status status;
  169. i40evf_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
  170. desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_SI);
  171. desc.cookie_high = cpu_to_le32(v_opcode);
  172. desc.cookie_low = cpu_to_le32(v_retval);
  173. if (msglen) {
  174. desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF
  175. | I40E_AQ_FLAG_RD));
  176. if (msglen > I40E_AQ_LARGE_BUF)
  177. desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
  178. desc.datalen = cpu_to_le16(msglen);
  179. }
  180. if (!cmd_details) {
  181. struct i40e_asq_cmd_details details;
  182. memset(&details, 0, sizeof(details));
  183. details.async = true;
  184. cmd_details = &details;
  185. }
  186. status = i40evf_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
  187. msglen, cmd_details);
  188. return status;
  189. }
  190. /**
  191. * i40e_vf_parse_hw_config
  192. * @hw: pointer to the hardware structure
  193. * @msg: pointer to the virtual channel VF resource structure
  194. *
  195. * Given a VF resource message from the PF, populate the hw struct
  196. * with appropriate information.
  197. **/
  198. void i40e_vf_parse_hw_config(struct i40e_hw *hw,
  199. struct i40e_virtchnl_vf_resource *msg)
  200. {
  201. struct i40e_virtchnl_vsi_resource *vsi_res;
  202. int i;
  203. vsi_res = &msg->vsi_res[0];
  204. hw->dev_caps.num_vsis = msg->num_vsis;
  205. hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
  206. hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
  207. hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
  208. hw->dev_caps.dcb = msg->vf_offload_flags &
  209. I40E_VIRTCHNL_VF_OFFLOAD_L2;
  210. hw->dev_caps.fcoe = (msg->vf_offload_flags &
  211. I40E_VIRTCHNL_VF_OFFLOAD_FCOE) ? 1 : 0;
  212. for (i = 0; i < msg->num_vsis; i++) {
  213. if (vsi_res->vsi_type == I40E_VSI_SRIOV) {
  214. memcpy(hw->mac.perm_addr, vsi_res->default_mac_addr,
  215. ETH_ALEN);
  216. memcpy(hw->mac.addr, vsi_res->default_mac_addr,
  217. ETH_ALEN);
  218. }
  219. vsi_res++;
  220. }
  221. }
  222. /**
  223. * i40e_vf_reset
  224. * @hw: pointer to the hardware structure
  225. *
  226. * Send a VF_RESET message to the PF. Does not wait for response from PF
  227. * as none will be forthcoming. Immediately after calling this function,
  228. * the admin queue should be shut down and (optionally) reinitialized.
  229. **/
  230. i40e_status i40e_vf_reset(struct i40e_hw *hw)
  231. {
  232. return i40e_aq_send_msg_to_pf(hw, I40E_VIRTCHNL_OP_RESET_VF,
  233. 0, NULL, 0, NULL);
  234. }