fdmi.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. /*
  2. * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
  3. * All rights reserved
  4. * www.brocade.com
  5. *
  6. * Linux driver for Brocade Fibre Channel Host Bus Adapter.
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License (GPL) Version 2 as
  10. * published by the Free Software Foundation
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. /**
  18. * port_api.c BFA FCS port
  19. */
  20. #include <bfa.h>
  21. #include <bfa_svc.h>
  22. #include "fcs_lport.h"
  23. #include "fcs_rport.h"
  24. #include "lport_priv.h"
  25. #include "fcs_trcmod.h"
  26. #include "fcs_fcxp.h"
  27. #include <fcs/bfa_fcs_fdmi.h>
  28. BFA_TRC_FILE(FCS, FDMI);
  29. #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
  30. /*
  31. * forward declarations
  32. */
  33. static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg,
  34. struct bfa_fcxp_s *fcxp_alloced);
  35. static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg,
  36. struct bfa_fcxp_s *fcxp_alloced);
  37. static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg,
  38. struct bfa_fcxp_s *fcxp_alloced);
  39. static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg,
  40. struct bfa_fcxp_s *fcxp,
  41. void *cbarg,
  42. bfa_status_t req_status,
  43. u32 rsp_len,
  44. u32 resid_len,
  45. struct fchs_s *rsp_fchs);
  46. static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg,
  47. struct bfa_fcxp_s *fcxp,
  48. void *cbarg,
  49. bfa_status_t req_status,
  50. u32 rsp_len,
  51. u32 resid_len,
  52. struct fchs_s *rsp_fchs);
  53. static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg,
  54. struct bfa_fcxp_s *fcxp,
  55. void *cbarg,
  56. bfa_status_t req_status,
  57. u32 rsp_len,
  58. u32 resid_len,
  59. struct fchs_s *rsp_fchs);
  60. static void bfa_fcs_port_fdmi_timeout(void *arg);
  61. static u16 bfa_fcs_port_fdmi_build_rhba_pyld(
  62. struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
  63. static u16 bfa_fcs_port_fdmi_build_rprt_pyld(
  64. struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
  65. static u16 bfa_fcs_port_fdmi_build_rpa_pyld(
  66. struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
  67. static u16 bfa_fcs_port_fdmi_build_portattr_block(
  68. struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
  69. static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
  70. struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
  71. static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
  72. struct bfa_fcs_fdmi_port_attr_s *port_attr);
  73. /**
  74. * fcs_fdmi_sm FCS FDMI state machine
  75. */
  76. /**
  77. * FDMI State Machine events
  78. */
  79. enum port_fdmi_event {
  80. FDMISM_EVENT_PORT_ONLINE = 1,
  81. FDMISM_EVENT_PORT_OFFLINE = 2,
  82. FDMISM_EVENT_RSP_OK = 4,
  83. FDMISM_EVENT_RSP_ERROR = 5,
  84. FDMISM_EVENT_TIMEOUT = 6,
  85. FDMISM_EVENT_RHBA_SENT = 7,
  86. FDMISM_EVENT_RPRT_SENT = 8,
  87. FDMISM_EVENT_RPA_SENT = 9,
  88. };
  89. static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
  90. enum port_fdmi_event event);
  91. static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
  92. enum port_fdmi_event event);
  93. static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
  94. enum port_fdmi_event event);
  95. static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  96. enum port_fdmi_event event);
  97. static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
  98. enum port_fdmi_event event);
  99. static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
  100. enum port_fdmi_event event);
  101. static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  102. enum port_fdmi_event event);
  103. static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
  104. enum port_fdmi_event event);
  105. static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
  106. enum port_fdmi_event event);
  107. static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  108. enum port_fdmi_event event);
  109. static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
  110. enum port_fdmi_event event);
  111. /**
  112. * Start in offline state - awaiting MS to send start.
  113. */
  114. static void
  115. bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
  116. enum port_fdmi_event event)
  117. {
  118. struct bfa_fcs_port_s *port = fdmi->ms->port;
  119. bfa_trc(port->fcs, port->port_cfg.pwwn);
  120. bfa_trc(port->fcs, event);
  121. fdmi->retry_cnt = 0;
  122. switch (event) {
  123. case FDMISM_EVENT_PORT_ONLINE:
  124. if (port->vport) {
  125. /*
  126. * For Vports, register a new port.
  127. */
  128. bfa_sm_set_state(fdmi,
  129. bfa_fcs_port_fdmi_sm_sending_rprt);
  130. bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
  131. } else {
  132. /*
  133. * For a base port, we should first register the HBA
  134. * atribute. The HBA attribute also contains the base
  135. * port registration.
  136. */
  137. bfa_sm_set_state(fdmi,
  138. bfa_fcs_port_fdmi_sm_sending_rhba);
  139. bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
  140. }
  141. break;
  142. case FDMISM_EVENT_PORT_OFFLINE:
  143. break;
  144. default:
  145. bfa_assert(0);
  146. }
  147. }
  148. static void
  149. bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
  150. enum port_fdmi_event event)
  151. {
  152. struct bfa_fcs_port_s *port = fdmi->ms->port;
  153. bfa_trc(port->fcs, port->port_cfg.pwwn);
  154. bfa_trc(port->fcs, event);
  155. switch (event) {
  156. case FDMISM_EVENT_RHBA_SENT:
  157. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba);
  158. break;
  159. case FDMISM_EVENT_PORT_OFFLINE:
  160. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  161. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
  162. &fdmi->fcxp_wqe);
  163. break;
  164. default:
  165. bfa_assert(0);
  166. }
  167. }
  168. static void
  169. bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
  170. enum port_fdmi_event event)
  171. {
  172. struct bfa_fcs_port_s *port = fdmi->ms->port;
  173. bfa_trc(port->fcs, port->port_cfg.pwwn);
  174. bfa_trc(port->fcs, event);
  175. switch (event) {
  176. case FDMISM_EVENT_RSP_ERROR:
  177. /*
  178. * if max retries have not been reached, start timer for a
  179. * delayed retry
  180. */
  181. if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
  182. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba_retry);
  183. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
  184. &fdmi->timer, bfa_fcs_port_fdmi_timeout,
  185. fdmi, BFA_FCS_RETRY_TIMEOUT);
  186. } else {
  187. /*
  188. * set state to offline
  189. */
  190. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  191. }
  192. break;
  193. case FDMISM_EVENT_RSP_OK:
  194. /*
  195. * Initiate Register Port Attributes
  196. */
  197. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
  198. fdmi->retry_cnt = 0;
  199. bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
  200. break;
  201. case FDMISM_EVENT_PORT_OFFLINE:
  202. bfa_fcxp_discard(fdmi->fcxp);
  203. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  204. break;
  205. default:
  206. bfa_assert(0);
  207. }
  208. }
  209. static void
  210. bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  211. enum port_fdmi_event event)
  212. {
  213. struct bfa_fcs_port_s *port = fdmi->ms->port;
  214. bfa_trc(port->fcs, port->port_cfg.pwwn);
  215. bfa_trc(port->fcs, event);
  216. switch (event) {
  217. case FDMISM_EVENT_TIMEOUT:
  218. /*
  219. * Retry Timer Expired. Re-send
  220. */
  221. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba);
  222. bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
  223. break;
  224. case FDMISM_EVENT_PORT_OFFLINE:
  225. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  226. bfa_timer_stop(&fdmi->timer);
  227. break;
  228. default:
  229. bfa_assert(0);
  230. }
  231. }
  232. /*
  233. * RPRT : Register Port
  234. */
  235. static void
  236. bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
  237. enum port_fdmi_event event)
  238. {
  239. struct bfa_fcs_port_s *port = fdmi->ms->port;
  240. bfa_trc(port->fcs, port->port_cfg.pwwn);
  241. bfa_trc(port->fcs, event);
  242. switch (event) {
  243. case FDMISM_EVENT_RPRT_SENT:
  244. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt);
  245. break;
  246. case FDMISM_EVENT_PORT_OFFLINE:
  247. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  248. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
  249. &fdmi->fcxp_wqe);
  250. break;
  251. default:
  252. bfa_assert(0);
  253. }
  254. }
  255. static void
  256. bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
  257. enum port_fdmi_event event)
  258. {
  259. struct bfa_fcs_port_s *port = fdmi->ms->port;
  260. bfa_trc(port->fcs, port->port_cfg.pwwn);
  261. bfa_trc(port->fcs, event);
  262. switch (event) {
  263. case FDMISM_EVENT_RSP_ERROR:
  264. /*
  265. * if max retries have not been reached, start timer for a
  266. * delayed retry
  267. */
  268. if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
  269. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt_retry);
  270. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
  271. &fdmi->timer, bfa_fcs_port_fdmi_timeout,
  272. fdmi, BFA_FCS_RETRY_TIMEOUT);
  273. } else {
  274. /*
  275. * set state to offline
  276. */
  277. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  278. fdmi->retry_cnt = 0;
  279. }
  280. break;
  281. case FDMISM_EVENT_RSP_OK:
  282. fdmi->retry_cnt = 0;
  283. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
  284. break;
  285. case FDMISM_EVENT_PORT_OFFLINE:
  286. bfa_fcxp_discard(fdmi->fcxp);
  287. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  288. break;
  289. default:
  290. bfa_assert(0);
  291. }
  292. }
  293. static void
  294. bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  295. enum port_fdmi_event event)
  296. {
  297. struct bfa_fcs_port_s *port = fdmi->ms->port;
  298. bfa_trc(port->fcs, port->port_cfg.pwwn);
  299. bfa_trc(port->fcs, event);
  300. switch (event) {
  301. case FDMISM_EVENT_TIMEOUT:
  302. /*
  303. * Retry Timer Expired. Re-send
  304. */
  305. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt);
  306. bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
  307. break;
  308. case FDMISM_EVENT_PORT_OFFLINE:
  309. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  310. bfa_timer_stop(&fdmi->timer);
  311. break;
  312. default:
  313. bfa_assert(0);
  314. }
  315. }
  316. /*
  317. * Register Port Attributes
  318. */
  319. static void
  320. bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
  321. enum port_fdmi_event event)
  322. {
  323. struct bfa_fcs_port_s *port = fdmi->ms->port;
  324. bfa_trc(port->fcs, port->port_cfg.pwwn);
  325. bfa_trc(port->fcs, event);
  326. switch (event) {
  327. case FDMISM_EVENT_RPA_SENT:
  328. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa);
  329. break;
  330. case FDMISM_EVENT_PORT_OFFLINE:
  331. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  332. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
  333. &fdmi->fcxp_wqe);
  334. break;
  335. default:
  336. bfa_assert(0);
  337. }
  338. }
  339. static void
  340. bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
  341. enum port_fdmi_event event)
  342. {
  343. struct bfa_fcs_port_s *port = fdmi->ms->port;
  344. bfa_trc(port->fcs, port->port_cfg.pwwn);
  345. bfa_trc(port->fcs, event);
  346. switch (event) {
  347. case FDMISM_EVENT_RSP_ERROR:
  348. /*
  349. * if max retries have not been reached, start timer for a
  350. * delayed retry
  351. */
  352. if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
  353. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa_retry);
  354. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
  355. &fdmi->timer, bfa_fcs_port_fdmi_timeout,
  356. fdmi, BFA_FCS_RETRY_TIMEOUT);
  357. } else {
  358. /*
  359. * set state to offline
  360. */
  361. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  362. fdmi->retry_cnt = 0;
  363. }
  364. break;
  365. case FDMISM_EVENT_RSP_OK:
  366. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
  367. fdmi->retry_cnt = 0;
  368. break;
  369. case FDMISM_EVENT_PORT_OFFLINE:
  370. bfa_fcxp_discard(fdmi->fcxp);
  371. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  372. break;
  373. default:
  374. bfa_assert(0);
  375. }
  376. }
  377. static void
  378. bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
  379. enum port_fdmi_event event)
  380. {
  381. struct bfa_fcs_port_s *port = fdmi->ms->port;
  382. bfa_trc(port->fcs, port->port_cfg.pwwn);
  383. bfa_trc(port->fcs, event);
  384. switch (event) {
  385. case FDMISM_EVENT_TIMEOUT:
  386. /*
  387. * Retry Timer Expired. Re-send
  388. */
  389. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
  390. bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
  391. break;
  392. case FDMISM_EVENT_PORT_OFFLINE:
  393. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  394. bfa_timer_stop(&fdmi->timer);
  395. break;
  396. default:
  397. bfa_assert(0);
  398. }
  399. }
  400. static void
  401. bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
  402. enum port_fdmi_event event)
  403. {
  404. struct bfa_fcs_port_s *port = fdmi->ms->port;
  405. bfa_trc(port->fcs, port->port_cfg.pwwn);
  406. bfa_trc(port->fcs, event);
  407. switch (event) {
  408. case FDMISM_EVENT_PORT_OFFLINE:
  409. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  410. break;
  411. default:
  412. bfa_assert(0);
  413. }
  414. }
  415. /**
  416. * RHBA : Register HBA Attributes.
  417. */
  418. static void
  419. bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  420. {
  421. struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
  422. struct bfa_fcs_port_s *port = fdmi->ms->port;
  423. struct fchs_s fchs;
  424. int len, attr_len;
  425. struct bfa_fcxp_s *fcxp;
  426. u8 *pyld;
  427. bfa_trc(port->fcs, port->port_cfg.pwwn);
  428. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  429. if (!fcxp) {
  430. bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
  431. bfa_fcs_port_fdmi_send_rhba, fdmi);
  432. return;
  433. }
  434. fdmi->fcxp = fcxp;
  435. pyld = bfa_fcxp_get_reqbuf(fcxp);
  436. bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
  437. len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
  438. FDMI_RHBA);
  439. attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi,
  440. (u8 *) ((struct ct_hdr_s *) pyld + 1));
  441. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  442. FC_CLASS_3, (len + attr_len), &fchs,
  443. bfa_fcs_port_fdmi_rhba_response, (void *)fdmi,
  444. FC_MAX_PDUSZ, FC_RA_TOV);
  445. bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
  446. }
  447. static u16
  448. bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
  449. u8 *pyld)
  450. {
  451. struct bfa_fcs_port_s *port = fdmi->ms->port;
  452. struct bfa_fcs_fdmi_hba_attr_s hba_attr; /* @todo */
  453. struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; /* @todo */
  454. struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
  455. struct fdmi_attr_s *attr;
  456. u8 *curr_ptr;
  457. u16 len, count;
  458. /*
  459. * get hba attributes
  460. */
  461. bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
  462. rhba->hba_id = bfa_fcs_port_get_pwwn(port);
  463. rhba->port_list.num_ports = bfa_os_htonl(1);
  464. rhba->port_list.port_entry = bfa_fcs_port_get_pwwn(port);
  465. len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
  466. count = 0;
  467. len += sizeof(rhba->hba_attr_blk.attr_count);
  468. /*
  469. * fill out the invididual entries of the HBA attrib Block
  470. */
  471. curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
  472. /*
  473. * Node Name
  474. */
  475. attr = (struct fdmi_attr_s *) curr_ptr;
  476. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME);
  477. attr->len = sizeof(wwn_t);
  478. memcpy(attr->value, &bfa_fcs_port_get_nwwn(port), attr->len);
  479. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  480. len += attr->len;
  481. count++;
  482. attr->len =
  483. bfa_os_htons(attr->len + sizeof(attr->type) +
  484. sizeof(attr->len));
  485. /*
  486. * Manufacturer
  487. */
  488. attr = (struct fdmi_attr_s *) curr_ptr;
  489. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER);
  490. attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
  491. memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
  492. /* variable fields need to be 4 byte aligned */
  493. attr->len = fc_roundup(attr->len, sizeof(u32));
  494. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  495. len += attr->len;
  496. count++;
  497. attr->len =
  498. bfa_os_htons(attr->len + sizeof(attr->type) +
  499. sizeof(attr->len));
  500. /*
  501. * Serial Number
  502. */
  503. attr = (struct fdmi_attr_s *) curr_ptr;
  504. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM);
  505. attr->len = (u16) strlen(fcs_hba_attr->serial_num);
  506. memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
  507. /* variable fields need to be 4 byte aligned */
  508. attr->len = fc_roundup(attr->len, sizeof(u32));
  509. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  510. len += attr->len;
  511. count++;
  512. attr->len =
  513. bfa_os_htons(attr->len + sizeof(attr->type) +
  514. sizeof(attr->len));
  515. /*
  516. * Model
  517. */
  518. attr = (struct fdmi_attr_s *) curr_ptr;
  519. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL);
  520. attr->len = (u16) strlen(fcs_hba_attr->model);
  521. memcpy(attr->value, fcs_hba_attr->model, attr->len);
  522. /* variable fields need to be 4 byte aligned */
  523. attr->len = fc_roundup(attr->len, sizeof(u32));
  524. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  525. len += attr->len;
  526. count++;
  527. attr->len =
  528. bfa_os_htons(attr->len + sizeof(attr->type) +
  529. sizeof(attr->len));
  530. /*
  531. * Model Desc
  532. */
  533. attr = (struct fdmi_attr_s *) curr_ptr;
  534. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC);
  535. attr->len = (u16) strlen(fcs_hba_attr->model_desc);
  536. memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
  537. /* variable fields need to be 4 byte aligned */
  538. attr->len = fc_roundup(attr->len, sizeof(u32));
  539. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  540. len += attr->len;
  541. count++;
  542. attr->len =
  543. bfa_os_htons(attr->len + sizeof(attr->type) +
  544. sizeof(attr->len));
  545. /*
  546. * H/W Version
  547. */
  548. if (fcs_hba_attr->hw_version[0] != '\0') {
  549. attr = (struct fdmi_attr_s *) curr_ptr;
  550. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION);
  551. attr->len = (u16) strlen(fcs_hba_attr->hw_version);
  552. memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
  553. /* variable fields need to be 4 byte aligned */
  554. attr->len = fc_roundup(attr->len, sizeof(u32));
  555. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  556. len += attr->len;
  557. count++;
  558. attr->len =
  559. bfa_os_htons(attr->len + sizeof(attr->type) +
  560. sizeof(attr->len));
  561. }
  562. /*
  563. * Driver Version
  564. */
  565. attr = (struct fdmi_attr_s *) curr_ptr;
  566. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION);
  567. attr->len = (u16) strlen(fcs_hba_attr->driver_version);
  568. memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
  569. /* variable fields need to be 4 byte aligned */
  570. attr->len = fc_roundup(attr->len, sizeof(u32));
  571. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  572. len += attr->len;;
  573. count++;
  574. attr->len =
  575. bfa_os_htons(attr->len + sizeof(attr->type) +
  576. sizeof(attr->len));
  577. /*
  578. * Option Rom Version
  579. */
  580. if (fcs_hba_attr->option_rom_ver[0] != '\0') {
  581. attr = (struct fdmi_attr_s *) curr_ptr;
  582. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION);
  583. attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
  584. memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
  585. /* variable fields need to be 4 byte aligned */
  586. attr->len = fc_roundup(attr->len, sizeof(u32));
  587. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  588. len += attr->len;
  589. count++;
  590. attr->len =
  591. bfa_os_htons(attr->len + sizeof(attr->type) +
  592. sizeof(attr->len));
  593. }
  594. /*
  595. * f/w Version = driver version
  596. */
  597. attr = (struct fdmi_attr_s *) curr_ptr;
  598. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION);
  599. attr->len = (u16) strlen(fcs_hba_attr->driver_version);
  600. memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
  601. /* variable fields need to be 4 byte aligned */
  602. attr->len = fc_roundup(attr->len, sizeof(u32));
  603. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  604. len += attr->len;
  605. count++;
  606. attr->len =
  607. bfa_os_htons(attr->len + sizeof(attr->type) +
  608. sizeof(attr->len));
  609. /*
  610. * OS Name
  611. */
  612. if (fcs_hba_attr->os_name[0] != '\0') {
  613. attr = (struct fdmi_attr_s *) curr_ptr;
  614. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME);
  615. attr->len = (u16) strlen(fcs_hba_attr->os_name);
  616. memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
  617. /* variable fields need to be 4 byte aligned */
  618. attr->len = fc_roundup(attr->len, sizeof(u32));
  619. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  620. len += attr->len;
  621. count++;
  622. attr->len =
  623. bfa_os_htons(attr->len + sizeof(attr->type) +
  624. sizeof(attr->len));
  625. }
  626. /*
  627. * MAX_CT_PAYLOAD
  628. */
  629. attr = (struct fdmi_attr_s *) curr_ptr;
  630. attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT);
  631. attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
  632. memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
  633. len += attr->len;
  634. count++;
  635. attr->len =
  636. bfa_os_htons(attr->len + sizeof(attr->type) +
  637. sizeof(attr->len));
  638. /*
  639. * Update size of payload
  640. */
  641. len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
  642. rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
  643. return len;
  644. }
  645. static void
  646. bfa_fcs_port_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  647. void *cbarg, bfa_status_t req_status,
  648. u32 rsp_len, u32 resid_len,
  649. struct fchs_s *rsp_fchs)
  650. {
  651. struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
  652. struct bfa_fcs_port_s *port = fdmi->ms->port;
  653. struct ct_hdr_s *cthdr = NULL;
  654. bfa_trc(port->fcs, port->port_cfg.pwwn);
  655. /*
  656. * Sanity Checks
  657. */
  658. if (req_status != BFA_STATUS_OK) {
  659. bfa_trc(port->fcs, req_status);
  660. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  661. return;
  662. }
  663. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  664. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  665. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  666. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
  667. return;
  668. }
  669. bfa_trc(port->fcs, cthdr->reason_code);
  670. bfa_trc(port->fcs, cthdr->exp_code);
  671. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  672. }
  673. /**
  674. * RPRT : Register Port
  675. */
  676. static void
  677. bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  678. {
  679. struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
  680. struct bfa_fcs_port_s *port = fdmi->ms->port;
  681. struct fchs_s fchs;
  682. u16 len, attr_len;
  683. struct bfa_fcxp_s *fcxp;
  684. u8 *pyld;
  685. bfa_trc(port->fcs, port->port_cfg.pwwn);
  686. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  687. if (!fcxp) {
  688. bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
  689. bfa_fcs_port_fdmi_send_rprt, fdmi);
  690. return;
  691. }
  692. fdmi->fcxp = fcxp;
  693. pyld = bfa_fcxp_get_reqbuf(fcxp);
  694. bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
  695. len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
  696. FDMI_RPRT);
  697. attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi,
  698. (u8 *) ((struct ct_hdr_s *) pyld + 1));
  699. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  700. FC_CLASS_3, len + attr_len, &fchs,
  701. bfa_fcs_port_fdmi_rprt_response, (void *)fdmi,
  702. FC_MAX_PDUSZ, FC_RA_TOV);
  703. bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
  704. }
  705. /**
  706. * This routine builds Port Attribute Block that used in RPA, RPRT commands.
  707. */
  708. static u16
  709. bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi,
  710. u8 *pyld)
  711. {
  712. struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
  713. struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
  714. struct fdmi_attr_s *attr;
  715. u8 *curr_ptr;
  716. u16 len;
  717. u8 count = 0;
  718. /*
  719. * get port attributes
  720. */
  721. bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
  722. len = sizeof(port_attrib->attr_count);
  723. /*
  724. * fill out the invididual entries
  725. */
  726. curr_ptr = (u8 *) &port_attrib->port_attr;
  727. /*
  728. * FC4 Types
  729. */
  730. attr = (struct fdmi_attr_s *) curr_ptr;
  731. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES);
  732. attr->len = sizeof(fcs_port_attr.supp_fc4_types);
  733. memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
  734. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  735. len += attr->len;
  736. ++count;
  737. attr->len =
  738. bfa_os_htons(attr->len + sizeof(attr->type) +
  739. sizeof(attr->len));
  740. /*
  741. * Supported Speed
  742. */
  743. attr = (struct fdmi_attr_s *) curr_ptr;
  744. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED);
  745. attr->len = sizeof(fcs_port_attr.supp_speed);
  746. memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
  747. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  748. len += attr->len;
  749. ++count;
  750. attr->len =
  751. bfa_os_htons(attr->len + sizeof(attr->type) +
  752. sizeof(attr->len));
  753. /*
  754. * current Port Speed
  755. */
  756. attr = (struct fdmi_attr_s *) curr_ptr;
  757. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED);
  758. attr->len = sizeof(fcs_port_attr.curr_speed);
  759. memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
  760. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  761. len += attr->len;
  762. ++count;
  763. attr->len =
  764. bfa_os_htons(attr->len + sizeof(attr->type) +
  765. sizeof(attr->len));
  766. /*
  767. * max frame size
  768. */
  769. attr = (struct fdmi_attr_s *) curr_ptr;
  770. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE);
  771. attr->len = sizeof(fcs_port_attr.max_frm_size);
  772. memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
  773. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  774. len += attr->len;
  775. ++count;
  776. attr->len =
  777. bfa_os_htons(attr->len + sizeof(attr->type) +
  778. sizeof(attr->len));
  779. /*
  780. * OS Device Name
  781. */
  782. if (fcs_port_attr.os_device_name[0] != '\0') {
  783. attr = (struct fdmi_attr_s *) curr_ptr;
  784. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME);
  785. attr->len = (u16) strlen(fcs_port_attr.os_device_name);
  786. memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
  787. /* variable fields need to be 4 byte aligned */
  788. attr->len = fc_roundup(attr->len, sizeof(u32));
  789. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  790. len += attr->len;
  791. ++count;
  792. attr->len =
  793. bfa_os_htons(attr->len + sizeof(attr->type) +
  794. sizeof(attr->len));
  795. }
  796. /*
  797. * Host Name
  798. */
  799. if (fcs_port_attr.host_name[0] != '\0') {
  800. attr = (struct fdmi_attr_s *) curr_ptr;
  801. attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME);
  802. attr->len = (u16) strlen(fcs_port_attr.host_name);
  803. memcpy(attr->value, fcs_port_attr.host_name, attr->len);
  804. /* variable fields need to be 4 byte aligned */
  805. attr->len = fc_roundup(attr->len, sizeof(u32));
  806. curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
  807. len += attr->len;
  808. ++count;
  809. attr->len =
  810. bfa_os_htons(attr->len + sizeof(attr->type) +
  811. sizeof(attr->len));
  812. }
  813. /*
  814. * Update size of payload
  815. */
  816. port_attrib->attr_count = bfa_os_htonl(count);
  817. len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
  818. return len;
  819. }
  820. static u16
  821. bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
  822. u8 *pyld)
  823. {
  824. struct bfa_fcs_port_s *port = fdmi->ms->port;
  825. struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
  826. u16 len;
  827. rprt->hba_id = bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
  828. rprt->port_name = bfa_fcs_port_get_pwwn(port);
  829. len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
  830. (u8 *) &rprt->port_attr_blk);
  831. len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
  832. return len;
  833. }
  834. static void
  835. bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  836. void *cbarg, bfa_status_t req_status,
  837. u32 rsp_len, u32 resid_len,
  838. struct fchs_s *rsp_fchs)
  839. {
  840. struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
  841. struct bfa_fcs_port_s *port = fdmi->ms->port;
  842. struct ct_hdr_s *cthdr = NULL;
  843. bfa_trc(port->fcs, port->port_cfg.pwwn);
  844. /*
  845. * Sanity Checks
  846. */
  847. if (req_status != BFA_STATUS_OK) {
  848. bfa_trc(port->fcs, req_status);
  849. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  850. return;
  851. }
  852. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  853. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  854. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  855. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
  856. return;
  857. }
  858. bfa_trc(port->fcs, cthdr->reason_code);
  859. bfa_trc(port->fcs, cthdr->exp_code);
  860. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  861. }
  862. /**
  863. * RPA : Register Port Attributes.
  864. */
  865. static void
  866. bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  867. {
  868. struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
  869. struct bfa_fcs_port_s *port = fdmi->ms->port;
  870. struct fchs_s fchs;
  871. u16 len, attr_len;
  872. struct bfa_fcxp_s *fcxp;
  873. u8 *pyld;
  874. bfa_trc(port->fcs, port->port_cfg.pwwn);
  875. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  876. if (!fcxp) {
  877. bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
  878. bfa_fcs_port_fdmi_send_rpa, fdmi);
  879. return;
  880. }
  881. fdmi->fcxp = fcxp;
  882. pyld = bfa_fcxp_get_reqbuf(fcxp);
  883. bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
  884. len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
  885. FDMI_RPA);
  886. attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi,
  887. (u8 *) ((struct ct_hdr_s *) pyld + 1));
  888. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  889. FC_CLASS_3, len + attr_len, &fchs,
  890. bfa_fcs_port_fdmi_rpa_response, (void *)fdmi,
  891. FC_MAX_PDUSZ, FC_RA_TOV);
  892. bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
  893. }
  894. static u16
  895. bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
  896. u8 *pyld)
  897. {
  898. struct bfa_fcs_port_s *port = fdmi->ms->port;
  899. struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
  900. u16 len;
  901. rpa->port_name = bfa_fcs_port_get_pwwn(port);
  902. len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
  903. (u8 *) &rpa->port_attr_blk);
  904. len += sizeof(rpa->port_name);
  905. return len;
  906. }
  907. static void
  908. bfa_fcs_port_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  909. void *cbarg, bfa_status_t req_status,
  910. u32 rsp_len, u32 resid_len,
  911. struct fchs_s *rsp_fchs)
  912. {
  913. struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
  914. struct bfa_fcs_port_s *port = fdmi->ms->port;
  915. struct ct_hdr_s *cthdr = NULL;
  916. bfa_trc(port->fcs, port->port_cfg.pwwn);
  917. /*
  918. * Sanity Checks
  919. */
  920. if (req_status != BFA_STATUS_OK) {
  921. bfa_trc(port->fcs, req_status);
  922. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  923. return;
  924. }
  925. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  926. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  927. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  928. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
  929. return;
  930. }
  931. bfa_trc(port->fcs, cthdr->reason_code);
  932. bfa_trc(port->fcs, cthdr->exp_code);
  933. bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
  934. }
  935. static void
  936. bfa_fcs_port_fdmi_timeout(void *arg)
  937. {
  938. struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg;
  939. bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
  940. }
  941. static void
  942. bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
  943. struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
  944. {
  945. struct bfa_fcs_port_s *port = fdmi->ms->port;
  946. struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
  947. struct bfa_adapter_attr_s adapter_attr;
  948. bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
  949. bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
  950. bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
  951. strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
  952. sizeof(adapter_attr.manufacturer));
  953. strncpy(hba_attr->serial_num, adapter_attr.serial_num,
  954. sizeof(adapter_attr.serial_num));
  955. strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
  956. strncpy(hba_attr->model_desc, adapter_attr.model_descr,
  957. sizeof(hba_attr->model_desc));
  958. strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
  959. sizeof(hba_attr->hw_version));
  960. strncpy(hba_attr->driver_version, (char *)driver_info->version,
  961. sizeof(hba_attr->driver_version));
  962. strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
  963. sizeof(hba_attr->option_rom_ver));
  964. strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
  965. sizeof(hba_attr->fw_version));
  966. strncpy(hba_attr->os_name, driver_info->host_os_name,
  967. sizeof(hba_attr->os_name));
  968. /*
  969. * If there is a patch level, append it to the os name along with a
  970. * separator
  971. */
  972. if (driver_info->host_os_patch[0] != '\0') {
  973. strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  974. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  975. strncat(hba_attr->os_name, driver_info->host_os_patch,
  976. sizeof(driver_info->host_os_patch));
  977. }
  978. hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
  979. }
  980. static void
  981. bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
  982. struct bfa_fcs_fdmi_port_attr_s *port_attr)
  983. {
  984. struct bfa_fcs_port_s *port = fdmi->ms->port;
  985. struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
  986. struct bfa_pport_attr_s pport_attr;
  987. bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
  988. /*
  989. * get pport attributes from hal
  990. */
  991. bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
  992. /*
  993. * get FC4 type Bitmask
  994. */
  995. fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
  996. /*
  997. * Supported Speeds
  998. */
  999. port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
  1000. /*
  1001. * Current Speed
  1002. */
  1003. port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
  1004. /*
  1005. * Max PDU Size.
  1006. */
  1007. port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
  1008. /*
  1009. * OS device Name
  1010. */
  1011. strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
  1012. sizeof(port_attr->os_device_name));
  1013. /*
  1014. * Host name
  1015. */
  1016. strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
  1017. sizeof(port_attr->host_name));
  1018. }
  1019. void
  1020. bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
  1021. {
  1022. struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
  1023. fdmi->ms = ms;
  1024. bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
  1025. }
  1026. void
  1027. bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms)
  1028. {
  1029. struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
  1030. fdmi->ms = ms;
  1031. bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
  1032. }
  1033. void
  1034. bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms)
  1035. {
  1036. struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
  1037. fdmi->ms = ms;
  1038. bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
  1039. }