Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.35 345 lines 7.9 kB view raw
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 * bfa_uf.c BFA unsolicited frame receive implementation 20 */ 21 22#include <bfa.h> 23#include <bfa_svc.h> 24#include <bfi/bfi_uf.h> 25#include <cs/bfa_debug.h> 26 27BFA_TRC_FILE(HAL, UF); 28BFA_MODULE(uf); 29 30/* 31 ***************************************************************************** 32 * Internal functions 33 ***************************************************************************** 34 */ 35static void 36__bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) 37{ 38 struct bfa_uf_s *uf = cbarg; 39 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); 40 41 if (complete) 42 ufm->ufrecv(ufm->cbarg, uf); 43} 44 45static void 46claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 47{ 48 u32 uf_pb_tot_sz; 49 50 ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi); 51 ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi); 52 uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs), 53 BFA_DMA_ALIGN_SZ); 54 55 bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz; 56 bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz; 57 58 bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz); 59} 60 61static void 62claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 63{ 64 struct bfi_uf_buf_post_s *uf_bp_msg; 65 struct bfi_sge_s *sge; 66 union bfi_addr_u sga_zero = { {0} }; 67 u16 i; 68 u16 buf_len; 69 70 ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi); 71 uf_bp_msg = ufm->uf_buf_posts; 72 73 for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; 74 i++, uf_bp_msg++) { 75 bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); 76 77 uf_bp_msg->buf_tag = i; 78 buf_len = sizeof(struct bfa_uf_buf_s); 79 uf_bp_msg->buf_len = bfa_os_htons(buf_len); 80 bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, 81 bfa_lpuid(ufm->bfa)); 82 83 sge = uf_bp_msg->sge; 84 sge[0].sg_len = buf_len; 85 sge[0].flags = BFI_SGE_DATA_LAST; 86 bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i)); 87 bfa_sge_to_be(sge); 88 89 sge[1].sg_len = buf_len; 90 sge[1].flags = BFI_SGE_PGDLEN; 91 sge[1].sga = sga_zero; 92 bfa_sge_to_be(&sge[1]); 93 } 94 95 /** 96 * advance pointer beyond consumed memory 97 */ 98 bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg; 99} 100 101static void 102claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 103{ 104 u16 i; 105 struct bfa_uf_s *uf; 106 107 /* 108 * Claim block of memory for UF list 109 */ 110 ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi); 111 112 /* 113 * Initialize UFs and queue it in UF free queue 114 */ 115 for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { 116 bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s)); 117 uf->bfa = ufm->bfa; 118 uf->uf_tag = i; 119 uf->pb_len = sizeof(struct bfa_uf_buf_s); 120 uf->buf_kva = (void *)&ufm->uf_pbs_kva[i]; 121 uf->buf_pa = ufm_pbs_pa(ufm, i); 122 list_add_tail(&uf->qe, &ufm->uf_free_q); 123 } 124 125 /** 126 * advance memory pointer 127 */ 128 bfa_meminfo_kva(mi) = (u8 *) uf; 129} 130 131static void 132uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 133{ 134 claim_uf_pbs(ufm, mi); 135 claim_ufs(ufm, mi); 136 claim_uf_post_msgs(ufm, mi); 137} 138 139static void 140bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) 141{ 142 u32 num_ufs = cfg->fwcfg.num_uf_bufs; 143 144 /* 145 * dma-able memory for UF posted bufs 146 */ 147 *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs), 148 BFA_DMA_ALIGN_SZ); 149 150 /* 151 * kernel Virtual memory for UFs and UF buf post msg copies 152 */ 153 *ndm_len += sizeof(struct bfa_uf_s) * num_ufs; 154 *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs; 155} 156 157static void 158bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 159 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 160{ 161 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 162 163 bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s)); 164 ufm->bfa = bfa; 165 ufm->num_ufs = cfg->fwcfg.num_uf_bufs; 166 INIT_LIST_HEAD(&ufm->uf_free_q); 167 INIT_LIST_HEAD(&ufm->uf_posted_q); 168 169 uf_mem_claim(ufm, meminfo); 170} 171 172static void 173bfa_uf_initdone(struct bfa_s *bfa) 174{ 175} 176 177static void 178bfa_uf_detach(struct bfa_s *bfa) 179{ 180} 181 182static struct bfa_uf_s * 183bfa_uf_get(struct bfa_uf_mod_s *uf_mod) 184{ 185 struct bfa_uf_s *uf; 186 187 bfa_q_deq(&uf_mod->uf_free_q, &uf); 188 return uf; 189} 190 191static void 192bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) 193{ 194 list_add_tail(&uf->qe, &uf_mod->uf_free_q); 195} 196 197static bfa_status_t 198bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) 199{ 200 struct bfi_uf_buf_post_s *uf_post_msg; 201 202 uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); 203 if (!uf_post_msg) 204 return BFA_STATUS_FAILED; 205 206 bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], 207 sizeof(struct bfi_uf_buf_post_s)); 208 bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP); 209 210 bfa_trc(ufm->bfa, uf->uf_tag); 211 212 list_add_tail(&uf->qe, &ufm->uf_posted_q); 213 return BFA_STATUS_OK; 214} 215 216static void 217bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) 218{ 219 struct bfa_uf_s *uf; 220 221 while ((uf = bfa_uf_get(uf_mod)) != NULL) { 222 if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) 223 break; 224 } 225} 226 227static void 228uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) 229{ 230 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 231 u16 uf_tag = m->buf_tag; 232 struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag]; 233 struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; 234 u8 *buf = &uf_buf->d[0]; 235 struct fchs_s *fchs; 236 237 m->frm_len = bfa_os_ntohs(m->frm_len); 238 m->xfr_len = bfa_os_ntohs(m->xfr_len); 239 240 fchs = (struct fchs_s *) uf_buf; 241 242 list_del(&uf->qe); /* dequeue from posted queue */ 243 244 uf->data_ptr = buf; 245 uf->data_len = m->xfr_len; 246 247 bfa_assert(uf->data_len >= sizeof(struct fchs_s)); 248 249 if (uf->data_len == sizeof(struct fchs_s)) { 250 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, 251 uf->data_len, (struct fchs_s *) buf); 252 } else { 253 u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); 254 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, 255 BFA_PL_EID_RX, uf->data_len, 256 (struct fchs_s *) buf, pld_w0); 257 } 258 259 bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); 260} 261 262static void 263bfa_uf_stop(struct bfa_s *bfa) 264{ 265} 266 267static void 268bfa_uf_iocdisable(struct bfa_s *bfa) 269{ 270 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 271 struct bfa_uf_s *uf; 272 struct list_head *qe, *qen; 273 274 list_for_each_safe(qe, qen, &ufm->uf_posted_q) { 275 uf = (struct bfa_uf_s *) qe; 276 list_del(&uf->qe); 277 bfa_uf_put(ufm, uf); 278 } 279} 280 281static void 282bfa_uf_start(struct bfa_s *bfa) 283{ 284 bfa_uf_post_all(BFA_UF_MOD(bfa)); 285} 286 287 288 289/** 290 * bfa_uf_api 291 */ 292 293/** 294 * Register handler for all unsolicted recieve frames. 295 * 296 * @param[in] bfa BFA instance 297 * @param[in] ufrecv receive handler function 298 * @param[in] cbarg receive handler arg 299 */ 300void 301bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) 302{ 303 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 304 305 ufm->ufrecv = ufrecv; 306 ufm->cbarg = cbarg; 307} 308 309/** 310 * Free an unsolicited frame back to BFA. 311 * 312 * @param[in] uf unsolicited frame to be freed 313 * 314 * @return None 315 */ 316void 317bfa_uf_free(struct bfa_uf_s *uf) 318{ 319 bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); 320 bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); 321} 322 323 324 325/** 326 * uf_pub BFA uf module public functions 327 */ 328 329void 330bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 331{ 332 bfa_trc(bfa, msg->mhdr.msg_id); 333 334 switch (msg->mhdr.msg_id) { 335 case BFI_UF_I2H_FRM_RCVD: 336 uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); 337 break; 338 339 default: 340 bfa_trc(bfa, msg->mhdr.msg_id); 341 bfa_assert(0); 342 } 343} 344 345