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); */