aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fnic
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/fnic
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/fnic')
-rw-r--r--drivers/scsi/fnic/fnic.h27
-rw-r--r--drivers/scsi/fnic/fnic_fcs.c500
-rw-r--r--drivers/scsi/fnic/fnic_isr.c18
-rw-r--r--drivers/scsi/fnic/fnic_main.c109
-rw-r--r--drivers/scsi/fnic/fnic_res.c5
-rw-r--r--drivers/scsi/fnic/fnic_res.h54
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c97
-rw-r--r--drivers/scsi/fnic/vnic_dev.c1
-rw-r--r--drivers/scsi/fnic/vnic_devcmd.h2
-rw-r--r--drivers/scsi/fnic/vnic_rq.c1
-rw-r--r--drivers/scsi/fnic/vnic_scsi.h1
-rw-r--r--drivers/scsi/fnic/vnic_wq.c1
12 files changed, 426 insertions, 390 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index e4c0a3d7d87b..3966c71d0095 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -22,6 +22,7 @@
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <scsi/libfc.h> 24#include <scsi/libfc.h>
25#include <scsi/libfcoe.h>
25#include "fnic_io.h" 26#include "fnic_io.h"
26#include "fnic_res.h" 27#include "fnic_res.h"
27#include "vnic_dev.h" 28#include "vnic_dev.h"
@@ -35,7 +36,7 @@
35 36
36#define DRV_NAME "fnic" 37#define DRV_NAME "fnic"
37#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" 38#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
38#define DRV_VERSION "1.0.0.1121" 39#define DRV_VERSION "1.4.0.98"
39#define PFX DRV_NAME ": " 40#define PFX DRV_NAME ": "
40#define DFX DRV_NAME "%d: " 41#define DFX DRV_NAME "%d: "
41 42
@@ -44,7 +45,7 @@
44#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */ 45#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */
45#define FNIC_DFLT_QUEUE_DEPTH 32 46#define FNIC_DFLT_QUEUE_DEPTH 32
46#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */ 47#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
47 48#define FNIC_MAX_CMD_LEN 16 /* Supported CDB length */
48/* 49/*
49 * Tag bits used for special requests. 50 * Tag bits used for special requests.
50 */ 51 */
@@ -145,6 +146,7 @@ struct mempool;
145/* Per-instance private data structure */ 146/* Per-instance private data structure */
146struct fnic { 147struct fnic {
147 struct fc_lport *lport; 148 struct fc_lport *lport;
149 struct fcoe_ctlr ctlr; /* FIP FCoE controller structure */
148 struct vnic_dev_bar bar0; 150 struct vnic_dev_bar bar0;
149 151
150 struct msix_entry msix_entry[FNIC_MSIX_INTR_MAX]; 152 struct msix_entry msix_entry[FNIC_MSIX_INTR_MAX];
@@ -162,23 +164,16 @@ struct fnic {
162 unsigned int wq_count; 164 unsigned int wq_count;
163 unsigned int cq_count; 165 unsigned int cq_count;
164 166
165 u32 fcoui_mode:1; /* use fcoui address*/
166 u32 vlan_hw_insert:1; /* let hw insert the tag */ 167 u32 vlan_hw_insert:1; /* let hw insert the tag */
167 u32 in_remove:1; /* fnic device in removal */ 168 u32 in_remove:1; /* fnic device in removal */
168 u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */ 169 u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */
169 170
170 struct completion *remove_wait; /* device remove thread blocks */ 171 struct completion *remove_wait; /* device remove thread blocks */
171 172
172 struct fc_frame *flogi;
173 struct fc_frame *flogi_resp;
174 u16 flogi_oxid;
175 unsigned long s_id;
176 enum fnic_state state; 173 enum fnic_state state;
177 spinlock_t fnic_lock; 174 spinlock_t fnic_lock;
178 175
179 u16 vlan_id; /* VLAN tag including priority */ 176 u16 vlan_id; /* VLAN tag including priority */
180 u8 mac_addr[ETH_ALEN];
181 u8 dest_addr[ETH_ALEN];
182 u8 data_src_addr[ETH_ALEN]; 177 u8 data_src_addr[ETH_ALEN];
183 u64 fcp_input_bytes; /* internal statistic */ 178 u64 fcp_input_bytes; /* internal statistic */
184 u64 fcp_output_bytes; /* internal statistic */ 179 u64 fcp_output_bytes; /* internal statistic */
@@ -205,6 +200,7 @@ struct fnic {
205 struct work_struct link_work; 200 struct work_struct link_work;
206 struct work_struct frame_work; 201 struct work_struct frame_work;
207 struct sk_buff_head frame_queue; 202 struct sk_buff_head frame_queue;
203 struct sk_buff_head tx_queue;
208 204
209 /* copy work queue cache line section */ 205 /* copy work queue cache line section */
210 ____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; 206 ____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX];
@@ -224,6 +220,11 @@ struct fnic {
224 ____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX]; 220 ____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX];
225}; 221};
226 222
223static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
224{
225 return container_of(fip, struct fnic, ctlr);
226}
227
227extern struct workqueue_struct *fnic_event_queue; 228extern struct workqueue_struct *fnic_event_queue;
228extern struct device_attribute *fnic_attrs[]; 229extern struct device_attribute *fnic_attrs[];
229 230
@@ -239,7 +240,11 @@ void fnic_handle_link(struct work_struct *work);
239int fnic_rq_cmpl_handler(struct fnic *fnic, int); 240int fnic_rq_cmpl_handler(struct fnic *fnic, int);
240int fnic_alloc_rq_frame(struct vnic_rq *rq); 241int fnic_alloc_rq_frame(struct vnic_rq *rq);
241void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); 242void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
242int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp); 243void fnic_flush_tx(struct fnic *);
244void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb);
245void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
246void fnic_update_mac(struct fc_lport *, u8 *new);
247void fnic_update_mac_locked(struct fnic *, u8 *new);
243 248
244int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); 249int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
245int fnic_abort_cmd(struct scsi_cmnd *); 250int fnic_abort_cmd(struct scsi_cmnd *);
@@ -252,7 +257,7 @@ void fnic_empty_scsi_cleanup(struct fc_lport *);
252void fnic_exch_mgr_reset(struct fc_lport *, u32, u32); 257void fnic_exch_mgr_reset(struct fc_lport *, u32, u32);
253int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int); 258int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int);
254int fnic_wq_cmpl_handler(struct fnic *fnic, int); 259int fnic_wq_cmpl_handler(struct fnic *fnic, int);
255int fnic_flogi_reg_handler(struct fnic *fnic); 260int fnic_flogi_reg_handler(struct fnic *fnic, u32);
256void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq, 261void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
257 struct fcpio_host_req *desc); 262 struct fcpio_host_req *desc);
258int fnic_fw_reset_handler(struct fnic *fnic); 263int fnic_fw_reset_handler(struct fnic *fnic);
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 50db3e36a619..5259888fbfb1 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -17,12 +17,14 @@
17 */ 17 */
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/slab.h>
20#include <linux/skbuff.h> 21#include <linux/skbuff.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
23#include <linux/if_ether.h> 24#include <linux/if_ether.h>
24#include <linux/if_vlan.h> 25#include <linux/if_vlan.h>
25#include <linux/workqueue.h> 26#include <linux/workqueue.h>
27#include <scsi/fc/fc_fip.h>
26#include <scsi/fc/fc_els.h> 28#include <scsi/fc/fc_els.h>
27#include <scsi/fc/fc_fcoe.h> 29#include <scsi/fc/fc_fcoe.h>
28#include <scsi/fc_frame.h> 30#include <scsi/fc_frame.h>
@@ -34,6 +36,8 @@
34 36
35struct workqueue_struct *fnic_event_queue; 37struct workqueue_struct *fnic_event_queue;
36 38
39static void fnic_set_eth_mode(struct fnic *);
40
37void fnic_handle_link(struct work_struct *work) 41void fnic_handle_link(struct work_struct *work)
38{ 42{
39 struct fnic *fnic = container_of(work, struct fnic, link_work); 43 struct fnic *fnic = container_of(work, struct fnic, link_work);
@@ -64,10 +68,10 @@ void fnic_handle_link(struct work_struct *work)
64 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 68 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
65 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 69 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
66 "link down\n"); 70 "link down\n");
67 fc_linkdown(fnic->lport); 71 fcoe_ctlr_link_down(&fnic->ctlr);
68 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 72 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
69 "link up\n"); 73 "link up\n");
70 fc_linkup(fnic->lport); 74 fcoe_ctlr_link_up(&fnic->ctlr);
71 } else 75 } else
72 /* UP -> UP */ 76 /* UP -> UP */
73 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 77 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
@@ -76,13 +80,13 @@ void fnic_handle_link(struct work_struct *work)
76 /* DOWN -> UP */ 80 /* DOWN -> UP */
77 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 81 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
78 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); 82 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
79 fc_linkup(fnic->lport); 83 fcoe_ctlr_link_up(&fnic->ctlr);
80 } else { 84 } else {
81 /* UP -> DOWN */ 85 /* UP -> DOWN */
82 fnic->lport->host_stats.link_failure_count++; 86 fnic->lport->host_stats.link_failure_count++;
83 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 87 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
84 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); 88 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
85 fc_linkdown(fnic->lport); 89 fcoe_ctlr_link_down(&fnic->ctlr);
86 } 90 }
87 91
88} 92}
@@ -107,197 +111,179 @@ void fnic_handle_frame(struct work_struct *work)
107 return; 111 return;
108 } 112 }
109 fp = (struct fc_frame *)skb; 113 fp = (struct fc_frame *)skb;
110 /* if Flogi resp frame, register the address */ 114
111 if (fr_flags(fp)) { 115 /*
112 vnic_dev_add_addr(fnic->vdev, 116 * If we're in a transitional state, just re-queue and return.
113 fnic->data_src_addr); 117 * The queue will be serviced when we get to a stable state.
114 fr_flags(fp) = 0; 118 */
119 if (fnic->state != FNIC_IN_FC_MODE &&
120 fnic->state != FNIC_IN_ETH_MODE) {
121 skb_queue_head(&fnic->frame_queue, skb);
122 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
123 return;
115 } 124 }
116 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 125 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
117 126
118 fc_exch_recv(lp, fp); 127 fc_exch_recv(lp, fp);
119 } 128 }
120
121}
122
123static inline void fnic_import_rq_fc_frame(struct sk_buff *skb,
124 u32 len, u8 sof, u8 eof)
125{
126 struct fc_frame *fp = (struct fc_frame *)skb;
127
128 skb_trim(skb, len);
129 fr_eof(fp) = eof;
130 fr_sof(fp) = sof;
131} 129}
132 130
133 131/**
134static inline int fnic_import_rq_eth_pkt(struct sk_buff *skb, u32 len) 132 * fnic_import_rq_eth_pkt() - handle received FCoE or FIP frame.
133 * @fnic: fnic instance.
134 * @skb: Ethernet Frame.
135 */
136static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
135{ 137{
136 struct fc_frame *fp; 138 struct fc_frame *fp;
137 struct ethhdr *eh; 139 struct ethhdr *eh;
138 struct vlan_ethhdr *vh;
139 struct fcoe_hdr *fcoe_hdr; 140 struct fcoe_hdr *fcoe_hdr;
140 struct fcoe_crc_eof *ft; 141 struct fcoe_crc_eof *ft;
141 u32 transport_len = 0;
142 142
143 /*
144 * Undo VLAN encapsulation if present.
145 */
143 eh = (struct ethhdr *)skb->data; 146 eh = (struct ethhdr *)skb->data;
144 vh = (struct vlan_ethhdr *)skb->data; 147 if (eh->h_proto == htons(ETH_P_8021Q)) {
145 if (vh->h_vlan_proto == htons(ETH_P_8021Q) && 148 memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
146 vh->h_vlan_encapsulated_proto == htons(ETH_P_FCOE)) { 149 eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
147 skb_pull(skb, sizeof(struct vlan_ethhdr)); 150 skb_reset_mac_header(skb);
148 transport_len += sizeof(struct vlan_ethhdr); 151 }
149 } else if (eh->h_proto == htons(ETH_P_FCOE)) { 152 if (eh->h_proto == htons(ETH_P_FIP)) {
150 transport_len += sizeof(struct ethhdr); 153 skb_pull(skb, sizeof(*eh));
151 skb_pull(skb, sizeof(struct ethhdr)); 154 fcoe_ctlr_recv(&fnic->ctlr, skb);
152 } else 155 return 1; /* let caller know packet was used */
153 return -1; 156 }
157 if (eh->h_proto != htons(ETH_P_FCOE))
158 goto drop;
159 skb_set_network_header(skb, sizeof(*eh));
160 skb_pull(skb, sizeof(*eh));
154 161
155 fcoe_hdr = (struct fcoe_hdr *)skb->data; 162 fcoe_hdr = (struct fcoe_hdr *)skb->data;
156 if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER) 163 if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER)
157 return -1; 164 goto drop;
158 165
159 fp = (struct fc_frame *)skb; 166 fp = (struct fc_frame *)skb;
160 fc_frame_init(fp); 167 fc_frame_init(fp);
161 fr_sof(fp) = fcoe_hdr->fcoe_sof; 168 fr_sof(fp) = fcoe_hdr->fcoe_sof;
162 skb_pull(skb, sizeof(struct fcoe_hdr)); 169 skb_pull(skb, sizeof(struct fcoe_hdr));
163 transport_len += sizeof(struct fcoe_hdr); 170 skb_reset_transport_header(skb);
164 171
165 ft = (struct fcoe_crc_eof *)(skb->data + len - 172 ft = (struct fcoe_crc_eof *)(skb->data + skb->len - sizeof(*ft));
166 transport_len - sizeof(*ft));
167 fr_eof(fp) = ft->fcoe_eof; 173 fr_eof(fp) = ft->fcoe_eof;
168 skb_trim(skb, len - transport_len - sizeof(*ft)); 174 skb_trim(skb, skb->len - sizeof(*ft));
169 return 0; 175 return 0;
176drop:
177 dev_kfree_skb_irq(skb);
178 return -1;
170} 179}
171 180
172static inline int fnic_handle_flogi_resp(struct fnic *fnic, 181/**
173 struct fc_frame *fp) 182 * fnic_update_mac_locked() - set data MAC address and filters.
183 * @fnic: fnic instance.
184 * @new: newly-assigned FCoE MAC address.
185 *
186 * Called with the fnic lock held.
187 */
188void fnic_update_mac_locked(struct fnic *fnic, u8 *new)
174{ 189{
175 u8 mac[ETH_ALEN] = FC_FCOE_FLOGI_MAC; 190 u8 *ctl = fnic->ctlr.ctl_src_addr;
176 struct ethhdr *eth_hdr; 191 u8 *data = fnic->data_src_addr;
177 struct fc_frame_header *fh;
178 int ret = 0;
179 unsigned long flags;
180 struct fc_frame *old_flogi_resp = NULL;
181 192
182 fh = (struct fc_frame_header *)fr_hdr(fp); 193 if (is_zero_ether_addr(new))
194 new = ctl;
195 if (!compare_ether_addr(data, new))
196 return;
197 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "update_mac %pM\n", new);
198 if (!is_zero_ether_addr(data) && compare_ether_addr(data, ctl))
199 vnic_dev_del_addr(fnic->vdev, data);
200 memcpy(data, new, ETH_ALEN);
201 if (compare_ether_addr(new, ctl))
202 vnic_dev_add_addr(fnic->vdev, new);
203}
183 204
184 spin_lock_irqsave(&fnic->fnic_lock, flags); 205/**
206 * fnic_update_mac() - set data MAC address and filters.
207 * @lport: local port.
208 * @new: newly-assigned FCoE MAC address.
209 */
210void fnic_update_mac(struct fc_lport *lport, u8 *new)
211{
212 struct fnic *fnic = lport_priv(lport);
185 213
186 if (fnic->state == FNIC_IN_ETH_MODE) { 214 spin_lock_irq(&fnic->fnic_lock);
215 fnic_update_mac_locked(fnic, new);
216 spin_unlock_irq(&fnic->fnic_lock);
217}
187 218
188 /* 219/**
189 * Check if oxid matches on taking the lock. A new Flogi 220 * fnic_set_port_id() - set the port_ID after successful FLOGI.
190 * issued by libFC might have changed the fnic cached oxid 221 * @lport: local port.
191 */ 222 * @port_id: assigned FC_ID.
192 if (fnic->flogi_oxid != ntohs(fh->fh_ox_id)) { 223 * @fp: received frame containing the FLOGI accept or NULL.
193 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 224 *
194 "Flogi response oxid not" 225 * This is called from libfc when a new FC_ID has been assigned.
195 " matching cached oxid, dropping frame" 226 * This causes us to reset the firmware to FC_MODE and setup the new MAC
196 "\n"); 227 * address and FC_ID.
197 ret = -1; 228 *
198 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 229 * It is also called with FC_ID 0 when we're logged off.
199 dev_kfree_skb_irq(fp_skb(fp)); 230 *
200 goto handle_flogi_resp_end; 231 * If the FC_ID is due to point-to-point, fp may be NULL.
201 } 232 */
233void fnic_set_port_id(struct fc_lport *lport, u32 port_id, struct fc_frame *fp)
234{
235 struct fnic *fnic = lport_priv(lport);
236 u8 *mac;
237 int ret;
202 238
203 /* Drop older cached flogi response frame, cache this frame */ 239 FNIC_FCS_DBG(KERN_DEBUG, lport->host, "set port_id %x fp %p\n",
204 old_flogi_resp = fnic->flogi_resp; 240 port_id, fp);
205 fnic->flogi_resp = fp;
206 fnic->flogi_oxid = FC_XID_UNKNOWN;
207 241
208 /* 242 /*
209 * this frame is part of flogi get the src mac addr from this 243 * If we're clearing the FC_ID, change to use the ctl_src_addr.
210 * frame if the src mac is fcoui based then we mark the 244 * Set ethernet mode to send FLOGI.
211 * address mode flag to use fcoui base for dst mac addr 245 */
212 * otherwise we have to store the fcoe gateway addr 246 if (!port_id) {
213 */ 247 fnic_update_mac(lport, fnic->ctlr.ctl_src_addr);
214 eth_hdr = (struct ethhdr *)skb_mac_header(fp_skb(fp)); 248 fnic_set_eth_mode(fnic);
215 memcpy(mac, eth_hdr->h_source, ETH_ALEN); 249 return;
250 }
216 251
217 if (ntoh24(mac) == FC_FCOE_OUI) 252 if (fp) {
218 fnic->fcoui_mode = 1; 253 mac = fr_cb(fp)->granted_mac;
219 else { 254 if (is_zero_ether_addr(mac)) {
220 fnic->fcoui_mode = 0; 255 /* non-FIP - FLOGI already accepted - ignore return */
221 memcpy(fnic->dest_addr, mac, ETH_ALEN); 256 fcoe_ctlr_recv_flogi(&fnic->ctlr, lport, fp);
222 } 257 }
258 fnic_update_mac(lport, mac);
259 }
223 260
224 /* 261 /* Change state to reflect transition to FC mode */
225 * Except for Flogi frame, all outbound frames from us have the 262 spin_lock_irq(&fnic->fnic_lock);
226 * Eth Src address as FC_FCOE_OUI"our_sid". Flogi frame uses 263 if (fnic->state == FNIC_IN_ETH_MODE || fnic->state == FNIC_IN_FC_MODE)
227 * the vnic MAC address as the Eth Src address
228 */
229 fc_fcoe_set_mac(fnic->data_src_addr, fh->fh_d_id);
230
231 /* We get our s_id from the d_id of the flogi resp frame */
232 fnic->s_id = ntoh24(fh->fh_d_id);
233
234 /* Change state to reflect transition from Eth to FC mode */
235 fnic->state = FNIC_IN_ETH_TRANS_FC_MODE; 264 fnic->state = FNIC_IN_ETH_TRANS_FC_MODE;
236 265 else {
237 } else {
238 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 266 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
239 "Unexpected fnic state %s while" 267 "Unexpected fnic state %s while"
240 " processing flogi resp\n", 268 " processing flogi resp\n",
241 fnic_state_to_str(fnic->state)); 269 fnic_state_to_str(fnic->state));
242 ret = -1; 270 spin_unlock_irq(&fnic->fnic_lock);
243 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 271 return;
244 dev_kfree_skb_irq(fp_skb(fp));
245 goto handle_flogi_resp_end;
246 } 272 }
247 273 spin_unlock_irq(&fnic->fnic_lock);
248 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
249
250 /* Drop older cached frame */
251 if (old_flogi_resp)
252 dev_kfree_skb_irq(fp_skb(old_flogi_resp));
253 274
254 /* 275 /*
255 * send flogi reg request to firmware, this will put the fnic in 276 * Send FLOGI registration to firmware to set up FC mode.
256 * in FC mode 277 * The new address will be set up when registration completes.
257 */ 278 */
258 ret = fnic_flogi_reg_handler(fnic); 279 ret = fnic_flogi_reg_handler(fnic, port_id);
259 280
260 if (ret < 0) { 281 if (ret < 0) {
261 int free_fp = 1; 282 spin_lock_irq(&fnic->fnic_lock);
262 spin_lock_irqsave(&fnic->fnic_lock, flags);
263 /*
264 * free the frame is some other thread is not
265 * pointing to it
266 */
267 if (fnic->flogi_resp != fp)
268 free_fp = 0;
269 else
270 fnic->flogi_resp = NULL;
271
272 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) 283 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE)
273 fnic->state = FNIC_IN_ETH_MODE; 284 fnic->state = FNIC_IN_ETH_MODE;
274 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 285 spin_unlock_irq(&fnic->fnic_lock);
275 if (free_fp)
276 dev_kfree_skb_irq(fp_skb(fp));
277 } 286 }
278
279 handle_flogi_resp_end:
280 return ret;
281}
282
283/* Returns 1 for a response that matches cached flogi oxid */
284static inline int is_matching_flogi_resp_frame(struct fnic *fnic,
285 struct fc_frame *fp)
286{
287 struct fc_frame_header *fh;
288 int ret = 0;
289 u32 f_ctl;
290
291 fh = fc_frame_header_get(fp);
292 f_ctl = ntoh24(fh->fh_f_ctl);
293
294 if (fnic->flogi_oxid == ntohs(fh->fh_ox_id) &&
295 fh->fh_r_ctl == FC_RCTL_ELS_REP &&
296 (f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == FC_FC_EX_CTX &&
297 fh->fh_type == FC_TYPE_ELS)
298 ret = 1;
299
300 return ret;
301} 287}
302 288
303static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc 289static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
@@ -326,6 +312,7 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
326 pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len, 312 pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len,
327 PCI_DMA_FROMDEVICE); 313 PCI_DMA_FROMDEVICE);
328 skb = buf->os_buf; 314 skb = buf->os_buf;
315 fp = (struct fc_frame *)skb;
329 buf->os_buf = NULL; 316 buf->os_buf = NULL;
330 317
331 cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index); 318 cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index);
@@ -338,6 +325,9 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
338 &fcoe_enc_error, &fcs_ok, &vlan_stripped, 325 &fcoe_enc_error, &fcs_ok, &vlan_stripped,
339 &vlan); 326 &vlan);
340 eth_hdrs_stripped = 1; 327 eth_hdrs_stripped = 1;
328 skb_trim(skb, fcp_bytes_written);
329 fr_sof(fp) = sof;
330 fr_eof(fp) = eof;
341 331
342 } else if (type == CQ_DESC_TYPE_RQ_ENET) { 332 } else if (type == CQ_DESC_TYPE_RQ_ENET) {
343 cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, 333 cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
@@ -352,6 +342,14 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
352 &ipv4_csum_ok, &ipv6, &ipv4, 342 &ipv4_csum_ok, &ipv6, &ipv4,
353 &ipv4_fragment, &fcs_ok); 343 &ipv4_fragment, &fcs_ok);
354 eth_hdrs_stripped = 0; 344 eth_hdrs_stripped = 0;
345 skb_trim(skb, bytes_written);
346 if (!fcs_ok) {
347 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
348 "fcs error. dropping packet.\n");
349 goto drop;
350 }
351 if (fnic_import_rq_eth_pkt(fnic, skb))
352 return;
355 353
356 } else { 354 } else {
357 /* wrong CQ type*/ 355 /* wrong CQ type*/
@@ -370,43 +368,11 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
370 goto drop; 368 goto drop;
371 } 369 }
372 370
373 if (eth_hdrs_stripped)
374 fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof);
375 else if (fnic_import_rq_eth_pkt(skb, bytes_written))
376 goto drop;
377
378 fp = (struct fc_frame *)skb;
379
380 /*
381 * If frame is an ELS response that matches the cached FLOGI OX_ID,
382 * and is accept, issue flogi_reg_request copy wq request to firmware
383 * to register the S_ID and determine whether FC_OUI mode or GW mode.
384 */
385 if (is_matching_flogi_resp_frame(fnic, fp)) {
386 if (!eth_hdrs_stripped) {
387 if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
388 fnic_handle_flogi_resp(fnic, fp);
389 return;
390 }
391 /*
392 * Recd. Flogi reject. No point registering
393 * with fw, but forward to libFC
394 */
395 goto forward;
396 }
397 goto drop;
398 }
399 if (!eth_hdrs_stripped)
400 goto drop;
401
402forward:
403 spin_lock_irqsave(&fnic->fnic_lock, flags); 371 spin_lock_irqsave(&fnic->fnic_lock, flags);
404 if (fnic->stop_rx_link_events) { 372 if (fnic->stop_rx_link_events) {
405 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 373 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
406 goto drop; 374 goto drop;
407 } 375 }
408 /* Use fr_flags to indicate whether succ. flogi resp or not */
409 fr_flags(fp) = 0;
410 fr_dev(fp) = fnic->lport; 376 fr_dev(fp) = fnic->lport;
411 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 377 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
412 378
@@ -494,12 +460,49 @@ void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
494 buf->os_buf = NULL; 460 buf->os_buf = NULL;
495} 461}
496 462
497static inline int is_flogi_frame(struct fc_frame_header *fh) 463/**
464 * fnic_eth_send() - Send Ethernet frame.
465 * @fip: fcoe_ctlr instance.
466 * @skb: Ethernet Frame, FIP, without VLAN encapsulation.
467 */
468void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
498{ 469{
499 return fh->fh_r_ctl == FC_RCTL_ELS_REQ && *(u8 *)(fh + 1) == ELS_FLOGI; 470 struct fnic *fnic = fnic_from_ctlr(fip);
471 struct vnic_wq *wq = &fnic->wq[0];
472 dma_addr_t pa;
473 struct ethhdr *eth_hdr;
474 struct vlan_ethhdr *vlan_hdr;
475 unsigned long flags;
476
477 if (!fnic->vlan_hw_insert) {
478 eth_hdr = (struct ethhdr *)skb_mac_header(skb);
479 vlan_hdr = (struct vlan_ethhdr *)skb_push(skb,
480 sizeof(*vlan_hdr) - sizeof(*eth_hdr));
481 memcpy(vlan_hdr, eth_hdr, 2 * ETH_ALEN);
482 vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
483 vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
484 vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
485 }
486
487 pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
488
489 spin_lock_irqsave(&fnic->wq_lock[0], flags);
490 if (!vnic_wq_desc_avail(wq)) {
491 pci_unmap_single(fnic->pdev, pa, skb->len, PCI_DMA_TODEVICE);
492 spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
493 kfree_skb(skb);
494 return;
495 }
496
497 fnic_queue_wq_eth_desc(wq, skb, pa, skb->len,
498 fnic->vlan_hw_insert, fnic->vlan_id, 1);
499 spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
500} 500}
501 501
502int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) 502/*
503 * Send FC frame.
504 */
505static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
503{ 506{
504 struct vnic_wq *wq = &fnic->wq[0]; 507 struct vnic_wq *wq = &fnic->wq[0];
505 struct sk_buff *skb; 508 struct sk_buff *skb;
@@ -515,6 +518,10 @@ int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
515 fh = fc_frame_header_get(fp); 518 fh = fc_frame_header_get(fp);
516 skb = fp_skb(fp); 519 skb = fp_skb(fp);
517 520
521 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
522 fcoe_ctlr_els_send(&fnic->ctlr, fnic->lport, skb))
523 return 0;
524
518 if (!fnic->vlan_hw_insert) { 525 if (!fnic->vlan_hw_insert) {
519 eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr); 526 eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr);
520 vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, eth_hdr_len); 527 vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, eth_hdr_len);
@@ -530,16 +537,11 @@ int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
530 fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1); 537 fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1);
531 } 538 }
532 539
533 if (is_flogi_frame(fh)) { 540 if (fnic->ctlr.map_dest)
534 fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id); 541 fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
535 memcpy(eth_hdr->h_source, fnic->mac_addr, ETH_ALEN); 542 else
536 } else { 543 memcpy(eth_hdr->h_dest, fnic->ctlr.dest_addr, ETH_ALEN);
537 if (fnic->fcoui_mode) 544 memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
538 fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
539 else
540 memcpy(eth_hdr->h_dest, fnic->dest_addr, ETH_ALEN);
541 memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
542 }
543 545
544 tot_len = skb->len; 546 tot_len = skb->len;
545 BUG_ON(tot_len % 4); 547 BUG_ON(tot_len % 4);
@@ -578,109 +580,85 @@ fnic_send_frame_end:
578int fnic_send(struct fc_lport *lp, struct fc_frame *fp) 580int fnic_send(struct fc_lport *lp, struct fc_frame *fp)
579{ 581{
580 struct fnic *fnic = lport_priv(lp); 582 struct fnic *fnic = lport_priv(lp);
581 struct fc_frame_header *fh;
582 int ret = 0;
583 enum fnic_state old_state;
584 unsigned long flags; 583 unsigned long flags;
585 struct fc_frame *old_flogi = NULL;
586 struct fc_frame *old_flogi_resp = NULL;
587 584
588 if (fnic->in_remove) { 585 if (fnic->in_remove) {
589 dev_kfree_skb(fp_skb(fp)); 586 dev_kfree_skb(fp_skb(fp));
590 ret = -1; 587 return -1;
591 goto fnic_send_end;
592 } 588 }
593 589
594 fh = fc_frame_header_get(fp); 590 /*
595 /* if not an Flogi frame, send it out, this is the common case */ 591 * Queue frame if in a transitional state.
596 if (!is_flogi_frame(fh)) 592 * This occurs while registering the Port_ID / MAC address after FLOGI.
597 return fnic_send_frame(fnic, fp); 593 */
594 spin_lock_irqsave(&fnic->fnic_lock, flags);
595 if (fnic->state != FNIC_IN_FC_MODE && fnic->state != FNIC_IN_ETH_MODE) {
596 skb_queue_tail(&fnic->tx_queue, fp_skb(fp));
597 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
598 return 0;
599 }
600 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
598 601
599 /* Flogi frame, now enter the state machine */ 602 return fnic_send_frame(fnic, fp);
603}
600 604
601 spin_lock_irqsave(&fnic->fnic_lock, flags); 605/**
602again: 606 * fnic_flush_tx() - send queued frames.
603 /* Get any old cached frames, free them after dropping lock */ 607 * @fnic: fnic device
604 old_flogi = fnic->flogi; 608 *
605 fnic->flogi = NULL; 609 * Send frames that were waiting to go out in FC or Ethernet mode.
606 old_flogi_resp = fnic->flogi_resp; 610 * Whenever changing modes we purge queued frames, so these frames should
607 fnic->flogi_resp = NULL; 611 * be queued for the stable mode that we're in, either FC or Ethernet.
612 *
613 * Called without fnic_lock held.
614 */
615void fnic_flush_tx(struct fnic *fnic)
616{
617 struct sk_buff *skb;
618 struct fc_frame *fp;
608 619
609 fnic->flogi_oxid = FC_XID_UNKNOWN; 620 while ((skb = skb_dequeue(&fnic->frame_queue))) {
621 fp = (struct fc_frame *)skb;
622 fnic_send_frame(fnic, fp);
623 }
624}
610 625
626/**
627 * fnic_set_eth_mode() - put fnic into ethernet mode.
628 * @fnic: fnic device
629 *
630 * Called without fnic lock held.
631 */
632static void fnic_set_eth_mode(struct fnic *fnic)
633{
634 unsigned long flags;
635 enum fnic_state old_state;
636 int ret;
637
638 spin_lock_irqsave(&fnic->fnic_lock, flags);
639again:
611 old_state = fnic->state; 640 old_state = fnic->state;
612 switch (old_state) { 641 switch (old_state) {
613 case FNIC_IN_FC_MODE: 642 case FNIC_IN_FC_MODE:
614 case FNIC_IN_ETH_TRANS_FC_MODE: 643 case FNIC_IN_ETH_TRANS_FC_MODE:
615 default: 644 default:
616 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; 645 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
617 vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
618 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 646 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
619 647
620 if (old_flogi) {
621 dev_kfree_skb(fp_skb(old_flogi));
622 old_flogi = NULL;
623 }
624 if (old_flogi_resp) {
625 dev_kfree_skb(fp_skb(old_flogi_resp));
626 old_flogi_resp = NULL;
627 }
628
629 ret = fnic_fw_reset_handler(fnic); 648 ret = fnic_fw_reset_handler(fnic);
630 649
631 spin_lock_irqsave(&fnic->fnic_lock, flags); 650 spin_lock_irqsave(&fnic->fnic_lock, flags);
632 if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE) 651 if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE)
633 goto again; 652 goto again;
634 if (ret) { 653 if (ret)
635 fnic->state = old_state; 654 fnic->state = old_state;
636 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
637 dev_kfree_skb(fp_skb(fp));
638 goto fnic_send_end;
639 }
640 old_flogi = fnic->flogi;
641 fnic->flogi = fp;
642 fnic->flogi_oxid = ntohs(fh->fh_ox_id);
643 old_flogi_resp = fnic->flogi_resp;
644 fnic->flogi_resp = NULL;
645 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
646 break; 655 break;
647 656
648 case FNIC_IN_FC_TRANS_ETH_MODE: 657 case FNIC_IN_FC_TRANS_ETH_MODE:
649 /*
650 * A reset is pending with the firmware. Store the flogi
651 * and its oxid. The transition out of this state happens
652 * only when Firmware completes the reset, either with
653 * success or failed. If success, transition to
654 * FNIC_IN_ETH_MODE, if fail, then transition to
655 * FNIC_IN_FC_MODE
656 */
657 fnic->flogi = fp;
658 fnic->flogi_oxid = ntohs(fh->fh_ox_id);
659 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
660 break;
661
662 case FNIC_IN_ETH_MODE: 658 case FNIC_IN_ETH_MODE:
663 /*
664 * The fw/hw is already in eth mode. Store the oxid,
665 * and send the flogi frame out. The transition out of this
666 * state happens only we receive flogi response from the
667 * network, and the oxid matches the cached oxid when the
668 * flogi frame was sent out. If they match, then we issue
669 * a flogi_reg request and transition to state
670 * FNIC_IN_ETH_TRANS_FC_MODE
671 */
672 fnic->flogi_oxid = ntohs(fh->fh_ox_id);
673 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
674 ret = fnic_send_frame(fnic, fp);
675 break; 659 break;
676 } 660 }
677 661 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
678fnic_send_end:
679 if (old_flogi)
680 dev_kfree_skb(fp_skb(old_flogi));
681 if (old_flogi_resp)
682 dev_kfree_skb(fp_skb(old_flogi_resp));
683 return ret;
684} 662}
685 663
686static void fnic_wq_complete_frame_send(struct vnic_wq *wq, 664static void fnic_wq_complete_frame_send(struct vnic_wq *wq,
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c
index 2b3064828aea..5c1f223cabce 100644
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -48,9 +48,9 @@ static irqreturn_t fnic_isr_legacy(int irq, void *data)
48 } 48 }
49 49
50 if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) { 50 if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) {
51 work_done += fnic_wq_copy_cmpl_handler(fnic, 8); 51 work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
52 work_done += fnic_wq_cmpl_handler(fnic, 4); 52 work_done += fnic_wq_cmpl_handler(fnic, -1);
53 work_done += fnic_rq_cmpl_handler(fnic, 4); 53 work_done += fnic_rq_cmpl_handler(fnic, -1);
54 54
55 vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ], 55 vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ],
56 work_done, 56 work_done,
@@ -66,9 +66,9 @@ static irqreturn_t fnic_isr_msi(int irq, void *data)
66 struct fnic *fnic = data; 66 struct fnic *fnic = data;
67 unsigned long work_done = 0; 67 unsigned long work_done = 0;
68 68
69 work_done += fnic_wq_copy_cmpl_handler(fnic, 8); 69 work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
70 work_done += fnic_wq_cmpl_handler(fnic, 4); 70 work_done += fnic_wq_cmpl_handler(fnic, -1);
71 work_done += fnic_rq_cmpl_handler(fnic, 4); 71 work_done += fnic_rq_cmpl_handler(fnic, -1);
72 72
73 vnic_intr_return_credits(&fnic->intr[0], 73 vnic_intr_return_credits(&fnic->intr[0],
74 work_done, 74 work_done,
@@ -83,7 +83,7 @@ static irqreturn_t fnic_isr_msix_rq(int irq, void *data)
83 struct fnic *fnic = data; 83 struct fnic *fnic = data;
84 unsigned long rq_work_done = 0; 84 unsigned long rq_work_done = 0;
85 85
86 rq_work_done = fnic_rq_cmpl_handler(fnic, 4); 86 rq_work_done = fnic_rq_cmpl_handler(fnic, -1);
87 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ], 87 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ],
88 rq_work_done, 88 rq_work_done,
89 1 /* unmask intr */, 89 1 /* unmask intr */,
@@ -97,7 +97,7 @@ static irqreturn_t fnic_isr_msix_wq(int irq, void *data)
97 struct fnic *fnic = data; 97 struct fnic *fnic = data;
98 unsigned long wq_work_done = 0; 98 unsigned long wq_work_done = 0;
99 99
100 wq_work_done = fnic_wq_cmpl_handler(fnic, 4); 100 wq_work_done = fnic_wq_cmpl_handler(fnic, -1);
101 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ], 101 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ],
102 wq_work_done, 102 wq_work_done,
103 1 /* unmask intr */, 103 1 /* unmask intr */,
@@ -110,7 +110,7 @@ static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data)
110 struct fnic *fnic = data; 110 struct fnic *fnic = data;
111 unsigned long wq_copy_work_done = 0; 111 unsigned long wq_copy_work_done = 0;
112 112
113 wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, 8); 113 wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1);
114 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY], 114 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY],
115 wq_copy_work_done, 115 wq_copy_work_done,
116 1 /* unmask intr */, 116 1 /* unmask intr */,
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 71c7bbe26d05..97b212570bcc 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mempool.h> 19#include <linux/mempool.h>
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/slab.h>
21#include <linux/errno.h> 22#include <linux/errno.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/pci.h> 24#include <linux/pci.h>
@@ -25,6 +26,8 @@
25#include <linux/interrupt.h> 26#include <linux/interrupt.h>
26#include <linux/spinlock.h> 27#include <linux/spinlock.h>
27#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/if_ether.h>
30#include <scsi/fc/fc_fip.h>
28#include <scsi/scsi_host.h> 31#include <scsi/scsi_host.h>
29#include <scsi/scsi_transport.h> 32#include <scsi/scsi_transport.h>
30#include <scsi/scsi_transport_fc.h> 33#include <scsi/scsi_transport_fc.h>
@@ -68,6 +71,7 @@ MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels");
68 71
69static struct libfc_function_template fnic_transport_template = { 72static struct libfc_function_template fnic_transport_template = {
70 .frame_send = fnic_send, 73 .frame_send = fnic_send,
74 .lport_set_port_id = fnic_set_port_id,
71 .fcp_abort_io = fnic_empty_scsi_cleanup, 75 .fcp_abort_io = fnic_empty_scsi_cleanup,
72 .fcp_cleanup = fnic_empty_scsi_cleanup, 76 .fcp_cleanup = fnic_empty_scsi_cleanup,
73 .exch_mgr_reset = fnic_exch_mgr_reset 77 .exch_mgr_reset = fnic_exch_mgr_reset
@@ -140,6 +144,7 @@ static struct fc_function_template fnic_fc_functions = {
140 .get_fc_host_stats = fnic_get_stats, 144 .get_fc_host_stats = fnic_get_stats,
141 .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), 145 .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
142 .terminate_rport_io = fnic_terminate_rport_io, 146 .terminate_rport_io = fnic_terminate_rport_io,
147 .bsg_request = fc_lport_bsg_request,
143}; 148};
144 149
145static void fnic_get_host_speed(struct Scsi_Host *shost) 150static void fnic_get_host_speed(struct Scsi_Host *shost)
@@ -324,9 +329,6 @@ static int fnic_cleanup(struct fnic *fnic)
324{ 329{
325 unsigned int i; 330 unsigned int i;
326 int err; 331 int err;
327 unsigned long flags;
328 struct fc_frame *flogi = NULL;
329 struct fc_frame *flogi_resp = NULL;
330 332
331 vnic_dev_disable(fnic->vdev); 333 vnic_dev_disable(fnic->vdev);
332 for (i = 0; i < fnic->intr_count; i++) 334 for (i = 0; i < fnic->intr_count; i++)
@@ -367,24 +369,6 @@ static int fnic_cleanup(struct fnic *fnic)
367 for (i = 0; i < fnic->intr_count; i++) 369 for (i = 0; i < fnic->intr_count; i++)
368 vnic_intr_clean(&fnic->intr[i]); 370 vnic_intr_clean(&fnic->intr[i]);
369 371
370 /*
371 * Remove cached flogi and flogi resp frames if any
372 * These frames are not in any queue, and therefore queue
373 * cleanup does not clean them. So clean them explicitly
374 */
375 spin_lock_irqsave(&fnic->fnic_lock, flags);
376 flogi = fnic->flogi;
377 fnic->flogi = NULL;
378 flogi_resp = fnic->flogi_resp;
379 fnic->flogi_resp = NULL;
380 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
381
382 if (flogi)
383 dev_kfree_skb(fp_skb(flogi));
384
385 if (flogi_resp)
386 dev_kfree_skb(fp_skb(flogi_resp));
387
388 mempool_destroy(fnic->io_req_pool); 372 mempool_destroy(fnic->io_req_pool);
389 for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) 373 for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
390 mempool_destroy(fnic->io_sgl_pool[i]); 374 mempool_destroy(fnic->io_sgl_pool[i]);
@@ -409,6 +393,17 @@ static void *fnic_alloc_slab_dma(gfp_t gfp_mask, void *pool_data)
409 return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA); 393 return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA);
410} 394}
411 395
396/**
397 * fnic_get_mac() - get assigned data MAC address for FIP code.
398 * @lport: local port.
399 */
400static u8 *fnic_get_mac(struct fc_lport *lport)
401{
402 struct fnic *fnic = lport_priv(lport);
403
404 return fnic->data_src_addr;
405}
406
412static int __devinit fnic_probe(struct pci_dev *pdev, 407static int __devinit fnic_probe(struct pci_dev *pdev,
413 const struct pci_device_id *ent) 408 const struct pci_device_id *ent)
414{ 409{
@@ -424,17 +419,16 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
424 * Allocate SCSI Host and set up association between host, 419 * Allocate SCSI Host and set up association between host,
425 * local port, and fnic 420 * local port, and fnic
426 */ 421 */
427 host = scsi_host_alloc(&fnic_host_template, 422 lp = libfc_host_alloc(&fnic_host_template, sizeof(struct fnic));
428 sizeof(struct fc_lport) + sizeof(struct fnic)); 423 if (!lp) {
429 if (!host) { 424 printk(KERN_ERR PFX "Unable to alloc libfc local port\n");
430 printk(KERN_ERR PFX "Unable to alloc SCSI host\n");
431 err = -ENOMEM; 425 err = -ENOMEM;
432 goto err_out; 426 goto err_out;
433 } 427 }
434 lp = shost_priv(host); 428 host = lp->host;
435 lp->host = host;
436 fnic = lport_priv(lp); 429 fnic = lport_priv(lp);
437 fnic->lport = lp; 430 fnic->lport = lp;
431 fnic->ctlr.lp = lp;
438 432
439 snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME, 433 snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
440 host->host_no); 434 host->host_no);
@@ -543,12 +537,14 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
543 goto err_out_dev_close; 537 goto err_out_dev_close;
544 } 538 }
545 539
546 err = vnic_dev_mac_addr(fnic->vdev, fnic->mac_addr); 540 err = vnic_dev_mac_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
547 if (err) { 541 if (err) {
548 shost_printk(KERN_ERR, fnic->lport->host, 542 shost_printk(KERN_ERR, fnic->lport->host,
549 "vNIC get MAC addr failed \n"); 543 "vNIC get MAC addr failed \n");
550 goto err_out_dev_close; 544 goto err_out_dev_close;
551 } 545 }
546 /* set data_src for point-to-point mode and to keep it non-zero */
547 memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
552 548
553 /* Get vNIC configuration */ 549 /* Get vNIC configuration */
554 err = fnic_get_vnic_config(fnic); 550 err = fnic_get_vnic_config(fnic);
@@ -560,6 +556,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
560 } 556 }
561 host->max_lun = fnic->config.luns_per_tgt; 557 host->max_lun = fnic->config.luns_per_tgt;
562 host->max_id = FNIC_MAX_FCP_TARGET; 558 host->max_id = FNIC_MAX_FCP_TARGET;
559 host->max_cmd_len = FNIC_MAX_CMD_LEN;
563 560
564 fnic_get_res_counts(fnic); 561 fnic_get_res_counts(fnic);
565 562
@@ -571,19 +568,12 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
571 goto err_out_dev_close; 568 goto err_out_dev_close;
572 } 569 }
573 570
574 err = fnic_request_intr(fnic);
575 if (err) {
576 shost_printk(KERN_ERR, fnic->lport->host,
577 "Unable to request irq.\n");
578 goto err_out_clear_intr;
579 }
580
581 err = fnic_alloc_vnic_resources(fnic); 571 err = fnic_alloc_vnic_resources(fnic);
582 if (err) { 572 if (err) {
583 shost_printk(KERN_ERR, fnic->lport->host, 573 shost_printk(KERN_ERR, fnic->lport->host,
584 "Failed to alloc vNIC resources, " 574 "Failed to alloc vNIC resources, "
585 "aborting.\n"); 575 "aborting.\n");
586 goto err_out_free_intr; 576 goto err_out_clear_intr;
587 } 577 }
588 578
589 579
@@ -623,9 +613,23 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
623 fnic->vlan_hw_insert = 1; 613 fnic->vlan_hw_insert = 1;
624 fnic->vlan_id = 0; 614 fnic->vlan_id = 0;
625 615
626 fnic->flogi_oxid = FC_XID_UNKNOWN; 616 /* Initialize the FIP fcoe_ctrl struct */
627 fnic->flogi = NULL; 617 fnic->ctlr.send = fnic_eth_send;
628 fnic->flogi_resp = NULL; 618 fnic->ctlr.update_mac = fnic_update_mac;
619 fnic->ctlr.get_src_addr = fnic_get_mac;
620 fcoe_ctlr_init(&fnic->ctlr);
621 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
622 shost_printk(KERN_INFO, fnic->lport->host,
623 "firmware supports FIP\n");
624 /* enable directed and multicast */
625 vnic_dev_packet_filter(fnic->vdev, 1, 1, 0, 0, 0);
626 vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
627 vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
628 } else {
629 shost_printk(KERN_INFO, fnic->lport->host,
630 "firmware uses non-FIP mode\n");
631 fnic->ctlr.mode = FIP_ST_NON_FIP;
632 }
629 fnic->state = FNIC_IN_FC_MODE; 633 fnic->state = FNIC_IN_FC_MODE;
630 634
631 /* Enable hardware stripping of vlan header on ingress */ 635 /* Enable hardware stripping of vlan header on ingress */
@@ -697,6 +701,8 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
697 goto err_out_remove_scsi_host; 701 goto err_out_remove_scsi_host;
698 } 702 }
699 703
704 fc_lport_init_stats(lp);
705
700 fc_lport_config(lp); 706 fc_lport_config(lp);
701 707
702 if (fc_set_mfs(lp, fnic->config.maxdatafieldsize + 708 if (fc_set_mfs(lp, fnic->config.maxdatafieldsize +
@@ -716,6 +722,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
716 INIT_WORK(&fnic->link_work, fnic_handle_link); 722 INIT_WORK(&fnic->link_work, fnic_handle_link);
717 INIT_WORK(&fnic->frame_work, fnic_handle_frame); 723 INIT_WORK(&fnic->frame_work, fnic_handle_frame);
718 skb_queue_head_init(&fnic->frame_queue); 724 skb_queue_head_init(&fnic->frame_queue);
725 skb_queue_head_init(&fnic->tx_queue);
719 726
720 /* Enable all queues */ 727 /* Enable all queues */
721 for (i = 0; i < fnic->raw_wq_count; i++) 728 for (i = 0; i < fnic->raw_wq_count; i++)
@@ -728,6 +735,14 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
728 fc_fabric_login(lp); 735 fc_fabric_login(lp);
729 736
730 vnic_dev_enable(fnic->vdev); 737 vnic_dev_enable(fnic->vdev);
738
739 err = fnic_request_intr(fnic);
740 if (err) {
741 shost_printk(KERN_ERR, fnic->lport->host,
742 "Unable to request irq.\n");
743 goto err_out_free_exch_mgr;
744 }
745
731 for (i = 0; i < fnic->intr_count; i++) 746 for (i = 0; i < fnic->intr_count; i++)
732 vnic_intr_unmask(&fnic->intr[i]); 747 vnic_intr_unmask(&fnic->intr[i]);
733 748
@@ -738,8 +753,8 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
738err_out_free_exch_mgr: 753err_out_free_exch_mgr:
739 fc_exch_mgr_free(lp); 754 fc_exch_mgr_free(lp);
740err_out_remove_scsi_host: 755err_out_remove_scsi_host:
741 fc_remove_host(fnic->lport->host); 756 fc_remove_host(lp->host);
742 scsi_remove_host(fnic->lport->host); 757 scsi_remove_host(lp->host);
743err_out_free_rq_buf: 758err_out_free_rq_buf:
744 for (i = 0; i < fnic->rq_count; i++) 759 for (i = 0; i < fnic->rq_count; i++)
745 vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); 760 vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
@@ -752,8 +767,6 @@ err_out_free_ioreq_pool:
752 mempool_destroy(fnic->io_req_pool); 767 mempool_destroy(fnic->io_req_pool);
753err_out_free_resources: 768err_out_free_resources:
754 fnic_free_vnic_resources(fnic); 769 fnic_free_vnic_resources(fnic);
755err_out_free_intr:
756 fnic_free_intr(fnic);
757err_out_clear_intr: 770err_out_clear_intr:
758 fnic_clear_intr_mode(fnic); 771 fnic_clear_intr_mode(fnic);
759err_out_dev_close: 772err_out_dev_close:
@@ -775,6 +788,7 @@ err_out:
775static void __devexit fnic_remove(struct pci_dev *pdev) 788static void __devexit fnic_remove(struct pci_dev *pdev)
776{ 789{
777 struct fnic *fnic = pci_get_drvdata(pdev); 790 struct fnic *fnic = pci_get_drvdata(pdev);
791 struct fc_lport *lp = fnic->lport;
778 unsigned long flags; 792 unsigned long flags;
779 793
780 /* 794 /*
@@ -796,6 +810,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
796 */ 810 */
797 flush_workqueue(fnic_event_queue); 811 flush_workqueue(fnic_event_queue);
798 skb_queue_purge(&fnic->frame_queue); 812 skb_queue_purge(&fnic->frame_queue);
813 skb_queue_purge(&fnic->tx_queue);
799 814
800 /* 815 /*
801 * Log off the fabric. This stops all remote ports, dns port, 816 * Log off the fabric. This stops all remote ports, dns port,
@@ -808,7 +823,8 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
808 fnic->in_remove = 1; 823 fnic->in_remove = 1;
809 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 824 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
810 825
811 fc_lport_destroy(fnic->lport); 826 fcoe_ctlr_destroy(&fnic->ctlr);
827 fc_lport_destroy(lp);
812 828
813 /* 829 /*
814 * This stops the fnic device, masks all interrupts. Completed 830 * This stops the fnic device, masks all interrupts. Completed
@@ -818,6 +834,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
818 fnic_cleanup(fnic); 834 fnic_cleanup(fnic);
819 835
820 BUG_ON(!skb_queue_empty(&fnic->frame_queue)); 836 BUG_ON(!skb_queue_empty(&fnic->frame_queue));
837 BUG_ON(!skb_queue_empty(&fnic->tx_queue));
821 838
822 spin_lock_irqsave(&fnic_list_lock, flags); 839 spin_lock_irqsave(&fnic_list_lock, flags);
823 list_del(&fnic->list); 840 list_del(&fnic->list);
@@ -827,8 +844,8 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
827 scsi_remove_host(fnic->lport->host); 844 scsi_remove_host(fnic->lport->host);
828 fc_exch_mgr_free(fnic->lport); 845 fc_exch_mgr_free(fnic->lport);
829 vnic_dev_notify_unset(fnic->vdev); 846 vnic_dev_notify_unset(fnic->vdev);
830 fnic_free_vnic_resources(fnic);
831 fnic_free_intr(fnic); 847 fnic_free_intr(fnic);
848 fnic_free_vnic_resources(fnic);
832 fnic_clear_intr_mode(fnic); 849 fnic_clear_intr_mode(fnic);
833 vnic_dev_close(fnic->vdev); 850 vnic_dev_close(fnic->vdev);
834 vnic_dev_unregister(fnic->vdev); 851 vnic_dev_unregister(fnic->vdev);
@@ -836,7 +853,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
836 pci_release_regions(pdev); 853 pci_release_regions(pdev);
837 pci_disable_device(pdev); 854 pci_disable_device(pdev);
838 pci_set_drvdata(pdev, NULL); 855 pci_set_drvdata(pdev, NULL);
839 scsi_host_put(fnic->lport->host); 856 scsi_host_put(lp->host);
840} 857}
841 858
842static struct pci_driver fnic_driver = { 859static struct pci_driver fnic_driver = {
diff --git a/drivers/scsi/fnic/fnic_res.c b/drivers/scsi/fnic/fnic_res.c
index 7ba61ec715d2..50488f8e169d 100644
--- a/drivers/scsi/fnic/fnic_res.c
+++ b/drivers/scsi/fnic/fnic_res.c
@@ -144,10 +144,9 @@ int fnic_get_vnic_config(struct fnic *fnic)
144 c->intr_timer_type = c->intr_timer_type; 144 c->intr_timer_type = c->intr_timer_type;
145 145
146 shost_printk(KERN_INFO, fnic->lport->host, 146 shost_printk(KERN_INFO, fnic->lport->host,
147 "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x " 147 "vNIC MAC addr %pM "
148 "wq/wq_copy/rq %d/%d/%d\n", 148 "wq/wq_copy/rq %d/%d/%d\n",
149 fnic->mac_addr[0], fnic->mac_addr[1], fnic->mac_addr[2], 149 fnic->ctlr.ctl_src_addr,
150 fnic->mac_addr[3], fnic->mac_addr[4], fnic->mac_addr[5],
151 c->wq_enet_desc_count, c->wq_copy_desc_count, 150 c->wq_enet_desc_count, c->wq_copy_desc_count,
152 c->rq_desc_count); 151 c->rq_desc_count);
153 shost_printk(KERN_INFO, fnic->lport->host, 152 shost_printk(KERN_INFO, fnic->lport->host,
diff --git a/drivers/scsi/fnic/fnic_res.h b/drivers/scsi/fnic/fnic_res.h
index b6f310262534..ef8aaf2156dd 100644
--- a/drivers/scsi/fnic/fnic_res.h
+++ b/drivers/scsi/fnic/fnic_res.h
@@ -51,6 +51,31 @@ static inline void fnic_queue_wq_desc(struct vnic_wq *wq,
51 vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop); 51 vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
52} 52}
53 53
54static inline void fnic_queue_wq_eth_desc(struct vnic_wq *wq,
55 void *os_buf, dma_addr_t dma_addr,
56 unsigned int len,
57 int vlan_tag_insert,
58 unsigned int vlan_tag,
59 int cq_entry)
60{
61 struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
62
63 wq_enet_desc_enc(desc,
64 (u64)dma_addr | VNIC_PADDR_TARGET,
65 (u16)len,
66 0, /* mss_or_csum_offset */
67 0, /* fc_eof */
68 0, /* offload_mode */
69 1, /* eop */
70 (u8)cq_entry,
71 0, /* fcoe_encap */
72 (u8)vlan_tag_insert,
73 (u16)vlan_tag,
74 0 /* loopback */);
75
76 vnic_wq_post(wq, os_buf, dma_addr, len, 1, 1);
77}
78
54static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq, 79static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
55 u32 req_id, 80 u32 req_id,
56 u32 lunmap_id, u8 spl_flags, 81 u32 lunmap_id, u8 spl_flags,
@@ -58,6 +83,7 @@ static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
58 u64 sgl_addr, u64 sns_addr, 83 u64 sgl_addr, u64 sns_addr,
59 u8 crn, u8 pri_ta, 84 u8 crn, u8 pri_ta,
60 u8 flags, u8 *scsi_cdb, 85 u8 flags, u8 *scsi_cdb,
86 u8 cdb_len,
61 u32 data_len, u8 *lun, 87 u32 data_len, u8 *lun,
62 u32 d_id, u16 mss, 88 u32 d_id, u16 mss,
63 u32 ratov, u32 edtov) 89 u32 ratov, u32 edtov)
@@ -82,7 +108,8 @@ static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
82 desc->u.icmnd_16.pri_ta = pri_ta; /* SCSI Pri & Task attribute */ 108 desc->u.icmnd_16.pri_ta = pri_ta; /* SCSI Pri & Task attribute */
83 desc->u.icmnd_16._resvd1 = 0; /* reserved: should be 0 */ 109 desc->u.icmnd_16._resvd1 = 0; /* reserved: should be 0 */
84 desc->u.icmnd_16.flags = flags; /* command flags */ 110 desc->u.icmnd_16.flags = flags; /* command flags */
85 memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, CDB_16); /* SCSI CDB */ 111 memset(desc->u.icmnd_16.scsi_cdb, 0, CDB_16);
112 memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, cdb_len); /* SCSI CDB */
86 desc->u.icmnd_16.data_len = data_len; /* length of data expected */ 113 desc->u.icmnd_16.data_len = data_len; /* length of data expected */
87 memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS); /* LUN address */ 114 memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS); /* LUN address */
88 desc->u.icmnd_16._resvd2 = 0; /* reserved */ 115 desc->u.icmnd_16._resvd2 = 0; /* reserved */
@@ -132,12 +159,37 @@ static inline void fnic_queue_wq_copy_desc_flogi_reg(struct vnic_wq_copy *wq,
132 desc->hdr.tag.u.req_id = req_id; /* id for this request */ 159 desc->hdr.tag.u.req_id = req_id; /* id for this request */
133 160
134 desc->u.flogi_reg.format = format; 161 desc->u.flogi_reg.format = format;
162 desc->u.flogi_reg._resvd = 0;
135 hton24(desc->u.flogi_reg.s_id, s_id); 163 hton24(desc->u.flogi_reg.s_id, s_id);
136 memcpy(desc->u.flogi_reg.gateway_mac, gw_mac, ETH_ALEN); 164 memcpy(desc->u.flogi_reg.gateway_mac, gw_mac, ETH_ALEN);
137 165
138 vnic_wq_copy_post(wq); 166 vnic_wq_copy_post(wq);
139} 167}
140 168
169static inline void fnic_queue_wq_copy_desc_fip_reg(struct vnic_wq_copy *wq,
170 u32 req_id, u32 s_id,
171 u8 *fcf_mac, u8 *ha_mac,
172 u32 r_a_tov, u32 e_d_tov)
173{
174 struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq);
175
176 desc->hdr.type = FCPIO_FLOGI_FIP_REG; /* enum fcpio_type */
177 desc->hdr.status = 0; /* header status entry */
178 desc->hdr._resvd = 0; /* reserved */
179 desc->hdr.tag.u.req_id = req_id; /* id for this request */
180
181 desc->u.flogi_fip_reg._resvd0 = 0;
182 hton24(desc->u.flogi_fip_reg.s_id, s_id);
183 memcpy(desc->u.flogi_fip_reg.fcf_mac, fcf_mac, ETH_ALEN);
184 desc->u.flogi_fip_reg._resvd1 = 0;
185 desc->u.flogi_fip_reg.r_a_tov = r_a_tov;
186 desc->u.flogi_fip_reg.e_d_tov = e_d_tov;
187 memcpy(desc->u.flogi_fip_reg.ha_mac, ha_mac, ETH_ALEN);
188 desc->u.flogi_fip_reg._resvd2 = 0;
189
190 vnic_wq_copy_post(wq);
191}
192
141static inline void fnic_queue_wq_copy_desc_fw_reset(struct vnic_wq_copy *wq, 193static inline void fnic_queue_wq_copy_desc_fw_reset(struct vnic_wq_copy *wq,
142 u32 req_id) 194 u32 req_id)
143{ 195{
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index bfc996971b81..3cc47c6e1ada 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -26,6 +26,7 @@
26#include <linux/if_ether.h> 26#include <linux/if_ether.h>
27#include <linux/if_vlan.h> 27#include <linux/if_vlan.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/gfp.h>
29#include <scsi/scsi.h> 30#include <scsi/scsi.h>
30#include <scsi/scsi_host.h> 31#include <scsi/scsi_host.h>
31#include <scsi/scsi_device.h> 32#include <scsi/scsi_device.h>
@@ -174,6 +175,9 @@ int fnic_fw_reset_handler(struct fnic *fnic)
174 int ret = 0; 175 int ret = 0;
175 unsigned long flags; 176 unsigned long flags;
176 177
178 skb_queue_purge(&fnic->frame_queue);
179 skb_queue_purge(&fnic->tx_queue);
180
177 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); 181 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
178 182
179 if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) 183 if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0])
@@ -200,9 +204,11 @@ int fnic_fw_reset_handler(struct fnic *fnic)
200 * fnic_flogi_reg_handler 204 * fnic_flogi_reg_handler
201 * Routine to send flogi register msg to fw 205 * Routine to send flogi register msg to fw
202 */ 206 */
203int fnic_flogi_reg_handler(struct fnic *fnic) 207int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
204{ 208{
205 struct vnic_wq_copy *wq = &fnic->wq_copy[0]; 209 struct vnic_wq_copy *wq = &fnic->wq_copy[0];
210 enum fcpio_flogi_reg_format_type format;
211 struct fc_lport *lp = fnic->lport;
206 u8 gw_mac[ETH_ALEN]; 212 u8 gw_mac[ETH_ALEN];
207 int ret = 0; 213 int ret = 0;
208 unsigned long flags; 214 unsigned long flags;
@@ -217,23 +223,32 @@ int fnic_flogi_reg_handler(struct fnic *fnic)
217 goto flogi_reg_ioreq_end; 223 goto flogi_reg_ioreq_end;
218 } 224 }
219 225
220 if (fnic->fcoui_mode) 226 if (fnic->ctlr.map_dest) {
221 memset(gw_mac, 0xff, ETH_ALEN); 227 memset(gw_mac, 0xff, ETH_ALEN);
222 else 228 format = FCPIO_FLOGI_REG_DEF_DEST;
223 memcpy(gw_mac, fnic->dest_addr, ETH_ALEN); 229 } else {
230 memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN);
231 format = FCPIO_FLOGI_REG_GW_DEST;
232 }
224 233
225 fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG, 234 if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) {
226 FCPIO_FLOGI_REG_GW_DEST, 235 fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG,
227 fnic->s_id, 236 fc_id, gw_mac,
228 gw_mac); 237 fnic->data_src_addr,
238 lp->r_a_tov, lp->e_d_tov);
239 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
240 "FLOGI FIP reg issued fcid %x src %pM dest %pM\n",
241 fc_id, fnic->data_src_addr, gw_mac);
242 } else {
243 fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
244 format, fc_id, gw_mac);
245 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
246 "FLOGI reg issued fcid %x map %d dest %pM\n",
247 fc_id, fnic->ctlr.map_dest, gw_mac);
248 }
229 249
230flogi_reg_ioreq_end: 250flogi_reg_ioreq_end:
231 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 251 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
232
233 if (!ret)
234 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
235 "flog reg issued\n");
236
237 return ret; 252 return ret;
238} 253}
239 254
@@ -319,7 +334,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
319 0, /* scsi cmd ref, always 0 */ 334 0, /* scsi cmd ref, always 0 */
320 pri_tag, /* scsi pri and tag */ 335 pri_tag, /* scsi pri and tag */
321 flags, /* command flags */ 336 flags, /* command flags */
322 sc->cmnd, scsi_bufflen(sc), 337 sc->cmnd, sc->cmd_len,
338 scsi_bufflen(sc),
323 fc_lun.scsi_lun, io_req->port_id, 339 fc_lun.scsi_lun, io_req->port_id,
324 rport->maxframe_size, rp->r_a_tov, 340 rport->maxframe_size, rp->r_a_tov,
325 rp->e_d_tov); 341 rp->e_d_tov);
@@ -452,7 +468,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
452 u8 hdr_status; 468 u8 hdr_status;
453 struct fcpio_tag tag; 469 struct fcpio_tag tag;
454 int ret = 0; 470 int ret = 0;
455 struct fc_frame *flogi;
456 unsigned long flags; 471 unsigned long flags;
457 472
458 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); 473 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
@@ -462,9 +477,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
462 477
463 spin_lock_irqsave(&fnic->fnic_lock, flags); 478 spin_lock_irqsave(&fnic->fnic_lock, flags);
464 479
465 flogi = fnic->flogi;
466 fnic->flogi = NULL;
467
468 /* fnic should be in FC_TRANS_ETH_MODE */ 480 /* fnic should be in FC_TRANS_ETH_MODE */
469 if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) { 481 if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) {
470 /* Check status of reset completion */ 482 /* Check status of reset completion */
@@ -505,17 +517,14 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
505 * free the flogi frame. Else, send it out 517 * free the flogi frame. Else, send it out
506 */ 518 */
507 if (fnic->remove_wait || ret) { 519 if (fnic->remove_wait || ret) {
508 fnic->flogi_oxid = FC_XID_UNKNOWN;
509 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 520 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
510 if (flogi) 521 skb_queue_purge(&fnic->tx_queue);
511 dev_kfree_skb_irq(fp_skb(flogi));
512 goto reset_cmpl_handler_end; 522 goto reset_cmpl_handler_end;
513 } 523 }
514 524
515 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 525 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
516 526
517 if (flogi) 527 fnic_flush_tx(fnic);
518 ret = fnic_send_frame(fnic, flogi);
519 528
520 reset_cmpl_handler_end: 529 reset_cmpl_handler_end:
521 return ret; 530 return ret;
@@ -532,18 +541,13 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic,
532 u8 hdr_status; 541 u8 hdr_status;
533 struct fcpio_tag tag; 542 struct fcpio_tag tag;
534 int ret = 0; 543 int ret = 0;
535 struct fc_frame *flogi_resp = NULL;
536 unsigned long flags; 544 unsigned long flags;
537 struct sk_buff *skb;
538 545
539 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); 546 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
540 547
541 /* Update fnic state based on status of flogi reg completion */ 548 /* Update fnic state based on status of flogi reg completion */
542 spin_lock_irqsave(&fnic->fnic_lock, flags); 549 spin_lock_irqsave(&fnic->fnic_lock, flags);
543 550
544 flogi_resp = fnic->flogi_resp;
545 fnic->flogi_resp = NULL;
546
547 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) { 551 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) {
548 552
549 /* Check flogi registration completion status */ 553 /* Check flogi registration completion status */
@@ -567,25 +571,17 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic,
567 ret = -1; 571 ret = -1;
568 } 572 }
569 573
570 /* Successful flogi reg cmpl, pass frame to LibFC */ 574 if (!ret) {
571 if (!ret && flogi_resp) {
572 if (fnic->stop_rx_link_events) { 575 if (fnic->stop_rx_link_events) {
573 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 576 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
574 goto reg_cmpl_handler_end; 577 goto reg_cmpl_handler_end;
575 } 578 }
576 skb = (struct sk_buff *)flogi_resp;
577 /* Use fr_flags to indicate whether flogi resp or not */
578 fr_flags(flogi_resp) = 1;
579 fr_dev(flogi_resp) = fnic->lport;
580 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 579 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
581 580
582 skb_queue_tail(&fnic->frame_queue, skb); 581 fnic_flush_tx(fnic);
583 queue_work(fnic_event_queue, &fnic->frame_work); 582 queue_work(fnic_event_queue, &fnic->frame_work);
584
585 } else { 583 } else {
586 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 584 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
587 if (flogi_resp)
588 dev_kfree_skb_irq(fp_skb(flogi_resp));
589 } 585 }
590 586
591reg_cmpl_handler_end: 587reg_cmpl_handler_end:
@@ -907,6 +903,7 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev,
907 break; 903 break;
908 904
909 case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */ 905 case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
906 case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
910 ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc); 907 ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc);
911 break; 908 break;
912 909
@@ -1224,22 +1221,6 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1224 1221
1225} 1222}
1226 1223
1227static void fnic_block_error_handler(struct scsi_cmnd *sc)
1228{
1229 struct Scsi_Host *shost = sc->device->host;
1230 struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
1231 unsigned long flags;
1232
1233 spin_lock_irqsave(shost->host_lock, flags);
1234 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
1235 spin_unlock_irqrestore(shost->host_lock, flags);
1236 msleep(1000);
1237 spin_lock_irqsave(shost->host_lock, flags);
1238 }
1239 spin_unlock_irqrestore(shost->host_lock, flags);
1240
1241}
1242
1243/* 1224/*
1244 * This function is exported to SCSI for sending abort cmnds. 1225 * This function is exported to SCSI for sending abort cmnds.
1245 * A SCSI IO is represented by a io_req in the driver. 1226 * A SCSI IO is represented by a io_req in the driver.
@@ -1259,7 +1240,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1259 DECLARE_COMPLETION_ONSTACK(tm_done); 1240 DECLARE_COMPLETION_ONSTACK(tm_done);
1260 1241
1261 /* Wait for rport to unblock */ 1242 /* Wait for rport to unblock */
1262 fnic_block_error_handler(sc); 1243 fc_block_scsi_eh(sc);
1263 1244
1264 /* Get local-port, check ready and link up */ 1245 /* Get local-port, check ready and link up */
1265 lp = shost_priv(sc->device->host); 1246 lp = shost_priv(sc->device->host);
@@ -1541,7 +1522,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
1541 DECLARE_COMPLETION_ONSTACK(tm_done); 1522 DECLARE_COMPLETION_ONSTACK(tm_done);
1542 1523
1543 /* Wait for rport to unblock */ 1524 /* Wait for rport to unblock */
1544 fnic_block_error_handler(sc); 1525 fc_block_scsi_eh(sc);
1545 1526
1546 /* Get local-port, check ready and link up */ 1527 /* Get local-port, check ready and link up */
1547 lp = shost_priv(sc->device->host); 1528 lp = shost_priv(sc->device->host);
@@ -1762,7 +1743,7 @@ void fnic_scsi_abort_io(struct fc_lport *lp)
1762 fnic->remove_wait = &remove_wait; 1743 fnic->remove_wait = &remove_wait;
1763 old_state = fnic->state; 1744 old_state = fnic->state;
1764 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; 1745 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
1765 vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); 1746 fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
1766 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 1747 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
1767 1748
1768 err = fnic_fw_reset_handler(fnic); 1749 err = fnic_fw_reset_handler(fnic);
@@ -1802,7 +1783,7 @@ void fnic_scsi_cleanup(struct fc_lport *lp)
1802 spin_lock_irqsave(&fnic->fnic_lock, flags); 1783 spin_lock_irqsave(&fnic->fnic_lock, flags);
1803 old_state = fnic->state; 1784 old_state = fnic->state;
1804 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; 1785 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
1805 vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); 1786 fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
1806 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 1787 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
1807 1788
1808 if (fnic_fw_reset_handler(fnic)) { 1789 if (fnic_fw_reset_handler(fnic)) {
diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c
index 566770645086..db710148d156 100644
--- a/drivers/scsi/fnic/vnic_dev.c
+++ b/drivers/scsi/fnic/vnic_dev.c
@@ -22,6 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/if_ether.h> 24#include <linux/if_ether.h>
25#include <linux/slab.h>
25#include "vnic_resource.h" 26#include "vnic_resource.h"
26#include "vnic_devcmd.h" 27#include "vnic_devcmd.h"
27#include "vnic_dev.h" 28#include "vnic_dev.h"
diff --git a/drivers/scsi/fnic/vnic_devcmd.h b/drivers/scsi/fnic/vnic_devcmd.h
index d62b9061bf12..7c9ccbd4134b 100644
--- a/drivers/scsi/fnic/vnic_devcmd.h
+++ b/drivers/scsi/fnic/vnic_devcmd.h
@@ -94,7 +94,7 @@ enum vnic_devcmd_cmd {
94 CMD_STATS_DUMP = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 4), 94 CMD_STATS_DUMP = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 4),
95 95
96 /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */ 96 /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */
97 CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7), 97 CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 7),
98 98
99 /* hang detection notification */ 99 /* hang detection notification */
100 CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8), 100 CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
diff --git a/drivers/scsi/fnic/vnic_rq.c b/drivers/scsi/fnic/vnic_rq.c
index bedd0d285630..fd2068f5ae16 100644
--- a/drivers/scsi/fnic/vnic_rq.c
+++ b/drivers/scsi/fnic/vnic_rq.c
@@ -20,6 +20,7 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/slab.h>
23#include "vnic_dev.h" 24#include "vnic_dev.h"
24#include "vnic_rq.h" 25#include "vnic_rq.h"
25 26
diff --git a/drivers/scsi/fnic/vnic_scsi.h b/drivers/scsi/fnic/vnic_scsi.h
index 46baa5254001..fbb55364e272 100644
--- a/drivers/scsi/fnic/vnic_scsi.h
+++ b/drivers/scsi/fnic/vnic_scsi.h
@@ -95,5 +95,6 @@ struct vnic_fc_config {
95 95
96#define VFCF_FCP_SEQ_LVL_ERR 0x1 /* Enable FCP-2 Error Recovery */ 96#define VFCF_FCP_SEQ_LVL_ERR 0x1 /* Enable FCP-2 Error Recovery */
97#define VFCF_PERBI 0x2 /* persistent binding info available */ 97#define VFCF_PERBI 0x2 /* persistent binding info available */
98#define VFCF_FIP_CAPABLE 0x4 /* firmware can handle FIP */
98 99
99#endif /* _VNIC_SCSI_H_ */ 100#endif /* _VNIC_SCSI_H_ */
diff --git a/drivers/scsi/fnic/vnic_wq.c b/drivers/scsi/fnic/vnic_wq.c
index 1f9ea790d130..a414135460db 100644
--- a/drivers/scsi/fnic/vnic_wq.c
+++ b/drivers/scsi/fnic/vnic_wq.c
@@ -20,6 +20,7 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/slab.h>
23#include "vnic_dev.h" 24#include "vnic_dev.h"
24#include "vnic_wq.h" 25#include "vnic_wq.h"
25 26