2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
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
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.
18 #include <defs/bfa_defs_cee.h>
19 #include <cs/bfa_trc.h>
20 #include <cs/bfa_log.h>
21 #include <cs/bfa_debug.h>
22 #include <cee/bfa_cee.h>
23 #include <bfi/bfi_cee.h>
26 #include <cna/bfa_cna_trcmod.h>
28 BFA_TRC_FILE(CNA
, CEE
);
30 #define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31 #define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
33 static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s
*lldp_cfg
);
34 static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
36 static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
38 static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s
*cfg_stats
);
39 static void bfa_cee_format_cee_cfg(void *buffer
);
40 static void bfa_cee_format_cee_stats(void *buffer
);
43 bfa_cee_format_cee_stats(void *buffer
)
45 struct bfa_cee_stats_s
*cee_stats
= buffer
;
46 bfa_cee_format_dcbcx_stats(&cee_stats
->dcbx_stats
);
47 bfa_cee_format_lldp_stats(&cee_stats
->lldp_stats
);
48 bfa_cee_format_cfg_stats(&cee_stats
->cfg_stats
);
52 bfa_cee_format_cee_cfg(void *buffer
)
54 struct bfa_cee_attr_s
*cee_cfg
= buffer
;
55 bfa_cee_format_lldp_cfg(&cee_cfg
->lldp_remote
);
59 bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
*dcbcx_stats
)
61 dcbcx_stats
->subtlvs_unrecognized
=
62 bfa_os_ntohl(dcbcx_stats
->subtlvs_unrecognized
);
63 dcbcx_stats
->negotiation_failed
=
64 bfa_os_ntohl(dcbcx_stats
->negotiation_failed
);
65 dcbcx_stats
->remote_cfg_changed
=
66 bfa_os_ntohl(dcbcx_stats
->remote_cfg_changed
);
67 dcbcx_stats
->tlvs_received
= bfa_os_ntohl(dcbcx_stats
->tlvs_received
);
68 dcbcx_stats
->tlvs_invalid
= bfa_os_ntohl(dcbcx_stats
->tlvs_invalid
);
69 dcbcx_stats
->seqno
= bfa_os_ntohl(dcbcx_stats
->seqno
);
70 dcbcx_stats
->ackno
= bfa_os_ntohl(dcbcx_stats
->ackno
);
71 dcbcx_stats
->recvd_seqno
= bfa_os_ntohl(dcbcx_stats
->recvd_seqno
);
72 dcbcx_stats
->recvd_ackno
= bfa_os_ntohl(dcbcx_stats
->recvd_ackno
);
76 bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
*lldp_stats
)
78 lldp_stats
->frames_transmitted
=
79 bfa_os_ntohl(lldp_stats
->frames_transmitted
);
80 lldp_stats
->frames_aged_out
= bfa_os_ntohl(lldp_stats
->frames_aged_out
);
81 lldp_stats
->frames_discarded
=
82 bfa_os_ntohl(lldp_stats
->frames_discarded
);
83 lldp_stats
->frames_in_error
= bfa_os_ntohl(lldp_stats
->frames_in_error
);
84 lldp_stats
->frames_rcvd
= bfa_os_ntohl(lldp_stats
->frames_rcvd
);
85 lldp_stats
->tlvs_discarded
= bfa_os_ntohl(lldp_stats
->tlvs_discarded
);
86 lldp_stats
->tlvs_unrecognized
=
87 bfa_os_ntohl(lldp_stats
->tlvs_unrecognized
);
91 bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s
*cfg_stats
)
93 cfg_stats
->cee_status_down
= bfa_os_ntohl(cfg_stats
->cee_status_down
);
94 cfg_stats
->cee_status_up
= bfa_os_ntohl(cfg_stats
->cee_status_up
);
95 cfg_stats
->cee_hw_cfg_changed
=
96 bfa_os_ntohl(cfg_stats
->cee_hw_cfg_changed
);
97 cfg_stats
->recvd_invalid_cfg
=
98 bfa_os_ntohl(cfg_stats
->recvd_invalid_cfg
);
102 bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s
*lldp_cfg
)
104 lldp_cfg
->time_to_interval
= bfa_os_ntohs(lldp_cfg
->time_to_interval
);
105 lldp_cfg
->enabled_system_cap
=
106 bfa_os_ntohs(lldp_cfg
->enabled_system_cap
);
110 * bfa_cee_attr_meminfo()
115 * @return Size of DMA region
118 bfa_cee_attr_meminfo(void)
120 return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s
), BFA_DMA_ALIGN_SZ
);
124 * bfa_cee_stats_meminfo()
129 * @return Size of DMA region
132 bfa_cee_stats_meminfo(void)
134 return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s
), BFA_DMA_ALIGN_SZ
);
138 * bfa_cee_get_attr_isr()
141 * @param[in] cee - Pointer to the CEE module
142 * status - Return status from the f/w
147 bfa_cee_get_attr_isr(struct bfa_cee_s
*cee
, bfa_status_t status
)
149 cee
->get_attr_status
= status
;
151 if (status
== BFA_STATUS_OK
) {
154 * The requested data has been copied to the DMA area, *process
157 memcpy(cee
->attr
, cee
->attr_dma
.kva
,
158 sizeof(struct bfa_cee_attr_s
));
159 bfa_cee_format_cee_cfg(cee
->attr
);
161 cee
->get_attr_pending
= BFA_FALSE
;
162 if (cee
->cbfn
.get_attr_cbfn
) {
164 cee
->cbfn
.get_attr_cbfn(cee
->cbfn
.get_attr_cbarg
, status
);
170 * bfa_cee_get_attr_isr()
173 * @param[in] cee - Pointer to the CEE module
174 * status - Return status from the f/w
179 bfa_cee_get_stats_isr(struct bfa_cee_s
*cee
, bfa_status_t status
)
181 cee
->get_stats_status
= status
;
183 if (status
== BFA_STATUS_OK
) {
186 * The requested data has been copied to the DMA area, process
189 memcpy(cee
->stats
, cee
->stats_dma
.kva
,
190 sizeof(struct bfa_cee_stats_s
));
191 bfa_cee_format_cee_stats(cee
->stats
);
193 cee
->get_stats_pending
= BFA_FALSE
;
195 if (cee
->cbfn
.get_stats_cbfn
) {
197 cee
->cbfn
.get_stats_cbfn(cee
->cbfn
.get_stats_cbarg
, status
);
203 * bfa_cee_get_attr_isr()
206 * @param[in] cee - Pointer to the CEE module
207 * status - Return status from the f/w
212 bfa_cee_reset_stats_isr(struct bfa_cee_s
*cee
, bfa_status_t status
)
214 cee
->reset_stats_status
= status
;
215 cee
->reset_stats_pending
= BFA_FALSE
;
216 if (cee
->cbfn
.reset_stats_cbfn
)
217 cee
->cbfn
.reset_stats_cbfn(cee
->cbfn
.reset_stats_cbarg
, status
);
226 * @return Size of DMA region
229 bfa_cee_meminfo(void)
231 return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
235 * bfa_cee_mem_claim()
238 * @param[in] cee CEE module pointer
239 * dma_kva Kernel Virtual Address of CEE DMA Memory
240 * dma_pa Physical Address of CEE DMA Memory
245 bfa_cee_mem_claim(struct bfa_cee_s
*cee
, u8
*dma_kva
, u64 dma_pa
)
247 cee
->attr_dma
.kva
= dma_kva
;
248 cee
->attr_dma
.pa
= dma_pa
;
249 cee
->stats_dma
.kva
= dma_kva
+ bfa_cee_attr_meminfo();
250 cee
->stats_dma
.pa
= dma_pa
+ bfa_cee_attr_meminfo();
251 cee
->attr
= (struct bfa_cee_attr_s
*)dma_kva
;
253 (struct bfa_cee_stats_s
*)(dma_kva
+ bfa_cee_attr_meminfo());
259 * Send the request to the f/w to fetch CEE attributes.
261 * @param[in] Pointer to the CEE module data structure.
267 bfa_cee_get_attr(struct bfa_cee_s
*cee
, struct bfa_cee_attr_s
*attr
,
268 bfa_cee_get_attr_cbfn_t cbfn
, void *cbarg
)
270 struct bfi_cee_get_req_s
*cmd
;
272 bfa_assert((cee
!= NULL
) && (cee
->ioc
!= NULL
));
274 if (!bfa_ioc_is_operational(cee
->ioc
)) {
276 return BFA_STATUS_IOC_FAILURE
;
278 if (cee
->get_attr_pending
== BFA_TRUE
) {
280 return BFA_STATUS_DEVBUSY
;
282 cee
->get_attr_pending
= BFA_TRUE
;
283 cmd
= (struct bfi_cee_get_req_s
*)cee
->get_cfg_mb
.msg
;
285 cee
->cbfn
.get_attr_cbfn
= cbfn
;
286 cee
->cbfn
.get_attr_cbarg
= cbarg
;
287 bfi_h2i_set(cmd
->mh
, BFI_MC_CEE
, BFI_CEE_H2I_GET_CFG_REQ
,
288 bfa_ioc_portid(cee
->ioc
));
289 bfa_dma_be_addr_set(cmd
->dma_addr
, cee
->attr_dma
.pa
);
290 bfa_ioc_mbox_queue(cee
->ioc
, &cee
->get_cfg_mb
);
293 return BFA_STATUS_OK
;
297 * bfa_cee_get_stats()
299 * Send the request to the f/w to fetch CEE statistics.
301 * @param[in] Pointer to the CEE module data structure.
307 bfa_cee_get_stats(struct bfa_cee_s
*cee
, struct bfa_cee_stats_s
*stats
,
308 bfa_cee_get_stats_cbfn_t cbfn
, void *cbarg
)
310 struct bfi_cee_get_req_s
*cmd
;
312 bfa_assert((cee
!= NULL
) && (cee
->ioc
!= NULL
));
314 if (!bfa_ioc_is_operational(cee
->ioc
)) {
316 return BFA_STATUS_IOC_FAILURE
;
318 if (cee
->get_stats_pending
== BFA_TRUE
) {
320 return BFA_STATUS_DEVBUSY
;
322 cee
->get_stats_pending
= BFA_TRUE
;
323 cmd
= (struct bfi_cee_get_req_s
*)cee
->get_stats_mb
.msg
;
325 cee
->cbfn
.get_stats_cbfn
= cbfn
;
326 cee
->cbfn
.get_stats_cbarg
= cbarg
;
327 bfi_h2i_set(cmd
->mh
, BFI_MC_CEE
, BFI_CEE_H2I_GET_STATS_REQ
,
328 bfa_ioc_portid(cee
->ioc
));
329 bfa_dma_be_addr_set(cmd
->dma_addr
, cee
->stats_dma
.pa
);
330 bfa_ioc_mbox_queue(cee
->ioc
, &cee
->get_stats_mb
);
333 return BFA_STATUS_OK
;
337 * bfa_cee_reset_stats()
340 * @param[in] Pointer to the CEE module data structure.
346 bfa_cee_reset_stats(struct bfa_cee_s
*cee
, bfa_cee_reset_stats_cbfn_t cbfn
,
349 struct bfi_cee_reset_stats_s
*cmd
;
351 bfa_assert((cee
!= NULL
) && (cee
->ioc
!= NULL
));
352 if (!bfa_ioc_is_operational(cee
->ioc
)) {
354 return BFA_STATUS_IOC_FAILURE
;
356 if (cee
->reset_stats_pending
== BFA_TRUE
) {
358 return BFA_STATUS_DEVBUSY
;
360 cee
->reset_stats_pending
= BFA_TRUE
;
361 cmd
= (struct bfi_cee_reset_stats_s
*)cee
->reset_stats_mb
.msg
;
362 cee
->cbfn
.reset_stats_cbfn
= cbfn
;
363 cee
->cbfn
.reset_stats_cbarg
= cbarg
;
364 bfi_h2i_set(cmd
->mh
, BFI_MC_CEE
, BFI_CEE_H2I_RESET_STATS
,
365 bfa_ioc_portid(cee
->ioc
));
366 bfa_ioc_mbox_queue(cee
->ioc
, &cee
->reset_stats_mb
);
368 return BFA_STATUS_OK
;
375 * @param[in] Pointer to the CEE module data structure.
381 bfa_cee_isr(void *cbarg
, struct bfi_mbmsg_s
*m
)
383 union bfi_cee_i2h_msg_u
*msg
;
384 struct bfi_cee_get_rsp_s
*get_rsp
;
385 struct bfa_cee_s
*cee
= (struct bfa_cee_s
*)cbarg
;
386 msg
= (union bfi_cee_i2h_msg_u
*)m
;
387 get_rsp
= (struct bfi_cee_get_rsp_s
*)m
;
388 bfa_trc(cee
, msg
->mh
.msg_id
);
389 switch (msg
->mh
.msg_id
) {
390 case BFI_CEE_I2H_GET_CFG_RSP
:
391 bfa_trc(cee
, get_rsp
->cmd_status
);
392 bfa_cee_get_attr_isr(cee
, get_rsp
->cmd_status
);
394 case BFI_CEE_I2H_GET_STATS_RSP
:
395 bfa_cee_get_stats_isr(cee
, get_rsp
->cmd_status
);
397 case BFI_CEE_I2H_RESET_STATS_RSP
:
398 bfa_cee_reset_stats_isr(cee
, get_rsp
->cmd_status
);
409 * @param[in] Pointer to the CEE module data structure.
415 bfa_cee_hbfail(void *arg
)
417 struct bfa_cee_s
*cee
;
418 cee
= (struct bfa_cee_s
*)arg
;
420 if (cee
->get_attr_pending
== BFA_TRUE
) {
421 cee
->get_attr_status
= BFA_STATUS_FAILED
;
422 cee
->get_attr_pending
= BFA_FALSE
;
423 if (cee
->cbfn
.get_attr_cbfn
) {
424 cee
->cbfn
.get_attr_cbfn(cee
->cbfn
.get_attr_cbarg
,
428 if (cee
->get_stats_pending
== BFA_TRUE
) {
429 cee
->get_stats_status
= BFA_STATUS_FAILED
;
430 cee
->get_stats_pending
= BFA_FALSE
;
431 if (cee
->cbfn
.get_stats_cbfn
) {
432 cee
->cbfn
.get_stats_cbfn(cee
->cbfn
.get_stats_cbarg
,
436 if (cee
->reset_stats_pending
== BFA_TRUE
) {
437 cee
->reset_stats_status
= BFA_STATUS_FAILED
;
438 cee
->reset_stats_pending
= BFA_FALSE
;
439 if (cee
->cbfn
.reset_stats_cbfn
) {
440 cee
->cbfn
.reset_stats_cbfn(cee
->cbfn
.reset_stats_cbarg
,
450 * @param[in] cee - Pointer to the CEE module data structure
451 * ioc - Pointer to the ioc module data structure
452 * dev - Pointer to the device driver module data structure
453 * The device driver specific mbox ISR functions have
454 * this pointer as one of the parameters.
461 bfa_cee_attach(struct bfa_cee_s
*cee
, struct bfa_ioc_s
*ioc
, void *dev
,
462 struct bfa_trc_mod_s
*trcmod
, struct bfa_log_mod_s
*logmod
)
464 bfa_assert(cee
!= NULL
);
466 cee
->trcmod
= trcmod
;
467 cee
->logmod
= logmod
;
470 bfa_ioc_mbox_regisr(cee
->ioc
, BFI_MC_CEE
, bfa_cee_isr
, cee
);
471 bfa_ioc_hbfail_init(&cee
->hbfail
, bfa_cee_hbfail
, cee
);
472 bfa_ioc_hbfail_register(cee
->ioc
, &cee
->hbfail
);
480 * @param[in] cee - Pointer to the CEE module data structure
485 bfa_cee_detach(struct bfa_cee_s
*cee
)
488 * For now, just check if there is some ioctl pending and mark that as
491 /* bfa_cee_hbfail(cee); */