static void qedf_process_l2_frame_compl(struct qedf_rport *fcport, struct fc_frame *fp, u16 l2_oxid) { struct fc_lport *lport = fcport->qedf->lport; struct fc_frame_header *fh; u32 crc; fh = (struct fc_frame_header *)fc_frame_header_get(fp); /* Set the OXID we return to what libfc used */ if (l2_oxid != FC_XID_UNKNOWN) fh->fh_ox_id = htons(l2_oxid); /* Setup header fields */ fh->fh_r_ctl = FC_RCTL_ELS_REP; fh->fh_type = FC_TYPE_ELS; /* Last sequence, end sequence */ fh->fh_f_ctl[0] = 0x98; hton24(fh->fh_d_id, lport->port_id); hton24(fh->fh_s_id, fcport->rdata->ids.port_id); fh->fh_rx_id = 0xffff; /* Set frame attributes */ crc = fcoe_fc_crc(fp); fc_frame_init(fp); fr_dev(fp) = lport; fr_sof(fp) = FC_SOF_I3; fr_eof(fp) = FC_EOF_T; fr_crc(fp) = cpu_to_le32(~crc); /* Send completed request to libfc */ fc_exch_recv(lport, fp); }
static void ft_free_cmd(struct ft_cmd *cmd) { struct fc_frame *fp; struct fc_lport *lport; if (!cmd) return; fp = cmd->req_frame; lport = fr_dev(fp); if (fr_seq(fp)) lport->tt.seq_release(fr_seq(fp)); fc_frame_free(fp); ft_sess_put(cmd->sess); /* undo get from lookup at recv */ kfree(cmd); }
static void ft_free_cmd(struct ft_cmd *cmd) { struct fc_frame *fp; struct fc_lport *lport; struct ft_sess *sess; if (!cmd) return; sess = cmd->sess; fp = cmd->req_frame; lport = fr_dev(fp); if (fr_seq(fp)) lport->tt.seq_release(fr_seq(fp)); fc_frame_free(fp); percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag); ft_sess_put(sess); /* undo get from lookup at recv */ }
static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc *cq_desc, struct vnic_rq_buf *buf, int skipped __attribute__((unused)), void *opaque) { struct fnic *fnic = vnic_dev_priv(rq->vdev); struct sk_buff *skb; struct fc_frame *fp; unsigned int eth_hdrs_stripped; u8 type, color, eop, sop, ingress_port, vlan_stripped; u8 fcoe = 0, fcoe_sof, fcoe_eof; u8 fcoe_fc_crc_ok = 1, fcoe_enc_error = 0; u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; u8 ipv6, ipv4, ipv4_fragment, rss_type, csum_not_calc; u8 fcs_ok = 1, packet_error = 0; u16 q_number, completed_index, bytes_written = 0, vlan, checksum; u32 rss_hash; u16 exchange_id, tmpl; u8 sof = 0; u8 eof = 0; u32 fcp_bytes_written = 0; unsigned long flags; pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len, PCI_DMA_FROMDEVICE); skb = buf->os_buf; buf->os_buf = NULL; cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index); if (type == CQ_DESC_TYPE_RQ_FCP) { cq_fcp_rq_desc_dec((struct cq_fcp_rq_desc *)cq_desc, &type, &color, &q_number, &completed_index, &eop, &sop, &fcoe_fc_crc_ok, &exchange_id, &tmpl, &fcp_bytes_written, &sof, &eof, &ingress_port, &packet_error, &fcoe_enc_error, &fcs_ok, &vlan_stripped, &vlan); eth_hdrs_stripped = 1; } else if (type == CQ_DESC_TYPE_RQ_ENET) { cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, &type, &color, &q_number, &completed_index, &ingress_port, &fcoe, &eop, &sop, &rss_type, &csum_not_calc, &rss_hash, &bytes_written, &packet_error, &vlan_stripped, &vlan, &checksum, &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, &fcs_ok); eth_hdrs_stripped = 0; } else { /* wrong CQ type*/ shost_printk(KERN_ERR, fnic->lport->host, "fnic rq_cmpl wrong cq type x%x\n", type); goto drop; } if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) { FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "fnic rq_cmpl fcoe x%x fcsok x%x" " pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err" " x%x\n", fcoe, fcs_ok, packet_error, fcoe_fc_crc_ok, fcoe_enc_error); goto drop; } if (eth_hdrs_stripped) fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof); else if (fnic_import_rq_eth_pkt(skb, bytes_written)) goto drop; fp = (struct fc_frame *)skb; /* * If frame is an ELS response that matches the cached FLOGI OX_ID, * and is accept, issue flogi_reg_request copy wq request to firmware * to register the S_ID and determine whether FC_OUI mode or GW mode. */ if (is_matching_flogi_resp_frame(fnic, fp)) { if (!eth_hdrs_stripped) { if (fc_frame_payload_op(fp) == ELS_LS_ACC) { fnic_handle_flogi_resp(fnic, fp); return; } /* * Recd. Flogi reject. No point registering * with fw, but forward to libFC */ goto forward; } goto drop; } if (!eth_hdrs_stripped) goto drop; forward: spin_lock_irqsave(&fnic->fnic_lock, flags); if (fnic->stop_rx_link_events) { spin_unlock_irqrestore(&fnic->fnic_lock, flags); goto drop; } /* Use fr_flags to indicate whether succ. flogi resp or not */ fr_flags(fp) = 0; fr_dev(fp) = fnic->lport; spin_unlock_irqrestore(&fnic->fnic_lock, flags); skb_queue_tail(&fnic->frame_queue, skb); queue_work(fnic_event_queue, &fnic->frame_work); return; drop: dev_kfree_skb_irq(skb); }