2 * Copyright (c) 2005-2010 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.
19 #include "bfa_defs_svc.h"
25 BFA_TRC_FILE(CNA
, PORT
);
27 #define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
30 bfa_port_stats_swap(struct bfa_port_s
*port
, union bfa_port_stats_u
*stats
)
32 u32
*dip
= (u32
*) stats
;
36 for (i
= 0; i
< sizeof(union bfa_port_stats_u
)/sizeof(u32
);
41 dip
[i
] = be32_to_cpu(t0
);
42 dip
[i
+ 1] = be32_to_cpu(t1
);
44 dip
[i
] = be32_to_cpu(t1
);
45 dip
[i
+ 1] = be32_to_cpu(t0
);
51 * bfa_port_enable_isr()
54 * @param[in] port - Pointer to the port module
55 * status - Return status from the f/w
60 bfa_port_enable_isr(struct bfa_port_s
*port
, bfa_status_t status
)
62 bfa_trc(port
, status
);
63 port
->endis_pending
= BFA_FALSE
;
64 port
->endis_cbfn(port
->endis_cbarg
, status
);
68 * bfa_port_disable_isr()
71 * @param[in] port - Pointer to the port module
72 * status - Return status from the f/w
77 bfa_port_disable_isr(struct bfa_port_s
*port
, bfa_status_t status
)
79 bfa_trc(port
, status
);
80 port
->endis_pending
= BFA_FALSE
;
81 port
->endis_cbfn(port
->endis_cbarg
, status
);
85 * bfa_port_get_stats_isr()
88 * @param[in] port - Pointer to the Port module
89 * status - Return status from the f/w
94 bfa_port_get_stats_isr(struct bfa_port_s
*port
, bfa_status_t status
)
96 port
->stats_status
= status
;
97 port
->stats_busy
= BFA_FALSE
;
99 if (status
== BFA_STATUS_OK
) {
102 memcpy(port
->stats
, port
->stats_dma
.kva
,
103 sizeof(union bfa_port_stats_u
));
104 bfa_port_stats_swap(port
, port
->stats
);
106 do_gettimeofday(&tv
);
107 port
->stats
->fc
.secs_reset
= tv
.tv_sec
- port
->stats_reset_time
;
110 if (port
->stats_cbfn
) {
111 port
->stats_cbfn(port
->stats_cbarg
, status
);
112 port
->stats_cbfn
= NULL
;
117 * bfa_port_clear_stats_isr()
120 * @param[in] port - Pointer to the Port module
121 * status - Return status from the f/w
126 bfa_port_clear_stats_isr(struct bfa_port_s
*port
, bfa_status_t status
)
130 port
->stats_status
= status
;
131 port
->stats_busy
= BFA_FALSE
;
134 * re-initialize time stamp for stats reset
136 do_gettimeofday(&tv
);
137 port
->stats_reset_time
= tv
.tv_sec
;
139 if (port
->stats_cbfn
) {
140 port
->stats_cbfn(port
->stats_cbarg
, status
);
141 port
->stats_cbfn
= NULL
;
149 * @param[in] Pointer to the Port module data structure.
154 bfa_port_isr(void *cbarg
, struct bfi_mbmsg_s
*m
)
156 struct bfa_port_s
*port
= (struct bfa_port_s
*) cbarg
;
157 union bfi_port_i2h_msg_u
*i2hmsg
;
159 i2hmsg
= (union bfi_port_i2h_msg_u
*) m
;
160 bfa_trc(port
, m
->mh
.msg_id
);
162 switch (m
->mh
.msg_id
) {
163 case BFI_PORT_I2H_ENABLE_RSP
:
164 if (port
->endis_pending
== BFA_FALSE
)
166 bfa_port_enable_isr(port
, i2hmsg
->enable_rsp
.status
);
169 case BFI_PORT_I2H_DISABLE_RSP
:
170 if (port
->endis_pending
== BFA_FALSE
)
172 bfa_port_disable_isr(port
, i2hmsg
->disable_rsp
.status
);
175 case BFI_PORT_I2H_GET_STATS_RSP
:
176 /* Stats busy flag is still set? (may be cmd timed out) */
177 if (port
->stats_busy
== BFA_FALSE
)
179 bfa_port_get_stats_isr(port
, i2hmsg
->getstats_rsp
.status
);
182 case BFI_PORT_I2H_CLEAR_STATS_RSP
:
183 if (port
->stats_busy
== BFA_FALSE
)
185 bfa_port_clear_stats_isr(port
, i2hmsg
->clearstats_rsp
.status
);
199 * @return Size of DMA region
202 bfa_port_meminfo(void)
204 return BFA_ROUNDUP(sizeof(union bfa_port_stats_u
), BFA_DMA_ALIGN_SZ
);
208 * bfa_port_mem_claim()
211 * @param[in] port Port module pointer
212 * dma_kva Kernel Virtual Address of Port DMA Memory
213 * dma_pa Physical Address of Port DMA Memory
218 bfa_port_mem_claim(struct bfa_port_s
*port
, u8
*dma_kva
, u64 dma_pa
)
220 port
->stats_dma
.kva
= dma_kva
;
221 port
->stats_dma
.pa
= dma_pa
;
227 * Send the Port enable request to the f/w
229 * @param[in] Pointer to the Port module data structure.
234 bfa_port_enable(struct bfa_port_s
*port
, bfa_port_endis_cbfn_t cbfn
,
237 struct bfi_port_generic_req_s
*m
;
239 if (bfa_ioc_is_disabled(port
->ioc
)) {
240 bfa_trc(port
, BFA_STATUS_IOC_DISABLED
);
241 return BFA_STATUS_IOC_DISABLED
;
244 if (!bfa_ioc_is_operational(port
->ioc
)) {
245 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
246 return BFA_STATUS_IOC_FAILURE
;
249 if (port
->endis_pending
) {
250 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
251 return BFA_STATUS_DEVBUSY
;
254 m
= (struct bfi_port_generic_req_s
*) port
->endis_mb
.msg
;
257 port
->endis_cbfn
= cbfn
;
258 port
->endis_cbarg
= cbarg
;
259 port
->endis_pending
= BFA_TRUE
;
261 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_ENABLE_REQ
,
262 bfa_ioc_portid(port
->ioc
));
263 bfa_ioc_mbox_queue(port
->ioc
, &port
->endis_mb
);
265 return BFA_STATUS_OK
;
271 * Send the Port disable request to the f/w
273 * @param[in] Pointer to the Port module data structure.
278 bfa_port_disable(struct bfa_port_s
*port
, bfa_port_endis_cbfn_t cbfn
,
281 struct bfi_port_generic_req_s
*m
;
283 if (bfa_ioc_is_disabled(port
->ioc
)) {
284 bfa_trc(port
, BFA_STATUS_IOC_DISABLED
);
285 return BFA_STATUS_IOC_DISABLED
;
288 if (!bfa_ioc_is_operational(port
->ioc
)) {
289 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
290 return BFA_STATUS_IOC_FAILURE
;
293 if (port
->endis_pending
) {
294 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
295 return BFA_STATUS_DEVBUSY
;
298 m
= (struct bfi_port_generic_req_s
*) port
->endis_mb
.msg
;
301 port
->endis_cbfn
= cbfn
;
302 port
->endis_cbarg
= cbarg
;
303 port
->endis_pending
= BFA_TRUE
;
305 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_DISABLE_REQ
,
306 bfa_ioc_portid(port
->ioc
));
307 bfa_ioc_mbox_queue(port
->ioc
, &port
->endis_mb
);
309 return BFA_STATUS_OK
;
313 * bfa_port_get_stats()
315 * Send the request to the f/w to fetch Port statistics.
317 * @param[in] Pointer to the Port module data structure.
322 bfa_port_get_stats(struct bfa_port_s
*port
, union bfa_port_stats_u
*stats
,
323 bfa_port_stats_cbfn_t cbfn
, void *cbarg
)
325 struct bfi_port_get_stats_req_s
*m
;
327 if (!bfa_ioc_is_operational(port
->ioc
)) {
328 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
329 return BFA_STATUS_IOC_FAILURE
;
332 if (port
->stats_busy
) {
333 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
334 return BFA_STATUS_DEVBUSY
;
337 m
= (struct bfi_port_get_stats_req_s
*) port
->stats_mb
.msg
;
340 port
->stats_cbfn
= cbfn
;
341 port
->stats_cbarg
= cbarg
;
342 port
->stats_busy
= BFA_TRUE
;
343 bfa_dma_be_addr_set(m
->dma_addr
, port
->stats_dma
.pa
);
345 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_GET_STATS_REQ
,
346 bfa_ioc_portid(port
->ioc
));
347 bfa_ioc_mbox_queue(port
->ioc
, &port
->stats_mb
);
349 return BFA_STATUS_OK
;
353 * bfa_port_clear_stats()
356 * @param[in] Pointer to the Port module data structure.
361 bfa_port_clear_stats(struct bfa_port_s
*port
, bfa_port_stats_cbfn_t cbfn
,
364 struct bfi_port_generic_req_s
*m
;
366 if (!bfa_ioc_is_operational(port
->ioc
)) {
367 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
368 return BFA_STATUS_IOC_FAILURE
;
371 if (port
->stats_busy
) {
372 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
373 return BFA_STATUS_DEVBUSY
;
376 m
= (struct bfi_port_generic_req_s
*) port
->stats_mb
.msg
;
378 port
->stats_cbfn
= cbfn
;
379 port
->stats_cbarg
= cbarg
;
380 port
->stats_busy
= BFA_TRUE
;
382 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_CLEAR_STATS_REQ
,
383 bfa_ioc_portid(port
->ioc
));
384 bfa_ioc_mbox_queue(port
->ioc
, &port
->stats_mb
);
386 return BFA_STATUS_OK
;
393 * @param[in] Pointer to the Port module data structure.
398 bfa_port_hbfail(void *arg
)
400 struct bfa_port_s
*port
= (struct bfa_port_s
*) arg
;
402 /* Fail any pending get_stats/clear_stats requests */
403 if (port
->stats_busy
) {
404 if (port
->stats_cbfn
)
405 port
->stats_cbfn(port
->stats_cbarg
, BFA_STATUS_FAILED
);
406 port
->stats_cbfn
= NULL
;
407 port
->stats_busy
= BFA_FALSE
;
410 /* Clear any enable/disable is pending */
411 if (port
->endis_pending
) {
412 if (port
->endis_cbfn
)
413 port
->endis_cbfn(port
->endis_cbarg
, BFA_STATUS_FAILED
);
414 port
->endis_cbfn
= NULL
;
415 port
->endis_pending
= BFA_FALSE
;
423 * @param[in] port - Pointer to the Port module data structure
424 * ioc - Pointer to the ioc module data structure
425 * dev - Pointer to the device driver module data structure
426 * The device driver specific mbox ISR functions have
427 * this pointer as one of the parameters.
433 bfa_port_attach(struct bfa_port_s
*port
, struct bfa_ioc_s
*ioc
,
434 void *dev
, struct bfa_trc_mod_s
*trcmod
)
442 port
->trcmod
= trcmod
;
444 port
->stats_busy
= BFA_FALSE
;
445 port
->endis_pending
= BFA_FALSE
;
446 port
->stats_cbfn
= NULL
;
447 port
->endis_cbfn
= NULL
;
449 bfa_ioc_mbox_regisr(port
->ioc
, BFI_MC_PORT
, bfa_port_isr
, port
);
450 bfa_ioc_hbfail_init(&port
->hbfail
, bfa_port_hbfail
, port
);
451 list_add_tail(&port
->hbfail
.qe
, &port
->ioc
->hb_notify_q
);
454 * initialize time stamp for stats reset
456 do_gettimeofday(&tv
);
457 port
->stats_reset_time
= tv
.tv_sec
;