be_mgmt.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532
  1. /**
  2. * Copyright (C) 2005 - 2013 Emulex
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation. The full GNU General
  8. * Public License is included in this distribution in the file called COPYING.
  9. *
  10. * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  11. *
  12. * Contact Information:
  13. * linux-drivers@emulex.com
  14. *
  15. * Emulex
  16. * 3333 Susan Street
  17. * Costa Mesa, CA 92626
  18. */
  19. #include <linux/bsg-lib.h>
  20. #include <scsi/scsi_transport_iscsi.h>
  21. #include <scsi/scsi_bsg_iscsi.h>
  22. #include "be_mgmt.h"
  23. #include "be_iscsi.h"
  24. #include "be_main.h"
  25. /* UE Status Low CSR */
  26. static const char * const desc_ue_status_low[] = {
  27. "CEV",
  28. "CTX",
  29. "DBUF",
  30. "ERX",
  31. "Host",
  32. "MPU",
  33. "NDMA",
  34. "PTC ",
  35. "RDMA ",
  36. "RXF ",
  37. "RXIPS ",
  38. "RXULP0 ",
  39. "RXULP1 ",
  40. "RXULP2 ",
  41. "TIM ",
  42. "TPOST ",
  43. "TPRE ",
  44. "TXIPS ",
  45. "TXULP0 ",
  46. "TXULP1 ",
  47. "UC ",
  48. "WDMA ",
  49. "TXULP2 ",
  50. "HOST1 ",
  51. "P0_OB_LINK ",
  52. "P1_OB_LINK ",
  53. "HOST_GPIO ",
  54. "MBOX ",
  55. "AXGMAC0",
  56. "AXGMAC1",
  57. "JTAG",
  58. "MPU_INTPEND"
  59. };
  60. /* UE Status High CSR */
  61. static const char * const desc_ue_status_hi[] = {
  62. "LPCMEMHOST",
  63. "MGMT_MAC",
  64. "PCS0ONLINE",
  65. "MPU_IRAM",
  66. "PCS1ONLINE",
  67. "PCTL0",
  68. "PCTL1",
  69. "PMEM",
  70. "RR",
  71. "TXPB",
  72. "RXPP",
  73. "XAUI",
  74. "TXP",
  75. "ARM",
  76. "IPC",
  77. "HOST2",
  78. "HOST3",
  79. "HOST4",
  80. "HOST5",
  81. "HOST6",
  82. "HOST7",
  83. "HOST8",
  84. "HOST9",
  85. "NETC",
  86. "Unknown",
  87. "Unknown",
  88. "Unknown",
  89. "Unknown",
  90. "Unknown",
  91. "Unknown",
  92. "Unknown",
  93. "Unknown"
  94. };
  95. /*
  96. * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
  97. * @phba: Driver priv structure
  98. *
  99. * Read registers linked to UE and check for the UE status
  100. **/
  101. void beiscsi_ue_detect(struct beiscsi_hba *phba)
  102. {
  103. uint32_t ue_hi = 0, ue_lo = 0;
  104. uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
  105. uint8_t i = 0;
  106. if (phba->ue_detected)
  107. return;
  108. pci_read_config_dword(phba->pcidev,
  109. PCICFG_UE_STATUS_LOW, &ue_lo);
  110. pci_read_config_dword(phba->pcidev,
  111. PCICFG_UE_STATUS_MASK_LOW,
  112. &ue_mask_lo);
  113. pci_read_config_dword(phba->pcidev,
  114. PCICFG_UE_STATUS_HIGH,
  115. &ue_hi);
  116. pci_read_config_dword(phba->pcidev,
  117. PCICFG_UE_STATUS_MASK_HI,
  118. &ue_mask_hi);
  119. ue_lo = (ue_lo & ~ue_mask_lo);
  120. ue_hi = (ue_hi & ~ue_mask_hi);
  121. if (ue_lo || ue_hi) {
  122. phba->ue_detected = true;
  123. beiscsi_log(phba, KERN_ERR,
  124. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  125. "BG_%d : Error detected on the adapter\n");
  126. }
  127. if (ue_lo) {
  128. for (i = 0; ue_lo; ue_lo >>= 1, i++) {
  129. if (ue_lo & 1)
  130. beiscsi_log(phba, KERN_ERR,
  131. BEISCSI_LOG_CONFIG,
  132. "BG_%d : UE_LOW %s bit set\n",
  133. desc_ue_status_low[i]);
  134. }
  135. }
  136. if (ue_hi) {
  137. for (i = 0; ue_hi; ue_hi >>= 1, i++) {
  138. if (ue_hi & 1)
  139. beiscsi_log(phba, KERN_ERR,
  140. BEISCSI_LOG_CONFIG,
  141. "BG_%d : UE_HIGH %s bit set\n",
  142. desc_ue_status_hi[i]);
  143. }
  144. }
  145. }
  146. /**
  147. * mgmt_reopen_session()- Reopen a session based on reopen_type
  148. * @phba: Device priv structure instance
  149. * @reopen_type: Type of reopen_session FW should do.
  150. * @sess_handle: Session Handle of the session to be re-opened
  151. *
  152. * return
  153. * the TAG used for MBOX Command
  154. *
  155. **/
  156. unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
  157. unsigned int reopen_type,
  158. unsigned int sess_handle)
  159. {
  160. struct be_ctrl_info *ctrl = &phba->ctrl;
  161. struct be_mcc_wrb *wrb;
  162. struct be_cmd_reopen_session_req *req;
  163. unsigned int tag = 0;
  164. beiscsi_log(phba, KERN_INFO,
  165. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  166. "BG_%d : In bescsi_get_boot_target\n");
  167. spin_lock(&ctrl->mbox_lock);
  168. tag = alloc_mcc_tag(phba);
  169. if (!tag) {
  170. spin_unlock(&ctrl->mbox_lock);
  171. return tag;
  172. }
  173. wrb = wrb_from_mccq(phba);
  174. req = embedded_payload(wrb);
  175. wrb->tag0 |= tag;
  176. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  177. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  178. OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
  179. sizeof(struct be_cmd_reopen_session_resp));
  180. /* set the reopen_type,sess_handle */
  181. req->reopen_type = reopen_type;
  182. req->session_handle = sess_handle;
  183. be_mcc_notify(phba);
  184. spin_unlock(&ctrl->mbox_lock);
  185. return tag;
  186. }
  187. unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
  188. {
  189. struct be_ctrl_info *ctrl = &phba->ctrl;
  190. struct be_mcc_wrb *wrb;
  191. struct be_cmd_get_boot_target_req *req;
  192. unsigned int tag = 0;
  193. beiscsi_log(phba, KERN_INFO,
  194. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  195. "BG_%d : In bescsi_get_boot_target\n");
  196. spin_lock(&ctrl->mbox_lock);
  197. tag = alloc_mcc_tag(phba);
  198. if (!tag) {
  199. spin_unlock(&ctrl->mbox_lock);
  200. return tag;
  201. }
  202. wrb = wrb_from_mccq(phba);
  203. req = embedded_payload(wrb);
  204. wrb->tag0 |= tag;
  205. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  206. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  207. OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
  208. sizeof(struct be_cmd_get_boot_target_resp));
  209. be_mcc_notify(phba);
  210. spin_unlock(&ctrl->mbox_lock);
  211. return tag;
  212. }
  213. unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
  214. u32 boot_session_handle,
  215. struct be_dma_mem *nonemb_cmd)
  216. {
  217. struct be_ctrl_info *ctrl = &phba->ctrl;
  218. struct be_mcc_wrb *wrb;
  219. unsigned int tag = 0;
  220. struct be_cmd_get_session_req *req;
  221. struct be_cmd_get_session_resp *resp;
  222. struct be_sge *sge;
  223. beiscsi_log(phba, KERN_INFO,
  224. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  225. "BG_%d : In beiscsi_get_session_info\n");
  226. spin_lock(&ctrl->mbox_lock);
  227. tag = alloc_mcc_tag(phba);
  228. if (!tag) {
  229. spin_unlock(&ctrl->mbox_lock);
  230. return tag;
  231. }
  232. nonemb_cmd->size = sizeof(*resp);
  233. req = nonemb_cmd->va;
  234. memset(req, 0, sizeof(*req));
  235. wrb = wrb_from_mccq(phba);
  236. sge = nonembedded_sgl(wrb);
  237. wrb->tag0 |= tag;
  238. wrb->tag0 |= tag;
  239. be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
  240. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  241. OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
  242. sizeof(*resp));
  243. req->session_handle = boot_session_handle;
  244. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  245. sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  246. sge->len = cpu_to_le32(nonemb_cmd->size);
  247. be_mcc_notify(phba);
  248. spin_unlock(&ctrl->mbox_lock);
  249. return tag;
  250. }
  251. /**
  252. * mgmt_get_fw_config()- Get the FW config for the function
  253. * @ctrl: ptr to Ctrl Info
  254. * @phba: ptr to the dev priv structure
  255. *
  256. * Get the FW config and resources available for the function.
  257. * The resources are created based on the count received here.
  258. *
  259. * return
  260. * Success: 0
  261. * Failure: Non-Zero Value
  262. **/
  263. int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
  264. struct beiscsi_hba *phba)
  265. {
  266. struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
  267. struct be_fw_cfg *req = embedded_payload(wrb);
  268. int status = 0;
  269. spin_lock(&ctrl->mbox_lock);
  270. memset(wrb, 0, sizeof(*wrb));
  271. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  272. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
  273. OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
  274. EMBED_MBX_MAX_PAYLOAD_SIZE);
  275. status = be_mbox_notify(ctrl);
  276. if (!status) {
  277. uint8_t ulp_num = 0;
  278. struct be_fw_cfg *pfw_cfg;
  279. pfw_cfg = req;
  280. for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
  281. if (pfw_cfg->ulp[ulp_num].ulp_mode &
  282. BEISCSI_ULP_ISCSI_INI_MODE)
  283. set_bit(ulp_num,
  284. &phba->fw_config.ulp_supported);
  285. phba->fw_config.phys_port = pfw_cfg->phys_port;
  286. for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
  287. if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
  288. phba->fw_config.iscsi_cid_start[ulp_num] =
  289. pfw_cfg->ulp[ulp_num].sq_base;
  290. phba->fw_config.iscsi_cid_count[ulp_num] =
  291. pfw_cfg->ulp[ulp_num].sq_count;
  292. phba->fw_config.iscsi_icd_start[ulp_num] =
  293. pfw_cfg->ulp[ulp_num].icd_base;
  294. phba->fw_config.iscsi_icd_count[ulp_num] =
  295. pfw_cfg->ulp[ulp_num].icd_count;
  296. phba->fw_config.iscsi_chain_start[ulp_num] =
  297. pfw_cfg->chain_icd[ulp_num].chain_base;
  298. phba->fw_config.iscsi_chain_count[ulp_num] =
  299. pfw_cfg->chain_icd[ulp_num].chain_count;
  300. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
  301. "BG_%d : Function loaded on ULP : %d\n"
  302. "\tiscsi_cid_count : %d\n"
  303. "\t iscsi_icd_count : %d\n",
  304. ulp_num,
  305. phba->fw_config.
  306. iscsi_cid_count[ulp_num],
  307. phba->fw_config.
  308. iscsi_icd_count[ulp_num]);
  309. }
  310. }
  311. phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
  312. BEISCSI_FUNC_DUA_MODE);
  313. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
  314. "BG_%d : DUA Mode : 0x%x\n",
  315. phba->fw_config.dual_ulp_aware);
  316. } else {
  317. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
  318. "BG_%d : Failed in mgmt_get_fw_config\n");
  319. status = -EINVAL;
  320. }
  321. spin_unlock(&ctrl->mbox_lock);
  322. return status;
  323. }
  324. int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
  325. struct beiscsi_hba *phba)
  326. {
  327. struct be_dma_mem nonemb_cmd;
  328. struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
  329. struct be_mgmt_controller_attributes *req;
  330. struct be_sge *sge = nonembedded_sgl(wrb);
  331. int status = 0;
  332. nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
  333. sizeof(struct be_mgmt_controller_attributes),
  334. &nonemb_cmd.dma);
  335. if (nonemb_cmd.va == NULL) {
  336. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
  337. "BG_%d : Failed to allocate memory for "
  338. "mgmt_check_supported_fw\n");
  339. return -ENOMEM;
  340. }
  341. nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
  342. req = nonemb_cmd.va;
  343. memset(req, 0, sizeof(*req));
  344. spin_lock(&ctrl->mbox_lock);
  345. memset(wrb, 0, sizeof(*wrb));
  346. be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
  347. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
  348. OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
  349. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
  350. sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
  351. sge->len = cpu_to_le32(nonemb_cmd.size);
  352. status = be_mbox_notify(ctrl);
  353. if (!status) {
  354. struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
  355. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
  356. "BG_%d : Firmware Version of CMD : %s\n"
  357. "Firmware Version is : %s\n"
  358. "Developer Build, not performing version check...\n",
  359. resp->params.hba_attribs
  360. .flashrom_version_string,
  361. resp->params.hba_attribs.
  362. firmware_version_string);
  363. phba->fw_config.iscsi_features =
  364. resp->params.hba_attribs.iscsi_features;
  365. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
  366. "BM_%d : phba->fw_config.iscsi_features = %d\n",
  367. phba->fw_config.iscsi_features);
  368. memcpy(phba->fw_ver_str, resp->params.hba_attribs.
  369. firmware_version_string, BEISCSI_VER_STRLEN);
  370. } else
  371. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
  372. "BG_%d : Failed in mgmt_check_supported_fw\n");
  373. spin_unlock(&ctrl->mbox_lock);
  374. if (nonemb_cmd.va)
  375. pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
  376. nonemb_cmd.va, nonemb_cmd.dma);
  377. return status;
  378. }
  379. unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
  380. struct beiscsi_hba *phba,
  381. struct bsg_job *job,
  382. struct be_dma_mem *nonemb_cmd)
  383. {
  384. struct be_cmd_resp_hdr *resp;
  385. struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
  386. struct be_sge *mcc_sge = nonembedded_sgl(wrb);
  387. unsigned int tag = 0;
  388. struct iscsi_bsg_request *bsg_req = job->request;
  389. struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
  390. unsigned short region, sector_size, sector, offset;
  391. nonemb_cmd->size = job->request_payload.payload_len;
  392. memset(nonemb_cmd->va, 0, nonemb_cmd->size);
  393. resp = nonemb_cmd->va;
  394. region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
  395. sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
  396. sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
  397. offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
  398. req->region = region;
  399. req->sector = sector;
  400. req->offset = offset;
  401. spin_lock(&ctrl->mbox_lock);
  402. memset(wrb, 0, sizeof(*wrb));
  403. switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
  404. case BEISCSI_WRITE_FLASH:
  405. offset = sector * sector_size + offset;
  406. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  407. OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
  408. sg_copy_to_buffer(job->request_payload.sg_list,
  409. job->request_payload.sg_cnt,
  410. nonemb_cmd->va + offset, job->request_len);
  411. break;
  412. case BEISCSI_READ_FLASH:
  413. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  414. OPCODE_COMMON_READ_FLASH, sizeof(*req));
  415. break;
  416. default:
  417. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  418. "BG_%d : Unsupported cmd = 0x%x\n\n",
  419. bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
  420. spin_unlock(&ctrl->mbox_lock);
  421. return -ENOSYS;
  422. }
  423. tag = alloc_mcc_tag(phba);
  424. if (!tag) {
  425. spin_unlock(&ctrl->mbox_lock);
  426. return tag;
  427. }
  428. be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
  429. job->request_payload.sg_cnt);
  430. mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  431. mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  432. mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
  433. wrb->tag0 |= tag;
  434. be_mcc_notify(phba);
  435. spin_unlock(&ctrl->mbox_lock);
  436. return tag;
  437. }
  438. int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
  439. {
  440. struct be_ctrl_info *ctrl = &phba->ctrl;
  441. struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
  442. struct iscsi_cleanup_req *req = embedded_payload(wrb);
  443. int status = 0;
  444. spin_lock(&ctrl->mbox_lock);
  445. memset(wrb, 0, sizeof(*wrb));
  446. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  447. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  448. OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
  449. req->chute = chute;
  450. req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, 0));
  451. req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, 0));
  452. status = be_mcc_notify_wait(phba);
  453. if (status)
  454. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
  455. "BG_%d : mgmt_epfw_cleanup , FAILED\n");
  456. spin_unlock(&ctrl->mbox_lock);
  457. return status;
  458. }
  459. unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
  460. struct invalidate_command_table *inv_tbl,
  461. unsigned int num_invalidate, unsigned int cid,
  462. struct be_dma_mem *nonemb_cmd)
  463. {
  464. struct be_ctrl_info *ctrl = &phba->ctrl;
  465. struct be_mcc_wrb *wrb;
  466. struct be_sge *sge;
  467. struct invalidate_commands_params_in *req;
  468. unsigned int i, tag = 0;
  469. spin_lock(&ctrl->mbox_lock);
  470. tag = alloc_mcc_tag(phba);
  471. if (!tag) {
  472. spin_unlock(&ctrl->mbox_lock);
  473. return tag;
  474. }
  475. req = nonemb_cmd->va;
  476. memset(req, 0, sizeof(*req));
  477. wrb = wrb_from_mccq(phba);
  478. sge = nonembedded_sgl(wrb);
  479. wrb->tag0 |= tag;
  480. be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
  481. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  482. OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
  483. sizeof(*req));
  484. req->ref_handle = 0;
  485. req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
  486. for (i = 0; i < num_invalidate; i++) {
  487. req->table[i].icd = inv_tbl->icd;
  488. req->table[i].cid = inv_tbl->cid;
  489. req->icd_count++;
  490. inv_tbl++;
  491. }
  492. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  493. sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  494. sge->len = cpu_to_le32(nonemb_cmd->size);
  495. be_mcc_notify(phba);
  496. spin_unlock(&ctrl->mbox_lock);
  497. return tag;
  498. }
  499. unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
  500. struct beiscsi_endpoint *beiscsi_ep,
  501. unsigned short cid,
  502. unsigned short issue_reset,
  503. unsigned short savecfg_flag)
  504. {
  505. struct be_ctrl_info *ctrl = &phba->ctrl;
  506. struct be_mcc_wrb *wrb;
  507. struct iscsi_invalidate_connection_params_in *req;
  508. unsigned int tag = 0;
  509. spin_lock(&ctrl->mbox_lock);
  510. tag = alloc_mcc_tag(phba);
  511. if (!tag) {
  512. spin_unlock(&ctrl->mbox_lock);
  513. return tag;
  514. }
  515. wrb = wrb_from_mccq(phba);
  516. wrb->tag0 |= tag;
  517. req = embedded_payload(wrb);
  518. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  519. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  520. OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
  521. sizeof(*req));
  522. req->session_handle = beiscsi_ep->fw_handle;
  523. req->cid = cid;
  524. if (issue_reset)
  525. req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
  526. else
  527. req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
  528. req->save_cfg = savecfg_flag;
  529. be_mcc_notify(phba);
  530. spin_unlock(&ctrl->mbox_lock);
  531. return tag;
  532. }
  533. unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
  534. unsigned short cid, unsigned int upload_flag)
  535. {
  536. struct be_ctrl_info *ctrl = &phba->ctrl;
  537. struct be_mcc_wrb *wrb;
  538. struct tcp_upload_params_in *req;
  539. unsigned int tag = 0;
  540. spin_lock(&ctrl->mbox_lock);
  541. tag = alloc_mcc_tag(phba);
  542. if (!tag) {
  543. spin_unlock(&ctrl->mbox_lock);
  544. return tag;
  545. }
  546. wrb = wrb_from_mccq(phba);
  547. req = embedded_payload(wrb);
  548. wrb->tag0 |= tag;
  549. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  550. be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
  551. OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
  552. req->id = (unsigned short)cid;
  553. req->upload_type = (unsigned char)upload_flag;
  554. be_mcc_notify(phba);
  555. spin_unlock(&ctrl->mbox_lock);
  556. return tag;
  557. }
  558. int mgmt_open_connection(struct beiscsi_hba *phba,
  559. struct sockaddr *dst_addr,
  560. struct beiscsi_endpoint *beiscsi_ep,
  561. struct be_dma_mem *nonemb_cmd)
  562. {
  563. struct hwi_controller *phwi_ctrlr;
  564. struct hwi_context_memory *phwi_context;
  565. struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
  566. struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
  567. struct be_ctrl_info *ctrl = &phba->ctrl;
  568. struct be_mcc_wrb *wrb;
  569. struct tcp_connect_and_offload_in *req;
  570. unsigned short def_hdr_id;
  571. unsigned short def_data_id;
  572. struct phys_addr template_address = { 0, 0 };
  573. struct phys_addr *ptemplate_address;
  574. unsigned int tag = 0;
  575. unsigned int i;
  576. unsigned short cid = beiscsi_ep->ep_cid;
  577. struct be_sge *sge;
  578. phwi_ctrlr = phba->phwi_ctrlr;
  579. phwi_context = phwi_ctrlr->phwi_ctxt;
  580. def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, 0);
  581. def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, 0);
  582. ptemplate_address = &template_address;
  583. ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
  584. spin_lock(&ctrl->mbox_lock);
  585. tag = alloc_mcc_tag(phba);
  586. if (!tag) {
  587. spin_unlock(&ctrl->mbox_lock);
  588. return tag;
  589. }
  590. wrb = wrb_from_mccq(phba);
  591. memset(wrb, 0, sizeof(*wrb));
  592. sge = nonembedded_sgl(wrb);
  593. req = nonemb_cmd->va;
  594. memset(req, 0, sizeof(*req));
  595. wrb->tag0 |= tag;
  596. be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
  597. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  598. OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
  599. sizeof(*req));
  600. if (dst_addr->sa_family == PF_INET) {
  601. __be32 s_addr = daddr_in->sin_addr.s_addr;
  602. req->ip_address.ip_type = BE2_IPV4;
  603. req->ip_address.addr[0] = s_addr & 0x000000ff;
  604. req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
  605. req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
  606. req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
  607. req->tcp_port = ntohs(daddr_in->sin_port);
  608. beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
  609. beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
  610. beiscsi_ep->ip_type = BE2_IPV4;
  611. } else if (dst_addr->sa_family == PF_INET6) {
  612. req->ip_address.ip_type = BE2_IPV6;
  613. memcpy(&req->ip_address.addr,
  614. &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
  615. req->tcp_port = ntohs(daddr_in6->sin6_port);
  616. beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
  617. memcpy(&beiscsi_ep->dst6_addr,
  618. &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
  619. beiscsi_ep->ip_type = BE2_IPV6;
  620. } else{
  621. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
  622. "BG_%d : unknown addr family %d\n",
  623. dst_addr->sa_family);
  624. spin_unlock(&ctrl->mbox_lock);
  625. free_mcc_tag(&phba->ctrl, tag);
  626. return -EINVAL;
  627. }
  628. req->cid = cid;
  629. i = phba->nxt_cqid++;
  630. if (phba->nxt_cqid == phba->num_cpus)
  631. phba->nxt_cqid = 0;
  632. req->cq_id = phwi_context->be_cq[i].id;
  633. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  634. "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
  635. req->defq_id = def_hdr_id;
  636. req->hdr_ring_id = def_hdr_id;
  637. req->data_ring_id = def_data_id;
  638. req->do_offload = 1;
  639. req->dataout_template_pa.lo = ptemplate_address->lo;
  640. req->dataout_template_pa.hi = ptemplate_address->hi;
  641. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  642. sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  643. sge->len = cpu_to_le32(nonemb_cmd->size);
  644. be_mcc_notify(phba);
  645. spin_unlock(&ctrl->mbox_lock);
  646. return tag;
  647. }
  648. unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
  649. {
  650. struct be_ctrl_info *ctrl = &phba->ctrl;
  651. struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
  652. struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
  653. struct be_cmd_get_all_if_id_req *pbe_allid = req;
  654. int status = 0;
  655. memset(wrb, 0, sizeof(*wrb));
  656. spin_lock(&ctrl->mbox_lock);
  657. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  658. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  659. OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
  660. sizeof(*req));
  661. status = be_mbox_notify(ctrl);
  662. if (!status)
  663. phba->interface_handle = pbe_allid->if_hndl_list[0];
  664. else {
  665. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  666. "BG_%d : Failed in mgmt_get_all_if_id\n");
  667. }
  668. spin_unlock(&ctrl->mbox_lock);
  669. return status;
  670. }
  671. /*
  672. * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
  673. * @phba: Driver priv structure
  674. * @nonemb_cmd: Address of the MBX command issued
  675. * @resp_buf: Buffer to copy the MBX cmd response
  676. * @resp_buf_len: respone lenght to be copied
  677. *
  678. **/
  679. static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
  680. struct be_dma_mem *nonemb_cmd, void *resp_buf,
  681. int resp_buf_len)
  682. {
  683. struct be_ctrl_info *ctrl = &phba->ctrl;
  684. struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
  685. struct be_sge *sge;
  686. unsigned int tag;
  687. int rc = 0;
  688. spin_lock(&ctrl->mbox_lock);
  689. tag = alloc_mcc_tag(phba);
  690. if (!tag) {
  691. spin_unlock(&ctrl->mbox_lock);
  692. rc = -ENOMEM;
  693. goto free_cmd;
  694. }
  695. memset(wrb, 0, sizeof(*wrb));
  696. wrb->tag0 |= tag;
  697. sge = nonembedded_sgl(wrb);
  698. be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
  699. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  700. sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
  701. sge->len = cpu_to_le32(nonemb_cmd->size);
  702. be_mcc_notify(phba);
  703. spin_unlock(&ctrl->mbox_lock);
  704. rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
  705. if (rc) {
  706. beiscsi_log(phba, KERN_ERR,
  707. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  708. "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
  709. rc = -EIO;
  710. goto free_cmd;
  711. }
  712. if (resp_buf)
  713. memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
  714. free_cmd:
  715. pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
  716. nonemb_cmd->va, nonemb_cmd->dma);
  717. return rc;
  718. }
  719. static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
  720. int iscsi_cmd, int size)
  721. {
  722. cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
  723. if (!cmd->va) {
  724. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
  725. "BG_%d : Failed to allocate memory for if info\n");
  726. return -ENOMEM;
  727. }
  728. memset(cmd->va, 0, size);
  729. cmd->size = size;
  730. be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
  731. return 0;
  732. }
  733. static int
  734. mgmt_static_ip_modify(struct beiscsi_hba *phba,
  735. struct be_cmd_get_if_info_resp *if_info,
  736. struct iscsi_iface_param_info *ip_param,
  737. struct iscsi_iface_param_info *subnet_param,
  738. uint32_t ip_action)
  739. {
  740. struct be_cmd_set_ip_addr_req *req;
  741. struct be_dma_mem nonemb_cmd;
  742. uint32_t ip_type;
  743. int rc;
  744. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  745. OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
  746. sizeof(*req));
  747. if (rc)
  748. return rc;
  749. ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
  750. BE2_IPV6 : BE2_IPV4 ;
  751. req = nonemb_cmd.va;
  752. req->ip_params.record_entry_count = 1;
  753. req->ip_params.ip_record.action = ip_action;
  754. req->ip_params.ip_record.interface_hndl =
  755. phba->interface_handle;
  756. req->ip_params.ip_record.ip_addr.size_of_structure =
  757. sizeof(struct be_ip_addr_subnet_format);
  758. req->ip_params.ip_record.ip_addr.ip_type = ip_type;
  759. if (ip_action == IP_ACTION_ADD) {
  760. memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
  761. ip_param->len);
  762. if (subnet_param)
  763. memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
  764. subnet_param->value, subnet_param->len);
  765. } else {
  766. memcpy(req->ip_params.ip_record.ip_addr.addr,
  767. if_info->ip_addr.addr, ip_param->len);
  768. memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
  769. if_info->ip_addr.subnet_mask, ip_param->len);
  770. }
  771. rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
  772. if (rc < 0)
  773. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  774. "BG_%d : Failed to Modify existing IP Address\n");
  775. return rc;
  776. }
  777. static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
  778. uint32_t gtway_action, uint32_t param_len)
  779. {
  780. struct be_cmd_set_def_gateway_req *req;
  781. struct be_dma_mem nonemb_cmd;
  782. int rt_val;
  783. rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  784. OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
  785. sizeof(*req));
  786. if (rt_val)
  787. return rt_val;
  788. req = nonemb_cmd.va;
  789. req->action = gtway_action;
  790. req->ip_addr.ip_type = BE2_IPV4;
  791. memcpy(req->ip_addr.addr, gt_addr, param_len);
  792. return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
  793. }
  794. int mgmt_set_ip(struct beiscsi_hba *phba,
  795. struct iscsi_iface_param_info *ip_param,
  796. struct iscsi_iface_param_info *subnet_param,
  797. uint32_t boot_proto)
  798. {
  799. struct be_cmd_get_def_gateway_resp gtway_addr_set;
  800. struct be_cmd_get_if_info_resp if_info;
  801. struct be_cmd_set_dhcp_req *dhcpreq;
  802. struct be_cmd_rel_dhcp_req *reldhcp;
  803. struct be_dma_mem nonemb_cmd;
  804. uint8_t *gtway_addr;
  805. uint32_t ip_type;
  806. int rc;
  807. if (mgmt_get_all_if_id(phba))
  808. return -EIO;
  809. memset(&if_info, 0, sizeof(if_info));
  810. ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
  811. BE2_IPV6 : BE2_IPV4 ;
  812. rc = mgmt_get_if_info(phba, ip_type, &if_info);
  813. if (rc)
  814. return rc;
  815. if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
  816. if (if_info.dhcp_state) {
  817. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  818. "BG_%d : DHCP Already Enabled\n");
  819. return 0;
  820. }
  821. /* The ip_param->len is 1 in DHCP case. Setting
  822. proper IP len as this it is used while
  823. freeing the Static IP.
  824. */
  825. ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
  826. IP_V6_LEN : IP_V4_LEN;
  827. } else {
  828. if (if_info.dhcp_state) {
  829. memset(&if_info, 0, sizeof(if_info));
  830. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  831. OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
  832. sizeof(*reldhcp));
  833. if (rc)
  834. return rc;
  835. reldhcp = nonemb_cmd.va;
  836. reldhcp->interface_hndl = phba->interface_handle;
  837. reldhcp->ip_type = ip_type;
  838. rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
  839. if (rc < 0) {
  840. beiscsi_log(phba, KERN_WARNING,
  841. BEISCSI_LOG_CONFIG,
  842. "BG_%d : Failed to Delete existing dhcp\n");
  843. return rc;
  844. }
  845. }
  846. }
  847. /* Delete the Static IP Set */
  848. if (if_info.ip_addr.addr[0]) {
  849. rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL,
  850. IP_ACTION_DEL);
  851. if (rc)
  852. return rc;
  853. }
  854. /* Delete the Gateway settings if mode change is to DHCP */
  855. if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
  856. memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
  857. rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
  858. if (rc) {
  859. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  860. "BG_%d : Failed to Get Gateway Addr\n");
  861. return rc;
  862. }
  863. if (gtway_addr_set.ip_addr.addr[0]) {
  864. gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
  865. rc = mgmt_modify_gateway(phba, gtway_addr,
  866. IP_ACTION_DEL, IP_V4_LEN);
  867. if (rc) {
  868. beiscsi_log(phba, KERN_WARNING,
  869. BEISCSI_LOG_CONFIG,
  870. "BG_%d : Failed to clear Gateway Addr Set\n");
  871. return rc;
  872. }
  873. }
  874. }
  875. /* Set Adapter to DHCP/Static Mode */
  876. if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
  877. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  878. OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
  879. sizeof(*dhcpreq));
  880. if (rc)
  881. return rc;
  882. dhcpreq = nonemb_cmd.va;
  883. dhcpreq->flags = BLOCKING;
  884. dhcpreq->retry_count = 1;
  885. dhcpreq->interface_hndl = phba->interface_handle;
  886. dhcpreq->ip_type = BE2_DHCP_V4;
  887. return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
  888. } else {
  889. return mgmt_static_ip_modify(phba, &if_info, ip_param,
  890. subnet_param, IP_ACTION_ADD);
  891. }
  892. return rc;
  893. }
  894. int mgmt_set_gateway(struct beiscsi_hba *phba,
  895. struct iscsi_iface_param_info *gateway_param)
  896. {
  897. struct be_cmd_get_def_gateway_resp gtway_addr_set;
  898. uint8_t *gtway_addr;
  899. int rt_val;
  900. memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
  901. rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
  902. if (rt_val) {
  903. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  904. "BG_%d : Failed to Get Gateway Addr\n");
  905. return rt_val;
  906. }
  907. if (gtway_addr_set.ip_addr.addr[0]) {
  908. gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
  909. rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
  910. gateway_param->len);
  911. if (rt_val) {
  912. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  913. "BG_%d : Failed to clear Gateway Addr Set\n");
  914. return rt_val;
  915. }
  916. }
  917. gtway_addr = (uint8_t *)&gateway_param->value;
  918. rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
  919. gateway_param->len);
  920. if (rt_val)
  921. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  922. "BG_%d : Failed to Set Gateway Addr\n");
  923. return rt_val;
  924. }
  925. int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
  926. struct be_cmd_get_def_gateway_resp *gateway)
  927. {
  928. struct be_cmd_get_def_gateway_req *req;
  929. struct be_dma_mem nonemb_cmd;
  930. int rc;
  931. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  932. OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
  933. sizeof(*gateway));
  934. if (rc)
  935. return rc;
  936. req = nonemb_cmd.va;
  937. req->ip_type = ip_type;
  938. return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
  939. sizeof(*gateway));
  940. }
  941. int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
  942. struct be_cmd_get_if_info_resp *if_info)
  943. {
  944. struct be_cmd_get_if_info_req *req;
  945. struct be_dma_mem nonemb_cmd;
  946. int rc;
  947. if (mgmt_get_all_if_id(phba))
  948. return -EIO;
  949. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  950. OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
  951. sizeof(*if_info));
  952. if (rc)
  953. return rc;
  954. req = nonemb_cmd.va;
  955. req->interface_hndl = phba->interface_handle;
  956. req->ip_type = ip_type;
  957. return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info,
  958. sizeof(*if_info));
  959. }
  960. int mgmt_get_nic_conf(struct beiscsi_hba *phba,
  961. struct be_cmd_get_nic_conf_resp *nic)
  962. {
  963. struct be_dma_mem nonemb_cmd;
  964. int rc;
  965. rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
  966. OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
  967. sizeof(*nic));
  968. if (rc)
  969. return rc;
  970. return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
  971. }
  972. unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
  973. {
  974. unsigned int tag = 0;
  975. struct be_mcc_wrb *wrb;
  976. struct be_cmd_hba_name *req;
  977. struct be_ctrl_info *ctrl = &phba->ctrl;
  978. spin_lock(&ctrl->mbox_lock);
  979. tag = alloc_mcc_tag(phba);
  980. if (!tag) {
  981. spin_unlock(&ctrl->mbox_lock);
  982. return tag;
  983. }
  984. wrb = wrb_from_mccq(phba);
  985. req = embedded_payload(wrb);
  986. wrb->tag0 |= tag;
  987. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  988. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  989. OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
  990. sizeof(*req));
  991. be_mcc_notify(phba);
  992. spin_unlock(&ctrl->mbox_lock);
  993. return tag;
  994. }
  995. unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
  996. {
  997. unsigned int tag = 0;
  998. struct be_mcc_wrb *wrb;
  999. struct be_cmd_ntwk_link_status_req *req;
  1000. struct be_ctrl_info *ctrl = &phba->ctrl;
  1001. spin_lock(&ctrl->mbox_lock);
  1002. tag = alloc_mcc_tag(phba);
  1003. if (!tag) {
  1004. spin_unlock(&ctrl->mbox_lock);
  1005. return tag;
  1006. }
  1007. wrb = wrb_from_mccq(phba);
  1008. req = embedded_payload(wrb);
  1009. wrb->tag0 |= tag;
  1010. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  1011. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
  1012. OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
  1013. sizeof(*req));
  1014. be_mcc_notify(phba);
  1015. spin_unlock(&ctrl->mbox_lock);
  1016. return tag;
  1017. }
  1018. /**
  1019. * be_mgmt_get_boot_shandle()- Get the session handle
  1020. * @phba: device priv structure instance
  1021. * @s_handle: session handle returned for boot session.
  1022. *
  1023. * Get the boot target session handle. In case of
  1024. * crashdump mode driver has to issue and MBX Cmd
  1025. * for FW to login to boot target
  1026. *
  1027. * return
  1028. * Success: 0
  1029. * Failure: Non-Zero value
  1030. *
  1031. **/
  1032. int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
  1033. unsigned int *s_handle)
  1034. {
  1035. struct be_cmd_get_boot_target_resp *boot_resp;
  1036. struct be_mcc_wrb *wrb;
  1037. unsigned int tag;
  1038. uint8_t boot_retry = 3;
  1039. int rc;
  1040. do {
  1041. /* Get the Boot Target Session Handle and Count*/
  1042. tag = mgmt_get_boot_target(phba);
  1043. if (!tag) {
  1044. beiscsi_log(phba, KERN_ERR,
  1045. BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
  1046. "BG_%d : Getting Boot Target Info Failed\n");
  1047. return -EAGAIN;
  1048. }
  1049. rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
  1050. if (rc) {
  1051. beiscsi_log(phba, KERN_ERR,
  1052. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  1053. "BG_%d : MBX CMD get_boot_target Failed\n");
  1054. return -EBUSY;
  1055. }
  1056. boot_resp = embedded_payload(wrb);
  1057. /* Check if the there are any Boot targets configured */
  1058. if (!boot_resp->boot_session_count) {
  1059. beiscsi_log(phba, KERN_INFO,
  1060. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  1061. "BG_%d ;No boot targets configured\n");
  1062. return -ENXIO;
  1063. }
  1064. /* FW returns the session handle of the boot session */
  1065. if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
  1066. *s_handle = boot_resp->boot_session_handle;
  1067. return 0;
  1068. }
  1069. /* Issue MBX Cmd to FW to login to the boot target */
  1070. tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
  1071. INVALID_SESS_HANDLE);
  1072. if (!tag) {
  1073. beiscsi_log(phba, KERN_ERR,
  1074. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  1075. "BG_%d : mgmt_reopen_session Failed\n");
  1076. return -EAGAIN;
  1077. }
  1078. rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
  1079. if (rc) {
  1080. beiscsi_log(phba, KERN_ERR,
  1081. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  1082. "BG_%d : mgmt_reopen_session Failed");
  1083. return rc;
  1084. }
  1085. } while (--boot_retry);
  1086. /* Couldn't log into the boot target */
  1087. beiscsi_log(phba, KERN_ERR,
  1088. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  1089. "BG_%d : Login to Boot Target Failed\n");
  1090. return -ENXIO;
  1091. }
  1092. /**
  1093. * mgmt_set_vlan()- Issue and wait for CMD completion
  1094. * @phba: device private structure instance
  1095. * @vlan_tag: VLAN tag
  1096. *
  1097. * Issue the MBX Cmd and wait for the completion of the
  1098. * command.
  1099. *
  1100. * returns
  1101. * Success: 0
  1102. * Failure: Non-Xero Value
  1103. **/
  1104. int mgmt_set_vlan(struct beiscsi_hba *phba,
  1105. uint16_t vlan_tag)
  1106. {
  1107. int rc;
  1108. unsigned int tag;
  1109. struct be_mcc_wrb *wrb = NULL;
  1110. tag = be_cmd_set_vlan(phba, vlan_tag);
  1111. if (!tag) {
  1112. beiscsi_log(phba, KERN_ERR,
  1113. (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
  1114. "BG_%d : VLAN Setting Failed\n");
  1115. return -EBUSY;
  1116. }
  1117. rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
  1118. if (rc) {
  1119. beiscsi_log(phba, KERN_ERR,
  1120. (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
  1121. "BS_%d : VLAN MBX Cmd Failed\n");
  1122. return rc;
  1123. }
  1124. return rc;
  1125. }
  1126. /**
  1127. * beiscsi_drvr_ver_disp()- Display the driver Name and Version
  1128. * @dev: ptr to device not used.
  1129. * @attr: device attribute, not used.
  1130. * @buf: contains formatted text driver name and version
  1131. *
  1132. * return
  1133. * size of the formatted string
  1134. **/
  1135. ssize_t
  1136. beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
  1137. char *buf)
  1138. {
  1139. return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
  1140. }
  1141. /**
  1142. * beiscsi_fw_ver_disp()- Display Firmware Version
  1143. * @dev: ptr to device not used.
  1144. * @attr: device attribute, not used.
  1145. * @buf: contains formatted text Firmware version
  1146. *
  1147. * return
  1148. * size of the formatted string
  1149. **/
  1150. ssize_t
  1151. beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
  1152. char *buf)
  1153. {
  1154. struct Scsi_Host *shost = class_to_shost(dev);
  1155. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1156. return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
  1157. }
  1158. /**
  1159. * beiscsi_active_cid_disp()- Display Sessions Active
  1160. * @dev: ptr to device not used.
  1161. * @attr: device attribute, not used.
  1162. * @buf: contains formatted text Session Count
  1163. *
  1164. * return
  1165. * size of the formatted string
  1166. **/
  1167. ssize_t
  1168. beiscsi_active_cid_disp(struct device *dev, struct device_attribute *attr,
  1169. char *buf)
  1170. {
  1171. struct Scsi_Host *shost = class_to_shost(dev);
  1172. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1173. uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
  1174. for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
  1175. if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
  1176. avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
  1177. total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
  1178. len += snprintf(buf+len, PAGE_SIZE - len,
  1179. "ULP%d : %d\n", ulp_num,
  1180. (total_cids - avlbl_cids));
  1181. } else
  1182. len += snprintf(buf+len, PAGE_SIZE - len,
  1183. "ULP%d : %d\n", ulp_num, 0);
  1184. }
  1185. return len;
  1186. }
  1187. /**
  1188. * beiscsi_adap_family_disp()- Display adapter family.
  1189. * @dev: ptr to device to get priv structure
  1190. * @attr: device attribute, not used.
  1191. * @buf: contains formatted text driver name and version
  1192. *
  1193. * return
  1194. * size of the formatted string
  1195. **/
  1196. ssize_t
  1197. beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
  1198. char *buf)
  1199. {
  1200. uint16_t dev_id = 0;
  1201. struct Scsi_Host *shost = class_to_shost(dev);
  1202. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1203. dev_id = phba->pcidev->device;
  1204. switch (dev_id) {
  1205. case BE_DEVICE_ID1:
  1206. case OC_DEVICE_ID1:
  1207. case OC_DEVICE_ID2:
  1208. return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
  1209. break;
  1210. case BE_DEVICE_ID2:
  1211. case OC_DEVICE_ID3:
  1212. return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
  1213. break;
  1214. case OC_SKH_ID1:
  1215. return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
  1216. break;
  1217. default:
  1218. return snprintf(buf, PAGE_SIZE,
  1219. "Unknown Adapter Family: 0x%x\n", dev_id);
  1220. break;
  1221. }
  1222. }
  1223. void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
  1224. struct wrb_handle *pwrb_handle,
  1225. struct be_mem_descriptor *mem_descr)
  1226. {
  1227. struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
  1228. memset(pwrb, 0, sizeof(*pwrb));
  1229. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1230. max_send_data_segment_length, pwrb,
  1231. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1232. max_send_data_segment_length) / 32]);
  1233. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
  1234. BE_TGT_CTX_UPDT_CMD);
  1235. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1236. first_burst_length,
  1237. pwrb,
  1238. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1239. first_burst_length) / 32]);
  1240. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
  1241. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1242. erl) / 32] & OFFLD_PARAMS_ERL));
  1243. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
  1244. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1245. dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
  1246. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
  1247. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1248. hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
  1249. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
  1250. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1251. ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
  1252. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
  1253. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1254. imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
  1255. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
  1256. pwrb,
  1257. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1258. exp_statsn) / 32] + 1));
  1259. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
  1260. pwrb, pwrb_handle->wrb_index);
  1261. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1262. max_burst_length, pwrb, params->dw[offsetof
  1263. (struct amap_beiscsi_offload_params,
  1264. max_burst_length) / 32]);
  1265. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
  1266. pwrb, pwrb_handle->nxt_wrb_index);
  1267. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1268. session_state, pwrb, 0);
  1269. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
  1270. pwrb, 1);
  1271. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
  1272. pwrb, 0);
  1273. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
  1274. 0);
  1275. mem_descr += ISCSI_MEM_GLOBAL_HEADER;
  1276. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1277. pad_buffer_addr_hi, pwrb,
  1278. mem_descr->mem_array[0].bus_address.u.a32.address_hi);
  1279. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1280. pad_buffer_addr_lo, pwrb,
  1281. mem_descr->mem_array[0].bus_address.u.a32.address_lo);
  1282. }
  1283. void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
  1284. struct wrb_handle *pwrb_handle)
  1285. {
  1286. struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
  1287. memset(pwrb, 0, sizeof(*pwrb));
  1288. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1289. max_burst_length, pwrb, params->dw[offsetof
  1290. (struct amap_beiscsi_offload_params,
  1291. max_burst_length) / 32]);
  1292. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1293. type, pwrb,
  1294. BE_TGT_CTX_UPDT_CMD);
  1295. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1296. ptr2nextwrb,
  1297. pwrb, pwrb_handle->nxt_wrb_index);
  1298. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
  1299. pwrb, pwrb_handle->wrb_index);
  1300. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1301. max_send_data_segment_length, pwrb,
  1302. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1303. max_send_data_segment_length) / 32]);
  1304. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1305. first_burst_length, pwrb,
  1306. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1307. first_burst_length) / 32]);
  1308. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1309. max_recv_dataseg_len, pwrb,
  1310. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1311. max_recv_data_segment_length) / 32]);
  1312. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1313. max_cxns, pwrb, BEISCSI_MAX_CXNS);
  1314. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
  1315. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1316. erl) / 32] & OFFLD_PARAMS_ERL));
  1317. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
  1318. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1319. dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
  1320. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
  1321. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1322. hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
  1323. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1324. ir2t, pwrb,
  1325. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1326. ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
  1327. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
  1328. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1329. imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
  1330. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1331. data_seq_inorder,
  1332. pwrb,
  1333. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1334. data_seq_inorder) / 32] &
  1335. OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
  1336. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1337. pdu_seq_inorder,
  1338. pwrb,
  1339. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1340. pdu_seq_inorder) / 32] &
  1341. OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
  1342. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
  1343. pwrb,
  1344. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1345. max_r2t) / 32] &
  1346. OFFLD_PARAMS_MAX_R2T) >> 8);
  1347. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
  1348. pwrb,
  1349. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1350. exp_statsn) / 32] + 1));
  1351. }