| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | 
					
						
							|  |  |  |  * All rights reserved | 
					
						
							|  |  |  |  * www.brocade.com | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Linux driver for Brocade Fibre Channel Host Bus Adapter. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify it | 
					
						
							|  |  |  |  * under the terms of the GNU General Public License (GPL) Version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, but | 
					
						
							|  |  |  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * General Public License for more details. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  bfa_uf.c BFA unsolicited frame receive implementation | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <bfa.h>
 | 
					
						
							|  |  |  | #include <bfa_svc.h>
 | 
					
						
							|  |  |  | #include <bfi/bfi_uf.h>
 | 
					
						
							|  |  |  | #include <cs/bfa_debug.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BFA_TRC_FILE(HAL, UF); | 
					
						
							|  |  |  | BFA_MODULE(uf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  ***************************************************************************** | 
					
						
							|  |  |  |  * Internal functions | 
					
						
							|  |  |  |  ***************************************************************************** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf = cbarg; | 
					
						
							|  |  |  | 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (complete) | 
					
						
							|  |  |  | 		ufm->ufrecv(ufm->cbarg, uf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32        uf_pb_tot_sz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi); | 
					
						
							|  |  |  | 	ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi); | 
					
						
							|  |  |  | 	uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs), | 
					
						
							|  |  |  | 							BFA_DMA_ALIGN_SZ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz; | 
					
						
							|  |  |  | 	bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfi_uf_buf_post_s *uf_bp_msg; | 
					
						
							|  |  |  | 	struct bfi_sge_s      *sge; | 
					
						
							|  |  |  | 	union bfi_addr_u      sga_zero = { {0} }; | 
					
						
							|  |  |  | 	u16        i; | 
					
						
							|  |  |  | 	u16        buf_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi); | 
					
						
							|  |  |  | 	uf_bp_msg = ufm->uf_buf_posts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; | 
					
						
							|  |  |  | 	     i++, uf_bp_msg++) { | 
					
						
							|  |  |  | 		bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uf_bp_msg->buf_tag = i; | 
					
						
							|  |  |  | 		buf_len = sizeof(struct bfa_uf_buf_s); | 
					
						
							|  |  |  | 		uf_bp_msg->buf_len = bfa_os_htons(buf_len); | 
					
						
							|  |  |  | 		bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, | 
					
						
							|  |  |  | 			    bfa_lpuid(ufm->bfa)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sge = uf_bp_msg->sge; | 
					
						
							|  |  |  | 		sge[0].sg_len = buf_len; | 
					
						
							|  |  |  | 		sge[0].flags = BFI_SGE_DATA_LAST; | 
					
						
							|  |  |  | 		bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i)); | 
					
						
							|  |  |  | 		bfa_sge_to_be(sge); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sge[1].sg_len = buf_len; | 
					
						
							|  |  |  | 		sge[1].flags = BFI_SGE_PGDLEN; | 
					
						
							|  |  |  | 		sge[1].sga = sga_zero; | 
					
						
							|  |  |  | 		bfa_sge_to_be(&sge[1]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * advance pointer beyond consumed memory | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16        i; | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Claim block of memory for UF list | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Initialize UFs and queue it in UF free queue | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { | 
					
						
							|  |  |  | 		bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s)); | 
					
						
							|  |  |  | 		uf->bfa = ufm->bfa; | 
					
						
							|  |  |  | 		uf->uf_tag = i; | 
					
						
							|  |  |  | 		uf->pb_len = sizeof(struct bfa_uf_buf_s); | 
					
						
							|  |  |  | 		uf->buf_kva = (void *)&ufm->uf_pbs_kva[i]; | 
					
						
							|  |  |  | 		uf->buf_pa = ufm_pbs_pa(ufm, i); | 
					
						
							|  |  |  | 		list_add_tail(&uf->qe, &ufm->uf_free_q); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * advance memory pointer | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	bfa_meminfo_kva(mi) = (u8 *) uf; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	claim_uf_pbs(ufm, mi); | 
					
						
							|  |  |  | 	claim_ufs(ufm, mi); | 
					
						
							|  |  |  | 	claim_uf_post_msgs(ufm, mi); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32        num_ufs = cfg->fwcfg.num_uf_bufs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * dma-able memory for UF posted bufs | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	*dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs), | 
					
						
							|  |  |  | 							BFA_DMA_ALIGN_SZ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * kernel Virtual memory for UFs and UF buf post msg copies | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	*ndm_len += sizeof(struct bfa_uf_s) * num_ufs; | 
					
						
							|  |  |  | 	*ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | 
					
						
							|  |  |  | 		  struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s)); | 
					
						
							|  |  |  | 	ufm->bfa = bfa; | 
					
						
							|  |  |  | 	ufm->num_ufs = cfg->fwcfg.num_uf_bufs; | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ufm->uf_free_q); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ufm->uf_posted_q); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uf_mem_claim(ufm, meminfo); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_initdone(struct bfa_s *bfa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_detach(struct bfa_s *bfa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct bfa_uf_s * | 
					
						
							|  |  |  | bfa_uf_get(struct bfa_uf_mod_s *uf_mod) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_q_deq(&uf_mod->uf_free_q, &uf); | 
					
						
							| 
									
										
										
										
											2009-09-25 12:29:54 -07:00
										 |  |  | 	return uf; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	list_add_tail(&uf->qe, &uf_mod->uf_free_q); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bfa_status_t | 
					
						
							|  |  |  | bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfi_uf_buf_post_s *uf_post_msg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); | 
					
						
							|  |  |  | 	if (!uf_post_msg) | 
					
						
							|  |  |  | 		return BFA_STATUS_FAILED; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], | 
					
						
							|  |  |  | 		      sizeof(struct bfi_uf_buf_post_s)); | 
					
						
							|  |  |  | 	bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_trc(ufm->bfa, uf->uf_tag); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	list_add_tail(&uf->qe, &ufm->uf_posted_q); | 
					
						
							|  |  |  | 	return BFA_STATUS_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((uf = bfa_uf_get(uf_mod)) != NULL) { | 
					
						
							|  |  |  | 		if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); | 
					
						
							|  |  |  | 	u16        uf_tag = m->buf_tag; | 
					
						
							|  |  |  | 	struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag]; | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf = &ufm->uf_list[uf_tag]; | 
					
						
							|  |  |  | 	u8        *buf = &uf_buf->d[0]; | 
					
						
							|  |  |  | 	struct fchs_s         *fchs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m->frm_len = bfa_os_ntohs(m->frm_len); | 
					
						
							|  |  |  | 	m->xfr_len = bfa_os_ntohs(m->xfr_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fchs = (struct fchs_s *) uf_buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	list_del(&uf->qe);	/* dequeue from posted queue */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uf->data_ptr = buf; | 
					
						
							|  |  |  | 	uf->data_len = m->xfr_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_assert(uf->data_len >= sizeof(struct fchs_s)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (uf->data_len == sizeof(struct fchs_s)) { | 
					
						
							|  |  |  | 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, | 
					
						
							|  |  |  | 			       uf->data_len, (struct fchs_s *) buf); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		u32        pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); | 
					
						
							|  |  |  | 		bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, | 
					
						
							|  |  |  | 				      BFA_PL_EID_RX, uf->data_len, | 
					
						
							|  |  |  | 				      (struct fchs_s *) buf, pld_w0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_stop(struct bfa_s *bfa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_iocdisable(struct bfa_s *bfa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); | 
					
						
							|  |  |  | 	struct bfa_uf_s   *uf; | 
					
						
							|  |  |  | 	struct list_head        *qe, *qen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	list_for_each_safe(qe, qen, &ufm->uf_posted_q) { | 
					
						
							|  |  |  | 		uf = (struct bfa_uf_s *) qe; | 
					
						
							|  |  |  | 		list_del(&uf->qe); | 
					
						
							|  |  |  | 		bfa_uf_put(ufm, uf); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | bfa_uf_start(struct bfa_s *bfa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bfa_uf_post_all(BFA_UF_MOD(bfa)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  bfa_uf_api | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		Register handler for all unsolicted recieve frames. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param[in]	bfa		BFA instance | 
					
						
							|  |  |  |  * @param[in]	ufrecv	receive handler function | 
					
						
							|  |  |  |  * @param[in]	cbarg	receive handler arg | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ufm->ufrecv = ufrecv; | 
					
						
							|  |  |  | 	ufm->cbarg = cbarg; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		Free an unsolicited frame back to BFA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param[in]		uf		unsolicited frame to be freed | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @return None | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | bfa_uf_free(struct bfa_uf_s *uf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); | 
					
						
							|  |  |  | 	bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  uf_pub BFA uf module public functions | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bfa_trc(bfa, msg->mhdr.msg_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (msg->mhdr.msg_id) { | 
					
						
							|  |  |  | 	case BFI_UF_I2H_FRM_RCVD: | 
					
						
							|  |  |  | 		uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		bfa_trc(bfa, msg->mhdr.msg_id); | 
					
						
							|  |  |  | 		bfa_assert(0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |