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_port.h>
19 #include <cs/bfa_trc.h>
20 #include <cs/bfa_log.h>
21 #include <cs/bfa_debug.h>
22 #include <port/bfa_port.h>
24 #include <bfi/bfi_port.h>
26 #include <cna/bfa_cna_trcmod.h>
28 BFA_TRC_FILE(CNA
, PORT
);
30 #define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31 #define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
34 bfa_port_stats_swap(struct bfa_port_s
*port
, union bfa_pport_stats_u
*stats
)
36 u32
*dip
= (u32
*) stats
;
40 for (i
= 0; i
< sizeof(union bfa_pport_stats_u
) / sizeof(u32
);
45 dip
[i
] = bfa_os_ntohl(t0
);
46 dip
[i
+ 1] = bfa_os_ntohl(t1
);
48 dip
[i
] = bfa_os_ntohl(t1
);
49 dip
[i
+ 1] = bfa_os_ntohl(t0
);
54 * QoS stats r also swapped as 64bit; that structure also
55 * has to use 64 bit counters
60 * bfa_port_enable_isr()
63 * @param[in] port - Pointer to the port module
64 * status - Return status from the f/w
69 bfa_port_enable_isr(struct bfa_port_s
*port
, bfa_status_t status
)
75 * bfa_port_disable_isr()
78 * @param[in] port - Pointer to the port module
79 * status - Return status from the f/w
84 bfa_port_disable_isr(struct bfa_port_s
*port
, bfa_status_t status
)
90 * bfa_port_get_stats_isr()
93 * @param[in] port - Pointer to the Port module
94 * status - Return status from the f/w
99 bfa_port_get_stats_isr(struct bfa_port_s
*port
, bfa_status_t status
)
101 port
->stats_status
= status
;
102 port
->stats_busy
= BFA_FALSE
;
104 if (status
== BFA_STATUS_OK
) {
105 memcpy(port
->stats
, port
->stats_dma
.kva
,
106 sizeof(union bfa_pport_stats_u
));
107 bfa_port_stats_swap(port
, port
->stats
);
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
)
128 port
->stats_status
= status
;
129 port
->stats_busy
= BFA_FALSE
;
131 if (port
->stats_cbfn
) {
132 port
->stats_cbfn(port
->stats_cbarg
, status
);
133 port
->stats_cbfn
= NULL
;
141 * @param[in] Pointer to the Port module data structure.
146 bfa_port_isr(void *cbarg
, struct bfi_mbmsg_s
*m
)
148 struct bfa_port_s
*port
= (struct bfa_port_s
*)cbarg
;
149 union bfi_port_i2h_msg_u
*i2hmsg
;
151 i2hmsg
= (union bfi_port_i2h_msg_u
*)m
;
152 bfa_trc(port
, m
->mh
.msg_id
);
154 switch (m
->mh
.msg_id
) {
155 case BFI_PORT_I2H_ENABLE_RSP
:
156 if (port
->endis_pending
== BFA_FALSE
)
158 bfa_port_enable_isr(port
, i2hmsg
->enable_rsp
.status
);
161 case BFI_PORT_I2H_DISABLE_RSP
:
162 if (port
->endis_pending
== BFA_FALSE
)
164 bfa_port_disable_isr(port
, i2hmsg
->disable_rsp
.status
);
167 case BFI_PORT_I2H_GET_STATS_RSP
:
169 * Stats busy flag is still set? (may be cmd timed out)
171 if (port
->stats_busy
== BFA_FALSE
)
173 bfa_port_get_stats_isr(port
, i2hmsg
->getstats_rsp
.status
);
176 case BFI_PORT_I2H_CLEAR_STATS_RSP
:
177 if (port
->stats_busy
== BFA_FALSE
)
179 bfa_port_clear_stats_isr(port
, i2hmsg
->clearstats_rsp
.status
);
193 * @return Size of DMA region
196 bfa_port_meminfo(void)
198 return BFA_ROUNDUP(sizeof(union bfa_pport_stats_u
), BFA_DMA_ALIGN_SZ
);
202 * bfa_port_mem_claim()
205 * @param[in] port Port module pointer
206 * dma_kva Kernel Virtual Address of Port DMA Memory
207 * dma_pa Physical Address of Port DMA Memory
212 bfa_port_mem_claim(struct bfa_port_s
*port
, u8
*dma_kva
, u64 dma_pa
)
214 port
->stats_dma
.kva
= dma_kva
;
215 port
->stats_dma
.pa
= dma_pa
;
221 * Send the Port enable request to the f/w
223 * @param[in] Pointer to the Port module data structure.
228 bfa_port_enable(struct bfa_port_s
*port
, bfa_port_endis_cbfn_t cbfn
,
231 struct bfi_port_generic_req_s
*m
;
233 /** todo Not implemented */
236 if (!bfa_ioc_is_operational(port
->ioc
)) {
237 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
238 return BFA_STATUS_IOC_FAILURE
;
241 if (port
->endis_pending
) {
242 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
243 return BFA_STATUS_DEVBUSY
;
246 m
= (struct bfi_port_generic_req_s
*)port
->endis_mb
.msg
;
249 port
->endis_cbfn
= cbfn
;
250 port
->endis_cbarg
= cbarg
;
251 port
->endis_pending
= BFA_TRUE
;
253 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_ENABLE_REQ
,
254 bfa_ioc_portid(port
->ioc
));
255 bfa_ioc_mbox_queue(port
->ioc
, &port
->endis_mb
);
257 return BFA_STATUS_OK
;
263 * Send the Port disable request to the f/w
265 * @param[in] Pointer to the Port module data structure.
270 bfa_port_disable(struct bfa_port_s
*port
, bfa_port_endis_cbfn_t cbfn
,
273 struct bfi_port_generic_req_s
*m
;
275 /** todo Not implemented */
278 if (!bfa_ioc_is_operational(port
->ioc
)) {
279 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
280 return BFA_STATUS_IOC_FAILURE
;
283 if (port
->endis_pending
) {
284 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
285 return BFA_STATUS_DEVBUSY
;
288 m
= (struct bfi_port_generic_req_s
*)port
->endis_mb
.msg
;
291 port
->endis_cbfn
= cbfn
;
292 port
->endis_cbarg
= cbarg
;
293 port
->endis_pending
= BFA_TRUE
;
295 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_DISABLE_REQ
,
296 bfa_ioc_portid(port
->ioc
));
297 bfa_ioc_mbox_queue(port
->ioc
, &port
->endis_mb
);
299 return BFA_STATUS_OK
;
303 * bfa_port_get_stats()
305 * Send the request to the f/w to fetch Port statistics.
307 * @param[in] Pointer to the Port module data structure.
312 bfa_port_get_stats(struct bfa_port_s
*port
, union bfa_pport_stats_u
*stats
,
313 bfa_port_stats_cbfn_t cbfn
, void *cbarg
)
315 struct bfi_port_get_stats_req_s
*m
;
317 if (!bfa_ioc_is_operational(port
->ioc
)) {
318 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
319 return BFA_STATUS_IOC_FAILURE
;
322 if (port
->stats_busy
) {
323 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
324 return BFA_STATUS_DEVBUSY
;
327 m
= (struct bfi_port_get_stats_req_s
*)port
->stats_mb
.msg
;
330 port
->stats_cbfn
= cbfn
;
331 port
->stats_cbarg
= cbarg
;
332 port
->stats_busy
= BFA_TRUE
;
333 bfa_dma_be_addr_set(m
->dma_addr
, port
->stats_dma
.pa
);
335 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_GET_STATS_REQ
,
336 bfa_ioc_portid(port
->ioc
));
337 bfa_ioc_mbox_queue(port
->ioc
, &port
->stats_mb
);
339 return BFA_STATUS_OK
;
343 * bfa_port_clear_stats()
346 * @param[in] Pointer to the Port module data structure.
351 bfa_port_clear_stats(struct bfa_port_s
*port
, bfa_port_stats_cbfn_t cbfn
,
354 struct bfi_port_generic_req_s
*m
;
356 if (!bfa_ioc_is_operational(port
->ioc
)) {
357 bfa_trc(port
, BFA_STATUS_IOC_FAILURE
);
358 return BFA_STATUS_IOC_FAILURE
;
361 if (port
->stats_busy
) {
362 bfa_trc(port
, BFA_STATUS_DEVBUSY
);
363 return BFA_STATUS_DEVBUSY
;
366 m
= (struct bfi_port_generic_req_s
*)port
->stats_mb
.msg
;
368 port
->stats_cbfn
= cbfn
;
369 port
->stats_cbarg
= cbarg
;
370 port
->stats_busy
= BFA_TRUE
;
372 bfi_h2i_set(m
->mh
, BFI_MC_PORT
, BFI_PORT_H2I_CLEAR_STATS_REQ
,
373 bfa_ioc_portid(port
->ioc
));
374 bfa_ioc_mbox_queue(port
->ioc
, &port
->stats_mb
);
376 return BFA_STATUS_OK
;
383 * @param[in] Pointer to the Port module data structure.
388 bfa_port_hbfail(void *arg
)
390 struct bfa_port_s
*port
= (struct bfa_port_s
*)arg
;
393 * Fail any pending get_stats/clear_stats requests
395 if (port
->stats_busy
) {
396 if (port
->stats_cbfn
)
397 port
->stats_cbfn(port
->dev
, BFA_STATUS_FAILED
);
398 port
->stats_cbfn
= NULL
;
399 port
->stats_busy
= BFA_FALSE
;
403 * Clear any enable/disable is pending
405 if (port
->endis_pending
) {
406 if (port
->endis_cbfn
)
407 port
->endis_cbfn(port
->dev
, BFA_STATUS_FAILED
);
408 port
->endis_cbfn
= NULL
;
409 port
->endis_pending
= BFA_FALSE
;
417 * @param[in] port - Pointer to the Port module data structure
418 * ioc - Pointer to the ioc module data structure
419 * dev - Pointer to the device driver module data structure
420 * The device driver specific mbox ISR functions have
421 * this pointer as one of the parameters.
428 bfa_port_attach(struct bfa_port_s
*port
, struct bfa_ioc_s
*ioc
, void *dev
,
429 struct bfa_trc_mod_s
*trcmod
, struct bfa_log_mod_s
*logmod
)
435 port
->trcmod
= trcmod
;
436 port
->logmod
= logmod
;
438 port
->stats_busy
= port
->endis_pending
= BFA_FALSE
;
439 port
->stats_cbfn
= port
->endis_cbfn
= NULL
;
441 bfa_ioc_mbox_regisr(port
->ioc
, BFI_MC_PORT
, bfa_port_isr
, port
);
442 bfa_ioc_hbfail_init(&port
->hbfail
, bfa_port_hbfail
, port
);
443 bfa_ioc_hbfail_register(port
->ioc
, &port
->hbfail
);
452 * @param[in] port - Pointer to the Port module data structure
457 bfa_port_detach(struct bfa_port_s
*port
)