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_fcs_uf.c BFA FCS UF ( Unsolicited Frames) 20 */ 21 22#include <fcs/bfa_fcs.h> 23#include <bfa_svc.h> 24#include <fcs/bfa_fcs_fabric.h> 25#include "fcs.h" 26#include "fcs_trcmod.h" 27#include "fcs_fabric.h" 28#include "fcs_uf.h" 29 30BFA_TRC_FILE(FCS, UF); 31 32/** 33 * BFA callback for unsolicited frame receive handler. 34 * 35 * @param[in] cbarg callback arg for receive handler 36 * @param[in] uf unsolicited frame descriptor 37 * 38 * @return None 39 */ 40static void 41bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf) 42{ 43 struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg; 44 struct fchs_s *fchs = bfa_uf_get_frmbuf(uf); 45 u16 len = bfa_uf_get_frmlen(uf); 46 struct fc_vft_s *vft; 47 struct bfa_fcs_fabric_s *fabric; 48 49 /** 50 * check for VFT header 51 */ 52 if (fchs->routing == FC_RTG_EXT_HDR && 53 fchs->cat_info == FC_CAT_VFT_HDR) { 54 bfa_stats(fcs, uf.tagged); 55 vft = bfa_uf_get_frmbuf(uf); 56 if (fcs->port_vfid == vft->vf_id) 57 fabric = &fcs->fabric; 58 else 59 fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id); 60 61 /** 62 * drop frame if vfid is unknown 63 */ 64 if (!fabric) { 65 bfa_assert(0); 66 bfa_stats(fcs, uf.vfid_unknown); 67 bfa_uf_free(uf); 68 return; 69 } 70 71 /** 72 * skip vft header 73 */ 74 fchs = (struct fchs_s *) (vft + 1); 75 len -= sizeof(struct fc_vft_s); 76 77 bfa_trc(fcs, vft->vf_id); 78 } else { 79 bfa_stats(fcs, uf.untagged); 80 fabric = &fcs->fabric; 81 } 82 83 bfa_trc(fcs, ((u32 *) fchs)[0]); 84 bfa_trc(fcs, ((u32 *) fchs)[1]); 85 bfa_trc(fcs, ((u32 *) fchs)[2]); 86 bfa_trc(fcs, ((u32 *) fchs)[3]); 87 bfa_trc(fcs, ((u32 *) fchs)[4]); 88 bfa_trc(fcs, ((u32 *) fchs)[5]); 89 bfa_trc(fcs, len); 90 91 bfa_fcs_fabric_uf_recv(fabric, fchs, len); 92 bfa_uf_free(uf); 93} 94 95void 96bfa_fcs_uf_attach(struct bfa_fcs_s *fcs) 97{ 98 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); 99} 100