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