qed_mng_tlv.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/types.h>
  3. #include <asm/byteorder.h>
  4. #include <linux/bug.h>
  5. #include <linux/errno.h>
  6. #include <linux/kernel.h>
  7. #include <linux/slab.h>
  8. #include <linux/string.h>
  9. #include <linux/vmalloc.h>
  10. #include "qed.h"
  11. #include "qed_hw.h"
  12. #include "qed_mcp.h"
  13. #include "qed_reg_addr.h"
  14. #define TLV_TYPE(p) (p[0])
  15. #define TLV_LENGTH(p) (p[1])
  16. #define TLV_FLAGS(p) (p[3])
  17. #define QED_TLV_DATA_MAX (14)
  18. struct qed_tlv_parsed_buf {
  19. /* To be filled with the address to set in Value field */
  20. void *p_val;
  21. /* To be used internally in case the value has to be modified */
  22. u8 data[QED_TLV_DATA_MAX];
  23. };
  24. static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
  25. {
  26. switch (tlv_type) {
  27. case DRV_TLV_FEATURE_FLAGS:
  28. case DRV_TLV_LOCAL_ADMIN_ADDR:
  29. case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
  30. case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
  31. case DRV_TLV_OS_DRIVER_STATES:
  32. case DRV_TLV_PXE_BOOT_PROGRESS:
  33. case DRV_TLV_RX_FRAMES_RECEIVED:
  34. case DRV_TLV_RX_BYTES_RECEIVED:
  35. case DRV_TLV_TX_FRAMES_SENT:
  36. case DRV_TLV_TX_BYTES_SENT:
  37. case DRV_TLV_NPIV_ENABLED:
  38. case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
  39. case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
  40. case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
  41. case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
  42. case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
  43. case DRV_TLV_NCSI_TX_BYTES_SENT:
  44. *tlv_group |= QED_MFW_TLV_GENERIC;
  45. break;
  46. case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
  47. case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
  48. case DRV_TLV_PROMISCUOUS_MODE:
  49. case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
  50. case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
  51. case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
  52. case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
  53. case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
  54. case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  55. case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  56. case DRV_TLV_IOV_OFFLOAD:
  57. case DRV_TLV_TX_QUEUES_EMPTY:
  58. case DRV_TLV_RX_QUEUES_EMPTY:
  59. case DRV_TLV_TX_QUEUES_FULL:
  60. case DRV_TLV_RX_QUEUES_FULL:
  61. *tlv_group |= QED_MFW_TLV_ETH;
  62. break;
  63. case DRV_TLV_SCSI_TO:
  64. case DRV_TLV_R_T_TOV:
  65. case DRV_TLV_R_A_TOV:
  66. case DRV_TLV_E_D_TOV:
  67. case DRV_TLV_CR_TOV:
  68. case DRV_TLV_BOOT_TYPE:
  69. case DRV_TLV_NPIV_STATE:
  70. case DRV_TLV_NUM_OF_NPIV_IDS:
  71. case DRV_TLV_SWITCH_NAME:
  72. case DRV_TLV_SWITCH_PORT_NUM:
  73. case DRV_TLV_SWITCH_PORT_ID:
  74. case DRV_TLV_VENDOR_NAME:
  75. case DRV_TLV_SWITCH_MODEL:
  76. case DRV_TLV_SWITCH_FW_VER:
  77. case DRV_TLV_QOS_PRIORITY_PER_802_1P:
  78. case DRV_TLV_PORT_ALIAS:
  79. case DRV_TLV_PORT_STATE:
  80. case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
  81. case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
  82. case DRV_TLV_LINK_FAILURE_COUNT:
  83. case DRV_TLV_FCOE_BOOT_PROGRESS:
  84. case DRV_TLV_RX_BROADCAST_PACKETS:
  85. case DRV_TLV_TX_BROADCAST_PACKETS:
  86. case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  87. case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  88. case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
  89. case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
  90. case DRV_TLV_FCOE_TX_FRAMES_SENT:
  91. case DRV_TLV_FCOE_TX_BYTES_SENT:
  92. case DRV_TLV_CRC_ERROR_COUNT:
  93. case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
  94. case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
  95. case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
  96. case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
  97. case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
  98. case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
  99. case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
  100. case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
  101. case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
  102. case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
  103. case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
  104. case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
  105. case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
  106. case DRV_TLV_DISPARITY_ERROR_COUNT:
  107. case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
  108. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
  109. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
  110. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
  111. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
  112. case DRV_TLV_LAST_FLOGI_TIMESTAMP:
  113. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
  114. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
  115. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
  116. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
  117. case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
  118. case DRV_TLV_LAST_FLOGI_RJT:
  119. case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
  120. case DRV_TLV_FDISCS_SENT_COUNT:
  121. case DRV_TLV_FDISC_ACCS_RECEIVED:
  122. case DRV_TLV_FDISC_RJTS_RECEIVED:
  123. case DRV_TLV_PLOGI_SENT_COUNT:
  124. case DRV_TLV_PLOGI_ACCS_RECEIVED:
  125. case DRV_TLV_PLOGI_RJTS_RECEIVED:
  126. case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
  127. case DRV_TLV_PLOGI_1_TIMESTAMP:
  128. case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
  129. case DRV_TLV_PLOGI_2_TIMESTAMP:
  130. case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
  131. case DRV_TLV_PLOGI_3_TIMESTAMP:
  132. case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
  133. case DRV_TLV_PLOGI_4_TIMESTAMP:
  134. case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
  135. case DRV_TLV_PLOGI_5_TIMESTAMP:
  136. case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
  137. case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
  138. case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
  139. case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
  140. case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
  141. case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
  142. case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
  143. case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
  144. case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
  145. case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
  146. case DRV_TLV_LOGOS_ISSUED:
  147. case DRV_TLV_LOGO_ACCS_RECEIVED:
  148. case DRV_TLV_LOGO_RJTS_RECEIVED:
  149. case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
  150. case DRV_TLV_LOGO_1_TIMESTAMP:
  151. case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
  152. case DRV_TLV_LOGO_2_TIMESTAMP:
  153. case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
  154. case DRV_TLV_LOGO_3_TIMESTAMP:
  155. case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
  156. case DRV_TLV_LOGO_4_TIMESTAMP:
  157. case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
  158. case DRV_TLV_LOGO_5_TIMESTAMP:
  159. case DRV_TLV_LOGOS_RECEIVED:
  160. case DRV_TLV_ACCS_ISSUED:
  161. case DRV_TLV_PRLIS_ISSUED:
  162. case DRV_TLV_ACCS_RECEIVED:
  163. case DRV_TLV_ABTS_SENT_COUNT:
  164. case DRV_TLV_ABTS_ACCS_RECEIVED:
  165. case DRV_TLV_ABTS_RJTS_RECEIVED:
  166. case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
  167. case DRV_TLV_ABTS_1_TIMESTAMP:
  168. case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
  169. case DRV_TLV_ABTS_2_TIMESTAMP:
  170. case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
  171. case DRV_TLV_ABTS_3_TIMESTAMP:
  172. case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
  173. case DRV_TLV_ABTS_4_TIMESTAMP:
  174. case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
  175. case DRV_TLV_ABTS_5_TIMESTAMP:
  176. case DRV_TLV_RSCNS_RECEIVED:
  177. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
  178. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
  179. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
  180. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
  181. case DRV_TLV_LUN_RESETS_ISSUED:
  182. case DRV_TLV_ABORT_TASK_SETS_ISSUED:
  183. case DRV_TLV_TPRLOS_SENT:
  184. case DRV_TLV_NOS_SENT_COUNT:
  185. case DRV_TLV_NOS_RECEIVED_COUNT:
  186. case DRV_TLV_OLS_COUNT:
  187. case DRV_TLV_LR_COUNT:
  188. case DRV_TLV_LRR_COUNT:
  189. case DRV_TLV_LIP_SENT_COUNT:
  190. case DRV_TLV_LIP_RECEIVED_COUNT:
  191. case DRV_TLV_EOFA_COUNT:
  192. case DRV_TLV_EOFNI_COUNT:
  193. case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
  194. case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
  195. case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
  196. case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
  197. case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
  198. case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
  199. case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
  200. case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
  201. case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
  202. case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
  203. case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
  204. case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
  205. case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
  206. case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
  207. case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
  208. case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
  209. case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
  210. case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
  211. case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
  212. *tlv_group = QED_MFW_TLV_FCOE;
  213. break;
  214. case DRV_TLV_TARGET_LLMNR_ENABLED:
  215. case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
  216. case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
  217. case DRV_TLV_AUTHENTICATION_METHOD:
  218. case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
  219. case DRV_TLV_MAX_FRAME_SIZE:
  220. case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
  221. case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
  222. case DRV_TLV_ISCSI_BOOT_PROGRESS:
  223. case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  224. case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  225. case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
  226. case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
  227. case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
  228. case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
  229. *tlv_group |= QED_MFW_TLV_ISCSI;
  230. break;
  231. default:
  232. return -EINVAL;
  233. }
  234. return 0;
  235. }
  236. /* Returns size of the data buffer or, -1 in case TLV data is not available. */
  237. static int
  238. qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
  239. struct qed_mfw_tlv_generic *p_drv_buf,
  240. struct qed_tlv_parsed_buf *p_buf)
  241. {
  242. switch (p_tlv->tlv_type) {
  243. case DRV_TLV_FEATURE_FLAGS:
  244. if (p_drv_buf->flags.b_set) {
  245. memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
  246. p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
  247. 1 : 0;
  248. p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
  249. 1 : 0) << 1;
  250. p_buf->p_val = p_buf->data;
  251. return QED_MFW_TLV_FLAGS_SIZE;
  252. }
  253. break;
  254. case DRV_TLV_LOCAL_ADMIN_ADDR:
  255. case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
  256. case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
  257. {
  258. int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
  259. if (p_drv_buf->mac_set[idx]) {
  260. p_buf->p_val = p_drv_buf->mac[idx];
  261. return ETH_ALEN;
  262. }
  263. break;
  264. }
  265. case DRV_TLV_RX_FRAMES_RECEIVED:
  266. if (p_drv_buf->rx_frames_set) {
  267. p_buf->p_val = &p_drv_buf->rx_frames;
  268. return sizeof(p_drv_buf->rx_frames);
  269. }
  270. break;
  271. case DRV_TLV_RX_BYTES_RECEIVED:
  272. if (p_drv_buf->rx_bytes_set) {
  273. p_buf->p_val = &p_drv_buf->rx_bytes;
  274. return sizeof(p_drv_buf->rx_bytes);
  275. }
  276. break;
  277. case DRV_TLV_TX_FRAMES_SENT:
  278. if (p_drv_buf->tx_frames_set) {
  279. p_buf->p_val = &p_drv_buf->tx_frames;
  280. return sizeof(p_drv_buf->tx_frames);
  281. }
  282. break;
  283. case DRV_TLV_TX_BYTES_SENT:
  284. if (p_drv_buf->tx_bytes_set) {
  285. p_buf->p_val = &p_drv_buf->tx_bytes;
  286. return sizeof(p_drv_buf->tx_bytes);
  287. }
  288. break;
  289. default:
  290. break;
  291. }
  292. return -1;
  293. }
  294. static int
  295. qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
  296. struct qed_mfw_tlv_eth *p_drv_buf,
  297. struct qed_tlv_parsed_buf *p_buf)
  298. {
  299. switch (p_tlv->tlv_type) {
  300. case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
  301. if (p_drv_buf->lso_maxoff_size_set) {
  302. p_buf->p_val = &p_drv_buf->lso_maxoff_size;
  303. return sizeof(p_drv_buf->lso_maxoff_size);
  304. }
  305. break;
  306. case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
  307. if (p_drv_buf->lso_minseg_size_set) {
  308. p_buf->p_val = &p_drv_buf->lso_minseg_size;
  309. return sizeof(p_drv_buf->lso_minseg_size);
  310. }
  311. break;
  312. case DRV_TLV_PROMISCUOUS_MODE:
  313. if (p_drv_buf->prom_mode_set) {
  314. p_buf->p_val = &p_drv_buf->prom_mode;
  315. return sizeof(p_drv_buf->prom_mode);
  316. }
  317. break;
  318. case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
  319. if (p_drv_buf->tx_descr_size_set) {
  320. p_buf->p_val = &p_drv_buf->tx_descr_size;
  321. return sizeof(p_drv_buf->tx_descr_size);
  322. }
  323. break;
  324. case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
  325. if (p_drv_buf->rx_descr_size_set) {
  326. p_buf->p_val = &p_drv_buf->rx_descr_size;
  327. return sizeof(p_drv_buf->rx_descr_size);
  328. }
  329. break;
  330. case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
  331. if (p_drv_buf->netq_count_set) {
  332. p_buf->p_val = &p_drv_buf->netq_count;
  333. return sizeof(p_drv_buf->netq_count);
  334. }
  335. break;
  336. case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
  337. if (p_drv_buf->tcp4_offloads_set) {
  338. p_buf->p_val = &p_drv_buf->tcp4_offloads;
  339. return sizeof(p_drv_buf->tcp4_offloads);
  340. }
  341. break;
  342. case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
  343. if (p_drv_buf->tcp6_offloads_set) {
  344. p_buf->p_val = &p_drv_buf->tcp6_offloads;
  345. return sizeof(p_drv_buf->tcp6_offloads);
  346. }
  347. break;
  348. case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  349. if (p_drv_buf->tx_descr_qdepth_set) {
  350. p_buf->p_val = &p_drv_buf->tx_descr_qdepth;
  351. return sizeof(p_drv_buf->tx_descr_qdepth);
  352. }
  353. break;
  354. case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  355. if (p_drv_buf->rx_descr_qdepth_set) {
  356. p_buf->p_val = &p_drv_buf->rx_descr_qdepth;
  357. return sizeof(p_drv_buf->rx_descr_qdepth);
  358. }
  359. break;
  360. case DRV_TLV_IOV_OFFLOAD:
  361. if (p_drv_buf->iov_offload_set) {
  362. p_buf->p_val = &p_drv_buf->iov_offload;
  363. return sizeof(p_drv_buf->iov_offload);
  364. }
  365. break;
  366. case DRV_TLV_TX_QUEUES_EMPTY:
  367. if (p_drv_buf->txqs_empty_set) {
  368. p_buf->p_val = &p_drv_buf->txqs_empty;
  369. return sizeof(p_drv_buf->txqs_empty);
  370. }
  371. break;
  372. case DRV_TLV_RX_QUEUES_EMPTY:
  373. if (p_drv_buf->rxqs_empty_set) {
  374. p_buf->p_val = &p_drv_buf->rxqs_empty;
  375. return sizeof(p_drv_buf->rxqs_empty);
  376. }
  377. break;
  378. case DRV_TLV_TX_QUEUES_FULL:
  379. if (p_drv_buf->num_txqs_full_set) {
  380. p_buf->p_val = &p_drv_buf->num_txqs_full;
  381. return sizeof(p_drv_buf->num_txqs_full);
  382. }
  383. break;
  384. case DRV_TLV_RX_QUEUES_FULL:
  385. if (p_drv_buf->num_rxqs_full_set) {
  386. p_buf->p_val = &p_drv_buf->num_rxqs_full;
  387. return sizeof(p_drv_buf->num_rxqs_full);
  388. }
  389. break;
  390. default:
  391. break;
  392. }
  393. return -1;
  394. }
  395. static int
  396. qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
  397. struct qed_tlv_parsed_buf *p_buf)
  398. {
  399. if (!p_time->b_set)
  400. return -1;
  401. /* Validate numbers */
  402. if (p_time->month > 12)
  403. p_time->month = 0;
  404. if (p_time->day > 31)
  405. p_time->day = 0;
  406. if (p_time->hour > 23)
  407. p_time->hour = 0;
  408. if (p_time->min > 59)
  409. p_time->hour = 0;
  410. if (p_time->msec > 999)
  411. p_time->msec = 0;
  412. if (p_time->usec > 999)
  413. p_time->usec = 0;
  414. memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
  415. snprintf(p_buf->data, 14, "%d%d%d%d%d%d",
  416. p_time->month, p_time->day,
  417. p_time->hour, p_time->min, p_time->msec, p_time->usec);
  418. p_buf->p_val = p_buf->data;
  419. return QED_MFW_TLV_TIME_SIZE;
  420. }
  421. static int
  422. qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
  423. struct qed_mfw_tlv_fcoe *p_drv_buf,
  424. struct qed_tlv_parsed_buf *p_buf)
  425. {
  426. struct qed_mfw_tlv_time *p_time;
  427. u8 idx;
  428. switch (p_tlv->tlv_type) {
  429. case DRV_TLV_SCSI_TO:
  430. if (p_drv_buf->scsi_timeout_set) {
  431. p_buf->p_val = &p_drv_buf->scsi_timeout;
  432. return sizeof(p_drv_buf->scsi_timeout);
  433. }
  434. break;
  435. case DRV_TLV_R_T_TOV:
  436. if (p_drv_buf->rt_tov_set) {
  437. p_buf->p_val = &p_drv_buf->rt_tov;
  438. return sizeof(p_drv_buf->rt_tov);
  439. }
  440. break;
  441. case DRV_TLV_R_A_TOV:
  442. if (p_drv_buf->ra_tov_set) {
  443. p_buf->p_val = &p_drv_buf->ra_tov;
  444. return sizeof(p_drv_buf->ra_tov);
  445. }
  446. break;
  447. case DRV_TLV_E_D_TOV:
  448. if (p_drv_buf->ed_tov_set) {
  449. p_buf->p_val = &p_drv_buf->ed_tov;
  450. return sizeof(p_drv_buf->ed_tov);
  451. }
  452. break;
  453. case DRV_TLV_CR_TOV:
  454. if (p_drv_buf->cr_tov_set) {
  455. p_buf->p_val = &p_drv_buf->cr_tov;
  456. return sizeof(p_drv_buf->cr_tov);
  457. }
  458. break;
  459. case DRV_TLV_BOOT_TYPE:
  460. if (p_drv_buf->boot_type_set) {
  461. p_buf->p_val = &p_drv_buf->boot_type;
  462. return sizeof(p_drv_buf->boot_type);
  463. }
  464. break;
  465. case DRV_TLV_NPIV_STATE:
  466. if (p_drv_buf->npiv_state_set) {
  467. p_buf->p_val = &p_drv_buf->npiv_state;
  468. return sizeof(p_drv_buf->npiv_state);
  469. }
  470. break;
  471. case DRV_TLV_NUM_OF_NPIV_IDS:
  472. if (p_drv_buf->num_npiv_ids_set) {
  473. p_buf->p_val = &p_drv_buf->num_npiv_ids;
  474. return sizeof(p_drv_buf->num_npiv_ids);
  475. }
  476. break;
  477. case DRV_TLV_SWITCH_NAME:
  478. if (p_drv_buf->switch_name_set) {
  479. p_buf->p_val = &p_drv_buf->switch_name;
  480. return sizeof(p_drv_buf->switch_name);
  481. }
  482. break;
  483. case DRV_TLV_SWITCH_PORT_NUM:
  484. if (p_drv_buf->switch_portnum_set) {
  485. p_buf->p_val = &p_drv_buf->switch_portnum;
  486. return sizeof(p_drv_buf->switch_portnum);
  487. }
  488. break;
  489. case DRV_TLV_SWITCH_PORT_ID:
  490. if (p_drv_buf->switch_portid_set) {
  491. p_buf->p_val = &p_drv_buf->switch_portid;
  492. return sizeof(p_drv_buf->switch_portid);
  493. }
  494. break;
  495. case DRV_TLV_VENDOR_NAME:
  496. if (p_drv_buf->vendor_name_set) {
  497. p_buf->p_val = &p_drv_buf->vendor_name;
  498. return sizeof(p_drv_buf->vendor_name);
  499. }
  500. break;
  501. case DRV_TLV_SWITCH_MODEL:
  502. if (p_drv_buf->switch_model_set) {
  503. p_buf->p_val = &p_drv_buf->switch_model;
  504. return sizeof(p_drv_buf->switch_model);
  505. }
  506. break;
  507. case DRV_TLV_SWITCH_FW_VER:
  508. if (p_drv_buf->switch_fw_version_set) {
  509. p_buf->p_val = &p_drv_buf->switch_fw_version;
  510. return sizeof(p_drv_buf->switch_fw_version);
  511. }
  512. break;
  513. case DRV_TLV_QOS_PRIORITY_PER_802_1P:
  514. if (p_drv_buf->qos_pri_set) {
  515. p_buf->p_val = &p_drv_buf->qos_pri;
  516. return sizeof(p_drv_buf->qos_pri);
  517. }
  518. break;
  519. case DRV_TLV_PORT_ALIAS:
  520. if (p_drv_buf->port_alias_set) {
  521. p_buf->p_val = &p_drv_buf->port_alias;
  522. return sizeof(p_drv_buf->port_alias);
  523. }
  524. break;
  525. case DRV_TLV_PORT_STATE:
  526. if (p_drv_buf->port_state_set) {
  527. p_buf->p_val = &p_drv_buf->port_state;
  528. return sizeof(p_drv_buf->port_state);
  529. }
  530. break;
  531. case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
  532. if (p_drv_buf->fip_tx_descr_size_set) {
  533. p_buf->p_val = &p_drv_buf->fip_tx_descr_size;
  534. return sizeof(p_drv_buf->fip_tx_descr_size);
  535. }
  536. break;
  537. case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
  538. if (p_drv_buf->fip_rx_descr_size_set) {
  539. p_buf->p_val = &p_drv_buf->fip_rx_descr_size;
  540. return sizeof(p_drv_buf->fip_rx_descr_size);
  541. }
  542. break;
  543. case DRV_TLV_LINK_FAILURE_COUNT:
  544. if (p_drv_buf->link_failures_set) {
  545. p_buf->p_val = &p_drv_buf->link_failures;
  546. return sizeof(p_drv_buf->link_failures);
  547. }
  548. break;
  549. case DRV_TLV_FCOE_BOOT_PROGRESS:
  550. if (p_drv_buf->fcoe_boot_progress_set) {
  551. p_buf->p_val = &p_drv_buf->fcoe_boot_progress;
  552. return sizeof(p_drv_buf->fcoe_boot_progress);
  553. }
  554. break;
  555. case DRV_TLV_RX_BROADCAST_PACKETS:
  556. if (p_drv_buf->rx_bcast_set) {
  557. p_buf->p_val = &p_drv_buf->rx_bcast;
  558. return sizeof(p_drv_buf->rx_bcast);
  559. }
  560. break;
  561. case DRV_TLV_TX_BROADCAST_PACKETS:
  562. if (p_drv_buf->tx_bcast_set) {
  563. p_buf->p_val = &p_drv_buf->tx_bcast;
  564. return sizeof(p_drv_buf->tx_bcast);
  565. }
  566. break;
  567. case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  568. if (p_drv_buf->fcoe_txq_depth_set) {
  569. p_buf->p_val = &p_drv_buf->fcoe_txq_depth;
  570. return sizeof(p_drv_buf->fcoe_txq_depth);
  571. }
  572. break;
  573. case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  574. if (p_drv_buf->fcoe_rxq_depth_set) {
  575. p_buf->p_val = &p_drv_buf->fcoe_rxq_depth;
  576. return sizeof(p_drv_buf->fcoe_rxq_depth);
  577. }
  578. break;
  579. case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
  580. if (p_drv_buf->fcoe_rx_frames_set) {
  581. p_buf->p_val = &p_drv_buf->fcoe_rx_frames;
  582. return sizeof(p_drv_buf->fcoe_rx_frames);
  583. }
  584. break;
  585. case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
  586. if (p_drv_buf->fcoe_rx_bytes_set) {
  587. p_buf->p_val = &p_drv_buf->fcoe_rx_bytes;
  588. return sizeof(p_drv_buf->fcoe_rx_bytes);
  589. }
  590. break;
  591. case DRV_TLV_FCOE_TX_FRAMES_SENT:
  592. if (p_drv_buf->fcoe_tx_frames_set) {
  593. p_buf->p_val = &p_drv_buf->fcoe_tx_frames;
  594. return sizeof(p_drv_buf->fcoe_tx_frames);
  595. }
  596. break;
  597. case DRV_TLV_FCOE_TX_BYTES_SENT:
  598. if (p_drv_buf->fcoe_tx_bytes_set) {
  599. p_buf->p_val = &p_drv_buf->fcoe_tx_bytes;
  600. return sizeof(p_drv_buf->fcoe_tx_bytes);
  601. }
  602. break;
  603. case DRV_TLV_CRC_ERROR_COUNT:
  604. if (p_drv_buf->crc_count_set) {
  605. p_buf->p_val = &p_drv_buf->crc_count;
  606. return sizeof(p_drv_buf->crc_count);
  607. }
  608. break;
  609. case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
  610. case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
  611. case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
  612. case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
  613. case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
  614. idx = (p_tlv->tlv_type -
  615. DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
  616. if (p_drv_buf->crc_err_src_fcid_set[idx]) {
  617. p_buf->p_val = &p_drv_buf->crc_err_src_fcid[idx];
  618. return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
  619. }
  620. break;
  621. case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
  622. case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
  623. case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
  624. case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
  625. case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
  626. idx = (p_tlv->tlv_type - DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
  627. return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
  628. p_buf);
  629. case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
  630. if (p_drv_buf->losync_err_set) {
  631. p_buf->p_val = &p_drv_buf->losync_err;
  632. return sizeof(p_drv_buf->losync_err);
  633. }
  634. break;
  635. case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
  636. if (p_drv_buf->losig_err_set) {
  637. p_buf->p_val = &p_drv_buf->losig_err;
  638. return sizeof(p_drv_buf->losig_err);
  639. }
  640. break;
  641. case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
  642. if (p_drv_buf->primtive_err_set) {
  643. p_buf->p_val = &p_drv_buf->primtive_err;
  644. return sizeof(p_drv_buf->primtive_err);
  645. }
  646. break;
  647. case DRV_TLV_DISPARITY_ERROR_COUNT:
  648. if (p_drv_buf->disparity_err_set) {
  649. p_buf->p_val = &p_drv_buf->disparity_err;
  650. return sizeof(p_drv_buf->disparity_err);
  651. }
  652. break;
  653. case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
  654. if (p_drv_buf->code_violation_err_set) {
  655. p_buf->p_val = &p_drv_buf->code_violation_err;
  656. return sizeof(p_drv_buf->code_violation_err);
  657. }
  658. break;
  659. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
  660. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
  661. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
  662. case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
  663. idx = p_tlv->tlv_type -
  664. DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
  665. if (p_drv_buf->flogi_param_set[idx]) {
  666. p_buf->p_val = &p_drv_buf->flogi_param[idx];
  667. return sizeof(p_drv_buf->flogi_param[idx]);
  668. }
  669. break;
  670. case DRV_TLV_LAST_FLOGI_TIMESTAMP:
  671. return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
  672. p_buf);
  673. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
  674. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
  675. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
  676. case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
  677. idx = p_tlv->tlv_type -
  678. DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
  679. if (p_drv_buf->flogi_acc_param_set[idx]) {
  680. p_buf->p_val = &p_drv_buf->flogi_acc_param[idx];
  681. return sizeof(p_drv_buf->flogi_acc_param[idx]);
  682. }
  683. break;
  684. case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
  685. return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
  686. p_buf);
  687. case DRV_TLV_LAST_FLOGI_RJT:
  688. if (p_drv_buf->flogi_rjt_set) {
  689. p_buf->p_val = &p_drv_buf->flogi_rjt;
  690. return sizeof(p_drv_buf->flogi_rjt);
  691. }
  692. break;
  693. case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
  694. return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
  695. p_buf);
  696. case DRV_TLV_FDISCS_SENT_COUNT:
  697. if (p_drv_buf->fdiscs_set) {
  698. p_buf->p_val = &p_drv_buf->fdiscs;
  699. return sizeof(p_drv_buf->fdiscs);
  700. }
  701. break;
  702. case DRV_TLV_FDISC_ACCS_RECEIVED:
  703. if (p_drv_buf->fdisc_acc_set) {
  704. p_buf->p_val = &p_drv_buf->fdisc_acc;
  705. return sizeof(p_drv_buf->fdisc_acc);
  706. }
  707. break;
  708. case DRV_TLV_FDISC_RJTS_RECEIVED:
  709. if (p_drv_buf->fdisc_rjt_set) {
  710. p_buf->p_val = &p_drv_buf->fdisc_rjt;
  711. return sizeof(p_drv_buf->fdisc_rjt);
  712. }
  713. break;
  714. case DRV_TLV_PLOGI_SENT_COUNT:
  715. if (p_drv_buf->plogi_set) {
  716. p_buf->p_val = &p_drv_buf->plogi;
  717. return sizeof(p_drv_buf->plogi);
  718. }
  719. break;
  720. case DRV_TLV_PLOGI_ACCS_RECEIVED:
  721. if (p_drv_buf->plogi_acc_set) {
  722. p_buf->p_val = &p_drv_buf->plogi_acc;
  723. return sizeof(p_drv_buf->plogi_acc);
  724. }
  725. break;
  726. case DRV_TLV_PLOGI_RJTS_RECEIVED:
  727. if (p_drv_buf->plogi_rjt_set) {
  728. p_buf->p_val = &p_drv_buf->plogi_rjt;
  729. return sizeof(p_drv_buf->plogi_rjt);
  730. }
  731. break;
  732. case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
  733. case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
  734. case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
  735. case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
  736. case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
  737. idx = (p_tlv->tlv_type -
  738. DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
  739. if (p_drv_buf->plogi_dst_fcid_set[idx]) {
  740. p_buf->p_val = &p_drv_buf->plogi_dst_fcid[idx];
  741. return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
  742. }
  743. break;
  744. case DRV_TLV_PLOGI_1_TIMESTAMP:
  745. case DRV_TLV_PLOGI_2_TIMESTAMP:
  746. case DRV_TLV_PLOGI_3_TIMESTAMP:
  747. case DRV_TLV_PLOGI_4_TIMESTAMP:
  748. case DRV_TLV_PLOGI_5_TIMESTAMP:
  749. idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
  750. return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
  751. p_buf);
  752. case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
  753. case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
  754. case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
  755. case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
  756. case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
  757. idx = (p_tlv->tlv_type -
  758. DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
  759. if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
  760. p_buf->p_val = &p_drv_buf->plogi_acc_src_fcid[idx];
  761. return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
  762. }
  763. break;
  764. case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
  765. case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
  766. case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
  767. case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
  768. case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
  769. idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
  770. p_time = &p_drv_buf->plogi_acc_tstamp[idx];
  771. return qed_mfw_get_tlv_time_value(p_time, p_buf);
  772. case DRV_TLV_LOGOS_ISSUED:
  773. if (p_drv_buf->tx_plogos_set) {
  774. p_buf->p_val = &p_drv_buf->tx_plogos;
  775. return sizeof(p_drv_buf->tx_plogos);
  776. }
  777. break;
  778. case DRV_TLV_LOGO_ACCS_RECEIVED:
  779. if (p_drv_buf->plogo_acc_set) {
  780. p_buf->p_val = &p_drv_buf->plogo_acc;
  781. return sizeof(p_drv_buf->plogo_acc);
  782. }
  783. break;
  784. case DRV_TLV_LOGO_RJTS_RECEIVED:
  785. if (p_drv_buf->plogo_rjt_set) {
  786. p_buf->p_val = &p_drv_buf->plogo_rjt;
  787. return sizeof(p_drv_buf->plogo_rjt);
  788. }
  789. break;
  790. case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
  791. case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
  792. case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
  793. case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
  794. case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
  795. idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) /
  796. 2;
  797. if (p_drv_buf->plogo_src_fcid_set[idx]) {
  798. p_buf->p_val = &p_drv_buf->plogo_src_fcid[idx];
  799. return sizeof(p_drv_buf->plogo_src_fcid[idx]);
  800. }
  801. break;
  802. case DRV_TLV_LOGO_1_TIMESTAMP:
  803. case DRV_TLV_LOGO_2_TIMESTAMP:
  804. case DRV_TLV_LOGO_3_TIMESTAMP:
  805. case DRV_TLV_LOGO_4_TIMESTAMP:
  806. case DRV_TLV_LOGO_5_TIMESTAMP:
  807. idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_TIMESTAMP) / 2;
  808. return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
  809. p_buf);
  810. case DRV_TLV_LOGOS_RECEIVED:
  811. if (p_drv_buf->rx_logos_set) {
  812. p_buf->p_val = &p_drv_buf->rx_logos;
  813. return sizeof(p_drv_buf->rx_logos);
  814. }
  815. break;
  816. case DRV_TLV_ACCS_ISSUED:
  817. if (p_drv_buf->tx_accs_set) {
  818. p_buf->p_val = &p_drv_buf->tx_accs;
  819. return sizeof(p_drv_buf->tx_accs);
  820. }
  821. break;
  822. case DRV_TLV_PRLIS_ISSUED:
  823. if (p_drv_buf->tx_prlis_set) {
  824. p_buf->p_val = &p_drv_buf->tx_prlis;
  825. return sizeof(p_drv_buf->tx_prlis);
  826. }
  827. break;
  828. case DRV_TLV_ACCS_RECEIVED:
  829. if (p_drv_buf->rx_accs_set) {
  830. p_buf->p_val = &p_drv_buf->rx_accs;
  831. return sizeof(p_drv_buf->rx_accs);
  832. }
  833. break;
  834. case DRV_TLV_ABTS_SENT_COUNT:
  835. if (p_drv_buf->tx_abts_set) {
  836. p_buf->p_val = &p_drv_buf->tx_abts;
  837. return sizeof(p_drv_buf->tx_abts);
  838. }
  839. break;
  840. case DRV_TLV_ABTS_ACCS_RECEIVED:
  841. if (p_drv_buf->rx_abts_acc_set) {
  842. p_buf->p_val = &p_drv_buf->rx_abts_acc;
  843. return sizeof(p_drv_buf->rx_abts_acc);
  844. }
  845. break;
  846. case DRV_TLV_ABTS_RJTS_RECEIVED:
  847. if (p_drv_buf->rx_abts_rjt_set) {
  848. p_buf->p_val = &p_drv_buf->rx_abts_rjt;
  849. return sizeof(p_drv_buf->rx_abts_rjt);
  850. }
  851. break;
  852. case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
  853. case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
  854. case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
  855. case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
  856. case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
  857. idx = (p_tlv->tlv_type -
  858. DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
  859. if (p_drv_buf->abts_dst_fcid_set[idx]) {
  860. p_buf->p_val = &p_drv_buf->abts_dst_fcid[idx];
  861. return sizeof(p_drv_buf->abts_dst_fcid[idx]);
  862. }
  863. break;
  864. case DRV_TLV_ABTS_1_TIMESTAMP:
  865. case DRV_TLV_ABTS_2_TIMESTAMP:
  866. case DRV_TLV_ABTS_3_TIMESTAMP:
  867. case DRV_TLV_ABTS_4_TIMESTAMP:
  868. case DRV_TLV_ABTS_5_TIMESTAMP:
  869. idx = (p_tlv->tlv_type - DRV_TLV_ABTS_1_TIMESTAMP) / 2;
  870. return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
  871. p_buf);
  872. case DRV_TLV_RSCNS_RECEIVED:
  873. if (p_drv_buf->rx_rscn_set) {
  874. p_buf->p_val = &p_drv_buf->rx_rscn;
  875. return sizeof(p_drv_buf->rx_rscn);
  876. }
  877. break;
  878. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
  879. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
  880. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
  881. case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
  882. idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
  883. if (p_drv_buf->rx_rscn_nport_set[idx]) {
  884. p_buf->p_val = &p_drv_buf->rx_rscn_nport[idx];
  885. return sizeof(p_drv_buf->rx_rscn_nport[idx]);
  886. }
  887. break;
  888. case DRV_TLV_LUN_RESETS_ISSUED:
  889. if (p_drv_buf->tx_lun_rst_set) {
  890. p_buf->p_val = &p_drv_buf->tx_lun_rst;
  891. return sizeof(p_drv_buf->tx_lun_rst);
  892. }
  893. break;
  894. case DRV_TLV_ABORT_TASK_SETS_ISSUED:
  895. if (p_drv_buf->abort_task_sets_set) {
  896. p_buf->p_val = &p_drv_buf->abort_task_sets;
  897. return sizeof(p_drv_buf->abort_task_sets);
  898. }
  899. break;
  900. case DRV_TLV_TPRLOS_SENT:
  901. if (p_drv_buf->tx_tprlos_set) {
  902. p_buf->p_val = &p_drv_buf->tx_tprlos;
  903. return sizeof(p_drv_buf->tx_tprlos);
  904. }
  905. break;
  906. case DRV_TLV_NOS_SENT_COUNT:
  907. if (p_drv_buf->tx_nos_set) {
  908. p_buf->p_val = &p_drv_buf->tx_nos;
  909. return sizeof(p_drv_buf->tx_nos);
  910. }
  911. break;
  912. case DRV_TLV_NOS_RECEIVED_COUNT:
  913. if (p_drv_buf->rx_nos_set) {
  914. p_buf->p_val = &p_drv_buf->rx_nos;
  915. return sizeof(p_drv_buf->rx_nos);
  916. }
  917. break;
  918. case DRV_TLV_OLS_COUNT:
  919. if (p_drv_buf->ols_set) {
  920. p_buf->p_val = &p_drv_buf->ols;
  921. return sizeof(p_drv_buf->ols);
  922. }
  923. break;
  924. case DRV_TLV_LR_COUNT:
  925. if (p_drv_buf->lr_set) {
  926. p_buf->p_val = &p_drv_buf->lr;
  927. return sizeof(p_drv_buf->lr);
  928. }
  929. break;
  930. case DRV_TLV_LRR_COUNT:
  931. if (p_drv_buf->lrr_set) {
  932. p_buf->p_val = &p_drv_buf->lrr;
  933. return sizeof(p_drv_buf->lrr);
  934. }
  935. break;
  936. case DRV_TLV_LIP_SENT_COUNT:
  937. if (p_drv_buf->tx_lip_set) {
  938. p_buf->p_val = &p_drv_buf->tx_lip;
  939. return sizeof(p_drv_buf->tx_lip);
  940. }
  941. break;
  942. case DRV_TLV_LIP_RECEIVED_COUNT:
  943. if (p_drv_buf->rx_lip_set) {
  944. p_buf->p_val = &p_drv_buf->rx_lip;
  945. return sizeof(p_drv_buf->rx_lip);
  946. }
  947. break;
  948. case DRV_TLV_EOFA_COUNT:
  949. if (p_drv_buf->eofa_set) {
  950. p_buf->p_val = &p_drv_buf->eofa;
  951. return sizeof(p_drv_buf->eofa);
  952. }
  953. break;
  954. case DRV_TLV_EOFNI_COUNT:
  955. if (p_drv_buf->eofni_set) {
  956. p_buf->p_val = &p_drv_buf->eofni;
  957. return sizeof(p_drv_buf->eofni);
  958. }
  959. break;
  960. case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
  961. if (p_drv_buf->scsi_chks_set) {
  962. p_buf->p_val = &p_drv_buf->scsi_chks;
  963. return sizeof(p_drv_buf->scsi_chks);
  964. }
  965. break;
  966. case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
  967. if (p_drv_buf->scsi_cond_met_set) {
  968. p_buf->p_val = &p_drv_buf->scsi_cond_met;
  969. return sizeof(p_drv_buf->scsi_cond_met);
  970. }
  971. break;
  972. case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
  973. if (p_drv_buf->scsi_busy_set) {
  974. p_buf->p_val = &p_drv_buf->scsi_busy;
  975. return sizeof(p_drv_buf->scsi_busy);
  976. }
  977. break;
  978. case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
  979. if (p_drv_buf->scsi_inter_set) {
  980. p_buf->p_val = &p_drv_buf->scsi_inter;
  981. return sizeof(p_drv_buf->scsi_inter);
  982. }
  983. break;
  984. case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
  985. if (p_drv_buf->scsi_inter_cond_met_set) {
  986. p_buf->p_val = &p_drv_buf->scsi_inter_cond_met;
  987. return sizeof(p_drv_buf->scsi_inter_cond_met);
  988. }
  989. break;
  990. case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
  991. if (p_drv_buf->scsi_rsv_conflicts_set) {
  992. p_buf->p_val = &p_drv_buf->scsi_rsv_conflicts;
  993. return sizeof(p_drv_buf->scsi_rsv_conflicts);
  994. }
  995. break;
  996. case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
  997. if (p_drv_buf->scsi_tsk_full_set) {
  998. p_buf->p_val = &p_drv_buf->scsi_tsk_full;
  999. return sizeof(p_drv_buf->scsi_tsk_full);
  1000. }
  1001. break;
  1002. case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
  1003. if (p_drv_buf->scsi_aca_active_set) {
  1004. p_buf->p_val = &p_drv_buf->scsi_aca_active;
  1005. return sizeof(p_drv_buf->scsi_aca_active);
  1006. }
  1007. break;
  1008. case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
  1009. if (p_drv_buf->scsi_tsk_abort_set) {
  1010. p_buf->p_val = &p_drv_buf->scsi_tsk_abort;
  1011. return sizeof(p_drv_buf->scsi_tsk_abort);
  1012. }
  1013. break;
  1014. case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
  1015. case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
  1016. case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
  1017. case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
  1018. case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
  1019. idx = (p_tlv->tlv_type -
  1020. DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
  1021. if (p_drv_buf->scsi_rx_chk_set[idx]) {
  1022. p_buf->p_val = &p_drv_buf->scsi_rx_chk[idx];
  1023. return sizeof(p_drv_buf->scsi_rx_chk[idx]);
  1024. }
  1025. break;
  1026. case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
  1027. case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
  1028. case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
  1029. case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
  1030. case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
  1031. idx = (p_tlv->tlv_type - DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
  1032. p_time = &p_drv_buf->scsi_chk_tstamp[idx];
  1033. return qed_mfw_get_tlv_time_value(p_time, p_buf);
  1034. default:
  1035. break;
  1036. }
  1037. return -1;
  1038. }
  1039. static int
  1040. qed_mfw_get_iscsi_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
  1041. struct qed_mfw_tlv_iscsi *p_drv_buf,
  1042. struct qed_tlv_parsed_buf *p_buf)
  1043. {
  1044. switch (p_tlv->tlv_type) {
  1045. case DRV_TLV_TARGET_LLMNR_ENABLED:
  1046. if (p_drv_buf->target_llmnr_set) {
  1047. p_buf->p_val = &p_drv_buf->target_llmnr;
  1048. return sizeof(p_drv_buf->target_llmnr);
  1049. }
  1050. break;
  1051. case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
  1052. if (p_drv_buf->header_digest_set) {
  1053. p_buf->p_val = &p_drv_buf->header_digest;
  1054. return sizeof(p_drv_buf->header_digest);
  1055. }
  1056. break;
  1057. case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
  1058. if (p_drv_buf->data_digest_set) {
  1059. p_buf->p_val = &p_drv_buf->data_digest;
  1060. return sizeof(p_drv_buf->data_digest);
  1061. }
  1062. break;
  1063. case DRV_TLV_AUTHENTICATION_METHOD:
  1064. if (p_drv_buf->auth_method_set) {
  1065. p_buf->p_val = &p_drv_buf->auth_method;
  1066. return sizeof(p_drv_buf->auth_method);
  1067. }
  1068. break;
  1069. case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
  1070. if (p_drv_buf->boot_taget_portal_set) {
  1071. p_buf->p_val = &p_drv_buf->boot_taget_portal;
  1072. return sizeof(p_drv_buf->boot_taget_portal);
  1073. }
  1074. break;
  1075. case DRV_TLV_MAX_FRAME_SIZE:
  1076. if (p_drv_buf->frame_size_set) {
  1077. p_buf->p_val = &p_drv_buf->frame_size;
  1078. return sizeof(p_drv_buf->frame_size);
  1079. }
  1080. break;
  1081. case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
  1082. if (p_drv_buf->tx_desc_size_set) {
  1083. p_buf->p_val = &p_drv_buf->tx_desc_size;
  1084. return sizeof(p_drv_buf->tx_desc_size);
  1085. }
  1086. break;
  1087. case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
  1088. if (p_drv_buf->rx_desc_size_set) {
  1089. p_buf->p_val = &p_drv_buf->rx_desc_size;
  1090. return sizeof(p_drv_buf->rx_desc_size);
  1091. }
  1092. break;
  1093. case DRV_TLV_ISCSI_BOOT_PROGRESS:
  1094. if (p_drv_buf->boot_progress_set) {
  1095. p_buf->p_val = &p_drv_buf->boot_progress;
  1096. return sizeof(p_drv_buf->boot_progress);
  1097. }
  1098. break;
  1099. case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
  1100. if (p_drv_buf->tx_desc_qdepth_set) {
  1101. p_buf->p_val = &p_drv_buf->tx_desc_qdepth;
  1102. return sizeof(p_drv_buf->tx_desc_qdepth);
  1103. }
  1104. break;
  1105. case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
  1106. if (p_drv_buf->rx_desc_qdepth_set) {
  1107. p_buf->p_val = &p_drv_buf->rx_desc_qdepth;
  1108. return sizeof(p_drv_buf->rx_desc_qdepth);
  1109. }
  1110. break;
  1111. case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
  1112. if (p_drv_buf->rx_frames_set) {
  1113. p_buf->p_val = &p_drv_buf->rx_frames;
  1114. return sizeof(p_drv_buf->rx_frames);
  1115. }
  1116. break;
  1117. case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
  1118. if (p_drv_buf->rx_bytes_set) {
  1119. p_buf->p_val = &p_drv_buf->rx_bytes;
  1120. return sizeof(p_drv_buf->rx_bytes);
  1121. }
  1122. break;
  1123. case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
  1124. if (p_drv_buf->tx_frames_set) {
  1125. p_buf->p_val = &p_drv_buf->tx_frames;
  1126. return sizeof(p_drv_buf->tx_frames);
  1127. }
  1128. break;
  1129. case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
  1130. if (p_drv_buf->tx_bytes_set) {
  1131. p_buf->p_val = &p_drv_buf->tx_bytes;
  1132. return sizeof(p_drv_buf->tx_bytes);
  1133. }
  1134. break;
  1135. default:
  1136. break;
  1137. }
  1138. return -1;
  1139. }
  1140. static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
  1141. u8 tlv_group, u8 *p_mfw_buf, u32 size)
  1142. {
  1143. union qed_mfw_tlv_data *p_tlv_data;
  1144. struct qed_tlv_parsed_buf buffer;
  1145. struct qed_drv_tlv_hdr tlv;
  1146. int len = 0;
  1147. u32 offset;
  1148. u8 *p_tlv;
  1149. p_tlv_data = vzalloc(sizeof(*p_tlv_data));
  1150. if (!p_tlv_data)
  1151. return -ENOMEM;
  1152. if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
  1153. vfree(p_tlv_data);
  1154. return -EINVAL;
  1155. }
  1156. memset(&tlv, 0, sizeof(tlv));
  1157. for (offset = 0; offset < size;
  1158. offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
  1159. p_tlv = &p_mfw_buf[offset];
  1160. tlv.tlv_type = TLV_TYPE(p_tlv);
  1161. tlv.tlv_length = TLV_LENGTH(p_tlv);
  1162. tlv.tlv_flags = TLV_FLAGS(p_tlv);
  1163. DP_VERBOSE(p_hwfn, QED_MSG_SP,
  1164. "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
  1165. tlv.tlv_length, tlv.tlv_flags);
  1166. if (tlv_group == QED_MFW_TLV_GENERIC)
  1167. len = qed_mfw_get_gen_tlv_value(&tlv,
  1168. &p_tlv_data->generic,
  1169. &buffer);
  1170. else if (tlv_group == QED_MFW_TLV_ETH)
  1171. len = qed_mfw_get_eth_tlv_value(&tlv,
  1172. &p_tlv_data->eth,
  1173. &buffer);
  1174. else if (tlv_group == QED_MFW_TLV_FCOE)
  1175. len = qed_mfw_get_fcoe_tlv_value(&tlv,
  1176. &p_tlv_data->fcoe,
  1177. &buffer);
  1178. else
  1179. len = qed_mfw_get_iscsi_tlv_value(&tlv,
  1180. &p_tlv_data->iscsi,
  1181. &buffer);
  1182. if (len > 0) {
  1183. WARN(len > 4 * tlv.tlv_length,
  1184. "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
  1185. len, 4 * tlv.tlv_length);
  1186. len = min_t(int, len, 4 * tlv.tlv_length);
  1187. tlv.tlv_flags |= QED_DRV_TLV_FLAGS_CHANGED;
  1188. TLV_FLAGS(p_tlv) = tlv.tlv_flags;
  1189. memcpy(p_mfw_buf + offset + sizeof(tlv),
  1190. buffer.p_val, len);
  1191. }
  1192. }
  1193. vfree(p_tlv_data);
  1194. return 0;
  1195. }
  1196. int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
  1197. {
  1198. u32 addr, size, offset, resp, param, val, global_offsize, global_addr;
  1199. u8 tlv_group = 0, id, *p_mfw_buf = NULL, *p_temp;
  1200. struct qed_drv_tlv_hdr tlv;
  1201. int rc;
  1202. addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
  1203. PUBLIC_GLOBAL);
  1204. global_offsize = qed_rd(p_hwfn, p_ptt, addr);
  1205. global_addr = SECTION_ADDR(global_offsize, 0);
  1206. addr = global_addr + offsetof(struct public_global, data_ptr);
  1207. addr = qed_rd(p_hwfn, p_ptt, addr);
  1208. size = qed_rd(p_hwfn, p_ptt, global_addr +
  1209. offsetof(struct public_global, data_size));
  1210. if (!size) {
  1211. DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
  1212. goto drv_done;
  1213. }
  1214. p_mfw_buf = vzalloc(size);
  1215. if (!p_mfw_buf) {
  1216. DP_NOTICE(p_hwfn, "Failed allocate memory for p_mfw_buf\n");
  1217. goto drv_done;
  1218. }
  1219. /* Read the TLV request to local buffer. MFW represents the TLV in
  1220. * little endian format and mcp returns it bigendian format. Hence
  1221. * driver need to convert data to little endian first and then do the
  1222. * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
  1223. *
  1224. */
  1225. for (offset = 0; offset < size; offset += sizeof(u32)) {
  1226. val = qed_rd(p_hwfn, p_ptt, addr + offset);
  1227. val = be32_to_cpu(val);
  1228. memcpy(&p_mfw_buf[offset], &val, sizeof(u32));
  1229. }
  1230. /* Parse the headers to enumerate the requested TLV groups */
  1231. for (offset = 0; offset < size;
  1232. offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
  1233. p_temp = &p_mfw_buf[offset];
  1234. tlv.tlv_type = TLV_TYPE(p_temp);
  1235. tlv.tlv_length = TLV_LENGTH(p_temp);
  1236. if (qed_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
  1237. DP_VERBOSE(p_hwfn, NETIF_MSG_DRV,
  1238. "Un recognized TLV %d\n", tlv.tlv_type);
  1239. }
  1240. /* Sanitize the TLV groups according to personality */
  1241. if ((tlv_group & QED_MFW_TLV_ETH) && !QED_IS_L2_PERSONALITY(p_hwfn)) {
  1242. DP_VERBOSE(p_hwfn, QED_MSG_SP,
  1243. "Skipping L2 TLVs for non-L2 function\n");
  1244. tlv_group &= ~QED_MFW_TLV_ETH;
  1245. }
  1246. if ((tlv_group & QED_MFW_TLV_FCOE) &&
  1247. p_hwfn->hw_info.personality != QED_PCI_FCOE) {
  1248. DP_VERBOSE(p_hwfn, QED_MSG_SP,
  1249. "Skipping FCoE TLVs for non-FCoE function\n");
  1250. tlv_group &= ~QED_MFW_TLV_FCOE;
  1251. }
  1252. if ((tlv_group & QED_MFW_TLV_ISCSI) &&
  1253. p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
  1254. DP_VERBOSE(p_hwfn, QED_MSG_SP,
  1255. "Skipping iSCSI TLVs for non-iSCSI function\n");
  1256. tlv_group &= ~QED_MFW_TLV_ISCSI;
  1257. }
  1258. /* Update the TLV values in the local buffer */
  1259. for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
  1260. if (tlv_group & id)
  1261. if (qed_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
  1262. goto drv_done;
  1263. }
  1264. /* Write the TLV data to shared memory. The stream of 4 bytes first need
  1265. * to be mem-copied to u32 element to make it as LSB format. And then
  1266. * converted to big endian as required by mcp-write.
  1267. */
  1268. for (offset = 0; offset < size; offset += sizeof(u32)) {
  1269. memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
  1270. val = cpu_to_be32(val);
  1271. qed_wr(p_hwfn, p_ptt, addr + offset, val);
  1272. }
  1273. drv_done:
  1274. rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
  1275. &param);
  1276. vfree(p_mfw_buf);
  1277. return rc;
  1278. }