diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:42:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:42:25 -0500 |
commit | 382f51fe2f2276344d8a21447656778cdf6583b6 (patch) | |
tree | c2836a2cca4126c9c026ce5aa2fdf9f1c8ccded6 /drivers/scsi/fcoe/libfcoe.c | |
parent | 701791cc3c8fc6dd83f6ec8af7e2541b4a316606 (diff) | |
parent | 54987386ee3790f3900de4df2ed4deb0e18dfc9f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (222 commits)
[SCSI] zfcp: Remove flag ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP
[SCSI] zfcp: Activate fc4s attributes for zfcp in FC transport class
[SCSI] zfcp: Block scsi_eh thread for rport state BLOCKED
[SCSI] zfcp: Update FSF error reporting
[SCSI] zfcp: Improve ELS ADISC handling
[SCSI] zfcp: Simplify handling of ct and els requests
[SCSI] zfcp: Remove ZFCP_DID_MASK
[SCSI] zfcp: Move WKA port to zfcp FC code
[SCSI] zfcp: Use common code definitions for FC CT structs
[SCSI] zfcp: Use common code definitions for FC ELS structs
[SCSI] zfcp: Update FCP protocol related code
[SCSI] zfcp: Dont fail SCSI commands when transitioning to blocked fc_rport
[SCSI] zfcp: Assign scheduled work to driver queue
[SCSI] zfcp: Remove STATUS_COMMON_REMOVE flag as it is not required anymore
[SCSI] zfcp: Implement module unloading
[SCSI] zfcp: Merge trace code for fsf requests in one function
[SCSI] zfcp: Access ports and units with container_of in sysfs code
[SCSI] zfcp: Remove suspend callback
[SCSI] zfcp: Remove global config_mutex
[SCSI] zfcp: Replace local reference counting with common kref
...
Diffstat (limited to 'drivers/scsi/fcoe/libfcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 433 |
1 files changed, 236 insertions, 197 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 11ae5c94608b..9823291395ad 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -59,26 +59,30 @@ unsigned int libfcoe_debug_logging; | |||
59 | module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); | 59 | module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); |
60 | MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); | 60 | MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); |
61 | 61 | ||
62 | #define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ | 62 | #define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ |
63 | #define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */ | 63 | #define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */ |
64 | 64 | ||
65 | #define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ | 65 | #define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ |
66 | do { \ | 66 | do { \ |
67 | if (unlikely(libfcoe_debug_logging & LEVEL)) \ | 67 | if (unlikely(libfcoe_debug_logging & LEVEL)) \ |
68 | do { \ | 68 | do { \ |
69 | CMD; \ | 69 | CMD; \ |
70 | } while (0); \ | 70 | } while (0); \ |
71 | } while (0) | 71 | } while (0) |
72 | 72 | ||
73 | #define LIBFCOE_DBG(fmt, args...) \ | 73 | #define LIBFCOE_DBG(fmt, args...) \ |
74 | LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ | 74 | LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ |
75 | printk(KERN_INFO "libfcoe: " fmt, ##args);) | 75 | printk(KERN_INFO "libfcoe: " fmt, ##args);) |
76 | 76 | ||
77 | #define LIBFCOE_FIP_DBG(fmt, args...) \ | 77 | #define LIBFCOE_FIP_DBG(fip, fmt, args...) \ |
78 | LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \ | 78 | LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \ |
79 | printk(KERN_INFO "fip: " fmt, ##args);) | 79 | printk(KERN_INFO "host%d: fip: " fmt, \ |
80 | (fip)->lp->host->host_no, ##args);) | ||
80 | 81 | ||
81 | /* | 82 | /** |
83 | * fcoe_ctlr_mtu_valid() - Check if a FCF's MTU is valid | ||
84 | * @fcf: The FCF to check | ||
85 | * | ||
82 | * Return non-zero if FCF fcoe_size has been validated. | 86 | * Return non-zero if FCF fcoe_size has been validated. |
83 | */ | 87 | */ |
84 | static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf) | 88 | static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf) |
@@ -86,7 +90,10 @@ static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf) | |||
86 | return (fcf->flags & FIP_FL_SOL) != 0; | 90 | return (fcf->flags & FIP_FL_SOL) != 0; |
87 | } | 91 | } |
88 | 92 | ||
89 | /* | 93 | /** |
94 | * fcoe_ctlr_fcf_usable() - Check if a FCF is usable | ||
95 | * @fcf: The FCF to check | ||
96 | * | ||
90 | * Return non-zero if the FCF is usable. | 97 | * Return non-zero if the FCF is usable. |
91 | */ | 98 | */ |
92 | static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf) | 99 | static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf) |
@@ -97,12 +104,13 @@ static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf) | |||
97 | } | 104 | } |
98 | 105 | ||
99 | /** | 106 | /** |
100 | * fcoe_ctlr_init() - Initialize the FCoE Controller instance. | 107 | * fcoe_ctlr_init() - Initialize the FCoE Controller instance |
101 | * @fip: FCoE controller. | 108 | * @fip: The FCoE controller to initialize |
102 | */ | 109 | */ |
103 | void fcoe_ctlr_init(struct fcoe_ctlr *fip) | 110 | void fcoe_ctlr_init(struct fcoe_ctlr *fip) |
104 | { | 111 | { |
105 | fip->state = FIP_ST_LINK_WAIT; | 112 | fip->state = FIP_ST_LINK_WAIT; |
113 | fip->mode = FIP_ST_AUTO; | ||
106 | INIT_LIST_HEAD(&fip->fcfs); | 114 | INIT_LIST_HEAD(&fip->fcfs); |
107 | spin_lock_init(&fip->lock); | 115 | spin_lock_init(&fip->lock); |
108 | fip->flogi_oxid = FC_XID_UNKNOWN; | 116 | fip->flogi_oxid = FC_XID_UNKNOWN; |
@@ -114,8 +122,8 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip) | |||
114 | EXPORT_SYMBOL(fcoe_ctlr_init); | 122 | EXPORT_SYMBOL(fcoe_ctlr_init); |
115 | 123 | ||
116 | /** | 124 | /** |
117 | * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller. | 125 | * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller |
118 | * @fip: FCoE controller. | 126 | * @fip: The FCoE controller whose FCFs are to be reset |
119 | * | 127 | * |
120 | * Called with &fcoe_ctlr lock held. | 128 | * Called with &fcoe_ctlr lock held. |
121 | */ | 129 | */ |
@@ -134,8 +142,8 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) | |||
134 | } | 142 | } |
135 | 143 | ||
136 | /** | 144 | /** |
137 | * fcoe_ctlr_destroy() - Disable and tear-down the FCoE controller. | 145 | * fcoe_ctlr_destroy() - Disable and tear down a FCoE controller |
138 | * @fip: FCoE controller. | 146 | * @fip: The FCoE controller to tear down |
139 | * | 147 | * |
140 | * This is called by FCoE drivers before freeing the &fcoe_ctlr. | 148 | * This is called by FCoE drivers before freeing the &fcoe_ctlr. |
141 | * | 149 | * |
@@ -148,9 +156,7 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) | |||
148 | void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) | 156 | void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) |
149 | { | 157 | { |
150 | cancel_work_sync(&fip->recv_work); | 158 | cancel_work_sync(&fip->recv_work); |
151 | spin_lock_bh(&fip->fip_recv_list.lock); | 159 | skb_queue_purge(&fip->fip_recv_list); |
152 | __skb_queue_purge(&fip->fip_recv_list); | ||
153 | spin_unlock_bh(&fip->fip_recv_list.lock); | ||
154 | 160 | ||
155 | spin_lock_bh(&fip->lock); | 161 | spin_lock_bh(&fip->lock); |
156 | fip->state = FIP_ST_DISABLED; | 162 | fip->state = FIP_ST_DISABLED; |
@@ -162,8 +168,8 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) | |||
162 | EXPORT_SYMBOL(fcoe_ctlr_destroy); | 168 | EXPORT_SYMBOL(fcoe_ctlr_destroy); |
163 | 169 | ||
164 | /** | 170 | /** |
165 | * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port. | 171 | * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port |
166 | * @fip: FCoE controller. | 172 | * @fip: The FCoE controller to get the maximum FCoE size from |
167 | * | 173 | * |
168 | * Returns the maximum packet size including the FCoE header and trailer, | 174 | * Returns the maximum packet size including the FCoE header and trailer, |
169 | * but not including any Ethernet or VLAN headers. | 175 | * but not including any Ethernet or VLAN headers. |
@@ -180,9 +186,9 @@ static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip) | |||
180 | } | 186 | } |
181 | 187 | ||
182 | /** | 188 | /** |
183 | * fcoe_ctlr_solicit() - Send a solicitation. | 189 | * fcoe_ctlr_solicit() - Send a FIP solicitation |
184 | * @fip: FCoE controller. | 190 | * @fip: The FCoE controller to send the solicitation on |
185 | * @fcf: Destination FCF. If NULL, a multicast solicitation is sent. | 191 | * @fcf: The destination FCF (if NULL, a multicast solicitation is sent) |
186 | */ | 192 | */ |
187 | static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) | 193 | static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) |
188 | { | 194 | { |
@@ -241,8 +247,8 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) | |||
241 | } | 247 | } |
242 | 248 | ||
243 | /** | 249 | /** |
244 | * fcoe_ctlr_link_up() - Start FCoE controller. | 250 | * fcoe_ctlr_link_up() - Start FCoE controller |
245 | * @fip: FCoE controller. | 251 | * @fip: The FCoE controller to start |
246 | * | 252 | * |
247 | * Called from the LLD when the network link is ready. | 253 | * Called from the LLD when the network link is ready. |
248 | */ | 254 | */ |
@@ -255,11 +261,12 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) | |||
255 | spin_unlock_bh(&fip->lock); | 261 | spin_unlock_bh(&fip->lock); |
256 | fc_linkup(fip->lp); | 262 | fc_linkup(fip->lp); |
257 | } else if (fip->state == FIP_ST_LINK_WAIT) { | 263 | } else if (fip->state == FIP_ST_LINK_WAIT) { |
258 | fip->state = FIP_ST_AUTO; | 264 | fip->state = fip->mode; |
259 | fip->last_link = 1; | 265 | fip->last_link = 1; |
260 | fip->link = 1; | 266 | fip->link = 1; |
261 | spin_unlock_bh(&fip->lock); | 267 | spin_unlock_bh(&fip->lock); |
262 | LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n"); | 268 | if (fip->state == FIP_ST_AUTO) |
269 | LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n"); | ||
263 | fc_linkup(fip->lp); | 270 | fc_linkup(fip->lp); |
264 | fcoe_ctlr_solicit(fip, NULL); | 271 | fcoe_ctlr_solicit(fip, NULL); |
265 | } else | 272 | } else |
@@ -268,45 +275,23 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) | |||
268 | EXPORT_SYMBOL(fcoe_ctlr_link_up); | 275 | EXPORT_SYMBOL(fcoe_ctlr_link_up); |
269 | 276 | ||
270 | /** | 277 | /** |
271 | * fcoe_ctlr_reset() - Reset FIP. | 278 | * fcoe_ctlr_reset() - Reset a FCoE controller |
272 | * @fip: FCoE controller. | 279 | * @fip: The FCoE controller to reset |
273 | * @new_state: FIP state to be entered. | ||
274 | * | ||
275 | * Returns non-zero if the link was up and now isn't. | ||
276 | */ | 280 | */ |
277 | static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) | 281 | static void fcoe_ctlr_reset(struct fcoe_ctlr *fip) |
278 | { | 282 | { |
279 | struct fc_lport *lp = fip->lp; | ||
280 | int link_dropped; | ||
281 | |||
282 | spin_lock_bh(&fip->lock); | ||
283 | fcoe_ctlr_reset_fcfs(fip); | 283 | fcoe_ctlr_reset_fcfs(fip); |
284 | del_timer(&fip->timer); | 284 | del_timer(&fip->timer); |
285 | fip->state = new_state; | ||
286 | fip->ctlr_ka_time = 0; | 285 | fip->ctlr_ka_time = 0; |
287 | fip->port_ka_time = 0; | 286 | fip->port_ka_time = 0; |
288 | fip->sol_time = 0; | 287 | fip->sol_time = 0; |
289 | fip->flogi_oxid = FC_XID_UNKNOWN; | 288 | fip->flogi_oxid = FC_XID_UNKNOWN; |
290 | fip->map_dest = 0; | 289 | fip->map_dest = 0; |
291 | fip->last_link = 0; | ||
292 | link_dropped = fip->link; | ||
293 | fip->link = 0; | ||
294 | spin_unlock_bh(&fip->lock); | ||
295 | |||
296 | if (link_dropped) | ||
297 | fc_linkdown(lp); | ||
298 | |||
299 | if (new_state == FIP_ST_ENABLED) { | ||
300 | fcoe_ctlr_solicit(fip, NULL); | ||
301 | fc_linkup(lp); | ||
302 | link_dropped = 0; | ||
303 | } | ||
304 | return link_dropped; | ||
305 | } | 290 | } |
306 | 291 | ||
307 | /** | 292 | /** |
308 | * fcoe_ctlr_link_down() - Stop FCoE controller. | 293 | * fcoe_ctlr_link_down() - Stop a FCoE controller |
309 | * @fip: FCoE controller. | 294 | * @fip: The FCoE controller to be stopped |
310 | * | 295 | * |
311 | * Returns non-zero if the link was up and now isn't. | 296 | * Returns non-zero if the link was up and now isn't. |
312 | * | 297 | * |
@@ -315,15 +300,29 @@ static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) | |||
315 | */ | 300 | */ |
316 | int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) | 301 | int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) |
317 | { | 302 | { |
318 | return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); | 303 | int link_dropped; |
304 | |||
305 | LIBFCOE_FIP_DBG(fip, "link down.\n"); | ||
306 | spin_lock_bh(&fip->lock); | ||
307 | fcoe_ctlr_reset(fip); | ||
308 | link_dropped = fip->link; | ||
309 | fip->link = 0; | ||
310 | fip->last_link = 0; | ||
311 | fip->state = FIP_ST_LINK_WAIT; | ||
312 | spin_unlock_bh(&fip->lock); | ||
313 | |||
314 | if (link_dropped) | ||
315 | fc_linkdown(fip->lp); | ||
316 | return link_dropped; | ||
319 | } | 317 | } |
320 | EXPORT_SYMBOL(fcoe_ctlr_link_down); | 318 | EXPORT_SYMBOL(fcoe_ctlr_link_down); |
321 | 319 | ||
322 | /** | 320 | /** |
323 | * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF. | 321 | * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF |
324 | * @fip: FCoE controller. | 322 | * @fip: The FCoE controller to send the FKA on |
325 | * @ports: 0 for controller keep-alive, 1 for port keep-alive. | 323 | * @lport: libfc fc_lport to send from |
326 | * @sa: source MAC address. | 324 | * @ports: 0 for controller keep-alive, 1 for port keep-alive |
325 | * @sa: The source MAC address | ||
327 | * | 326 | * |
328 | * A controller keep-alive is sent every fka_period (typically 8 seconds). | 327 | * A controller keep-alive is sent every fka_period (typically 8 seconds). |
329 | * The source MAC is the native MAC address. | 328 | * The source MAC is the native MAC address. |
@@ -332,7 +331,9 @@ EXPORT_SYMBOL(fcoe_ctlr_link_down); | |||
332 | * The source MAC is the assigned mapped source address. | 331 | * The source MAC is the assigned mapped source address. |
333 | * The destination is the FCF's F-port. | 332 | * The destination is the FCF's F-port. |
334 | */ | 333 | */ |
335 | static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | 334 | static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, |
335 | struct fc_lport *lport, | ||
336 | int ports, u8 *sa) | ||
336 | { | 337 | { |
337 | struct sk_buff *skb; | 338 | struct sk_buff *skb; |
338 | struct fip_kal { | 339 | struct fip_kal { |
@@ -350,8 +351,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | |||
350 | if (!fcf || !fc_host_port_id(lp->host)) | 351 | if (!fcf || !fc_host_port_id(lp->host)) |
351 | return; | 352 | return; |
352 | 353 | ||
353 | len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr); | 354 | len = sizeof(*kal) + ports * sizeof(*vn); |
354 | BUG_ON(len < sizeof(*kal) + sizeof(*vn)); | ||
355 | skb = dev_alloc_skb(len); | 355 | skb = dev_alloc_skb(len); |
356 | if (!skb) | 356 | if (!skb) |
357 | return; | 357 | return; |
@@ -366,7 +366,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | |||
366 | kal->fip.fip_op = htons(FIP_OP_CTRL); | 366 | kal->fip.fip_op = htons(FIP_OP_CTRL); |
367 | kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE; | 367 | kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE; |
368 | kal->fip.fip_dl_len = htons((sizeof(kal->mac) + | 368 | kal->fip.fip_dl_len = htons((sizeof(kal->mac) + |
369 | ports * sizeof(*vn)) / FIP_BPW); | 369 | ports * sizeof(*vn)) / FIP_BPW); |
370 | kal->fip.fip_flags = htons(FIP_FL_FPMA); | 370 | kal->fip.fip_flags = htons(FIP_FL_FPMA); |
371 | if (fip->spma) | 371 | if (fip->spma) |
372 | kal->fip.fip_flags |= htons(FIP_FL_SPMA); | 372 | kal->fip.fip_flags |= htons(FIP_FL_SPMA); |
@@ -374,16 +374,14 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | |||
374 | kal->mac.fd_desc.fip_dtype = FIP_DT_MAC; | 374 | kal->mac.fd_desc.fip_dtype = FIP_DT_MAC; |
375 | kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW; | 375 | kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW; |
376 | memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN); | 376 | memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN); |
377 | |||
378 | if (ports) { | 377 | if (ports) { |
379 | vn = (struct fip_vn_desc *)(kal + 1); | 378 | vn = (struct fip_vn_desc *)(kal + 1); |
380 | vn->fd_desc.fip_dtype = FIP_DT_VN_ID; | 379 | vn->fd_desc.fip_dtype = FIP_DT_VN_ID; |
381 | vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW; | 380 | vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW; |
382 | memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN); | 381 | memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN); |
383 | hton24(vn->fd_fc_id, fc_host_port_id(lp->host)); | 382 | hton24(vn->fd_fc_id, fc_host_port_id(lp->host)); |
384 | put_unaligned_be64(lp->wwpn, &vn->fd_wwpn); | 383 | put_unaligned_be64(lp->wwpn, &vn->fd_wwpn); |
385 | } | 384 | } |
386 | |||
387 | skb_put(skb, len); | 385 | skb_put(skb, len); |
388 | skb->protocol = htons(ETH_P_FIP); | 386 | skb->protocol = htons(ETH_P_FIP); |
389 | skb_reset_mac_header(skb); | 387 | skb_reset_mac_header(skb); |
@@ -392,10 +390,10 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | |||
392 | } | 390 | } |
393 | 391 | ||
394 | /** | 392 | /** |
395 | * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it. | 393 | * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it |
396 | * @fip: FCoE controller. | 394 | * @fip: The FCoE controller for the ELS frame |
397 | * @dtype: FIP descriptor type for the frame. | 395 | * @dtype: The FIP descriptor type for the frame |
398 | * @skb: FCoE ELS frame including FC header but no FCoE headers. | 396 | * @skb: The FCoE ELS frame including FC header but no FCoE headers |
399 | * | 397 | * |
400 | * Returns non-zero error code on failure. | 398 | * Returns non-zero error code on failure. |
401 | * | 399 | * |
@@ -405,7 +403,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) | |||
405 | * Headroom includes the FIP encapsulation description, FIP header, and | 403 | * Headroom includes the FIP encapsulation description, FIP header, and |
406 | * Ethernet header. The tailroom is for the FIP MAC descriptor. | 404 | * Ethernet header. The tailroom is for the FIP MAC descriptor. |
407 | */ | 405 | */ |
408 | static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, | 406 | static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport, |
409 | u8 dtype, struct sk_buff *skb) | 407 | u8 dtype, struct sk_buff *skb) |
410 | { | 408 | { |
411 | struct fip_encaps_head { | 409 | struct fip_encaps_head { |
@@ -449,8 +447,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, | |||
449 | memset(mac, 0, sizeof(mac)); | 447 | memset(mac, 0, sizeof(mac)); |
450 | mac->fd_desc.fip_dtype = FIP_DT_MAC; | 448 | mac->fd_desc.fip_dtype = FIP_DT_MAC; |
451 | mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; | 449 | mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; |
452 | if (dtype != FIP_DT_FLOGI) | 450 | if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) |
453 | memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); | 451 | memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN); |
454 | else if (fip->spma) | 452 | else if (fip->spma) |
455 | memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); | 453 | memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); |
456 | 454 | ||
@@ -463,6 +461,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, | |||
463 | /** | 461 | /** |
464 | * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate. | 462 | * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate. |
465 | * @fip: FCoE controller. | 463 | * @fip: FCoE controller. |
464 | * @lport: libfc fc_lport to send from | ||
466 | * @skb: FCoE ELS frame including FC header but no FCoE headers. | 465 | * @skb: FCoE ELS frame including FC header but no FCoE headers. |
467 | * | 466 | * |
468 | * Returns a non-zero error code if the frame should not be sent. | 467 | * Returns a non-zero error code if the frame should not be sent. |
@@ -471,11 +470,13 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, | |||
471 | * The caller must check that the length is a multiple of 4. | 470 | * The caller must check that the length is a multiple of 4. |
472 | * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). | 471 | * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). |
473 | */ | 472 | */ |
474 | int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | 473 | int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, |
474 | struct sk_buff *skb) | ||
475 | { | 475 | { |
476 | struct fc_frame_header *fh; | 476 | struct fc_frame_header *fh; |
477 | u16 old_xid; | 477 | u16 old_xid; |
478 | u8 op; | 478 | u8 op; |
479 | u8 mac[ETH_ALEN]; | ||
479 | 480 | ||
480 | fh = (struct fc_frame_header *)skb->data; | 481 | fh = (struct fc_frame_header *)skb->data; |
481 | op = *(u8 *)(fh + 1); | 482 | op = *(u8 *)(fh + 1); |
@@ -498,6 +499,8 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
498 | 499 | ||
499 | if (fip->state == FIP_ST_NON_FIP) | 500 | if (fip->state == FIP_ST_NON_FIP) |
500 | return 0; | 501 | return 0; |
502 | if (!fip->sel_fcf) | ||
503 | goto drop; | ||
501 | 504 | ||
502 | switch (op) { | 505 | switch (op) { |
503 | case ELS_FLOGI: | 506 | case ELS_FLOGI: |
@@ -530,14 +533,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
530 | * FLOGI. | 533 | * FLOGI. |
531 | */ | 534 | */ |
532 | fip->flogi_oxid = FC_XID_UNKNOWN; | 535 | fip->flogi_oxid = FC_XID_UNKNOWN; |
533 | fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id); | 536 | fc_fcoe_set_mac(mac, fh->fh_d_id); |
537 | fip->update_mac(lport, mac); | ||
534 | return 0; | 538 | return 0; |
535 | default: | 539 | default: |
536 | if (fip->state != FIP_ST_ENABLED) | 540 | if (fip->state != FIP_ST_ENABLED) |
537 | goto drop; | 541 | goto drop; |
538 | return 0; | 542 | return 0; |
539 | } | 543 | } |
540 | if (fcoe_ctlr_encaps(fip, op, skb)) | 544 | if (fcoe_ctlr_encaps(fip, lport, op, skb)) |
541 | goto drop; | 545 | goto drop; |
542 | fip->send(fip, skb); | 546 | fip->send(fip, skb); |
543 | return -EINPROGRESS; | 547 | return -EINPROGRESS; |
@@ -547,9 +551,9 @@ drop: | |||
547 | } | 551 | } |
548 | EXPORT_SYMBOL(fcoe_ctlr_els_send); | 552 | EXPORT_SYMBOL(fcoe_ctlr_els_send); |
549 | 553 | ||
550 | /* | 554 | /** |
551 | * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller. | 555 | * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller |
552 | * @fip: FCoE controller. | 556 | * @fip: The FCoE controller to free FCFs on |
553 | * | 557 | * |
554 | * Called with lock held. | 558 | * Called with lock held. |
555 | * | 559 | * |
@@ -558,14 +562,28 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send); | |||
558 | * times its keep-alive period including fuzz. | 562 | * times its keep-alive period including fuzz. |
559 | * | 563 | * |
560 | * In addition, determine the time when an FCF selection can occur. | 564 | * In addition, determine the time when an FCF selection can occur. |
565 | * | ||
566 | * Also, increment the MissDiscAdvCount when no advertisement is received | ||
567 | * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB). | ||
561 | */ | 568 | */ |
562 | static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) | 569 | static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) |
563 | { | 570 | { |
564 | struct fcoe_fcf *fcf; | 571 | struct fcoe_fcf *fcf; |
565 | struct fcoe_fcf *next; | 572 | struct fcoe_fcf *next; |
566 | unsigned long sel_time = 0; | 573 | unsigned long sel_time = 0; |
574 | unsigned long mda_time = 0; | ||
567 | 575 | ||
568 | list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { | 576 | list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { |
577 | mda_time = fcf->fka_period + (fcf->fka_period >> 1); | ||
578 | if ((fip->sel_fcf == fcf) && | ||
579 | (time_after(jiffies, fcf->time + mda_time))) { | ||
580 | mod_timer(&fip->timer, jiffies + mda_time); | ||
581 | fc_lport_get_stats(fip->lp)->MissDiscAdvCount++; | ||
582 | printk(KERN_INFO "libfcoe: host%d: Missing Discovery " | ||
583 | "Advertisement for fab %llx count %lld\n", | ||
584 | fip->lp->host->host_no, fcf->fabric_name, | ||
585 | fc_lport_get_stats(fip->lp)->MissDiscAdvCount); | ||
586 | } | ||
569 | if (time_after(jiffies, fcf->time + fcf->fka_period * 3 + | 587 | if (time_after(jiffies, fcf->time + fcf->fka_period * 3 + |
570 | msecs_to_jiffies(FIP_FCF_FUZZ * 3))) { | 588 | msecs_to_jiffies(FIP_FCF_FUZZ * 3))) { |
571 | if (fip->sel_fcf == fcf) | 589 | if (fip->sel_fcf == fcf) |
@@ -574,6 +592,7 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) | |||
574 | WARN_ON(!fip->fcf_count); | 592 | WARN_ON(!fip->fcf_count); |
575 | fip->fcf_count--; | 593 | fip->fcf_count--; |
576 | kfree(fcf); | 594 | kfree(fcf); |
595 | fc_lport_get_stats(fip->lp)->VLinkFailureCount++; | ||
577 | } else if (fcoe_ctlr_mtu_valid(fcf) && | 596 | } else if (fcoe_ctlr_mtu_valid(fcf) && |
578 | (!sel_time || time_before(sel_time, fcf->time))) { | 597 | (!sel_time || time_before(sel_time, fcf->time))) { |
579 | sel_time = fcf->time; | 598 | sel_time = fcf->time; |
@@ -590,14 +609,16 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) | |||
590 | } | 609 | } |
591 | 610 | ||
592 | /** | 611 | /** |
593 | * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry. | 612 | * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry |
594 | * @skb: received FIP advertisement frame | 613 | * @fip: The FCoE controller receiving the advertisement |
595 | * @fcf: resulting FCF entry. | 614 | * @skb: The received FIP advertisement frame |
615 | * @fcf: The resulting FCF entry | ||
596 | * | 616 | * |
597 | * Returns zero on a valid parsed advertisement, | 617 | * Returns zero on a valid parsed advertisement, |
598 | * otherwise returns non zero value. | 618 | * otherwise returns non zero value. |
599 | */ | 619 | */ |
600 | static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) | 620 | static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip, |
621 | struct sk_buff *skb, struct fcoe_fcf *fcf) | ||
601 | { | 622 | { |
602 | struct fip_header *fiph; | 623 | struct fip_header *fiph; |
603 | struct fip_desc *desc = NULL; | 624 | struct fip_desc *desc = NULL; |
@@ -636,7 +657,7 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) | |||
636 | ((struct fip_mac_desc *)desc)->fd_mac, | 657 | ((struct fip_mac_desc *)desc)->fd_mac, |
637 | ETH_ALEN); | 658 | ETH_ALEN); |
638 | if (!is_valid_ether_addr(fcf->fcf_mac)) { | 659 | if (!is_valid_ether_addr(fcf->fcf_mac)) { |
639 | LIBFCOE_FIP_DBG("Invalid MAC address " | 660 | LIBFCOE_FIP_DBG(fip, "Invalid MAC address " |
640 | "in FIP adv\n"); | 661 | "in FIP adv\n"); |
641 | return -EINVAL; | 662 | return -EINVAL; |
642 | } | 663 | } |
@@ -659,6 +680,8 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) | |||
659 | if (dlen != sizeof(struct fip_fka_desc)) | 680 | if (dlen != sizeof(struct fip_fka_desc)) |
660 | goto len_err; | 681 | goto len_err; |
661 | fka = (struct fip_fka_desc *)desc; | 682 | fka = (struct fip_fka_desc *)desc; |
683 | if (fka->fd_flags & FIP_FKA_ADV_D) | ||
684 | fcf->fd_flags = 1; | ||
662 | t = ntohl(fka->fd_fka_period); | 685 | t = ntohl(fka->fd_fka_period); |
663 | if (t >= FCOE_CTLR_MIN_FKA) | 686 | if (t >= FCOE_CTLR_MIN_FKA) |
664 | fcf->fka_period = msecs_to_jiffies(t); | 687 | fcf->fka_period = msecs_to_jiffies(t); |
@@ -670,7 +693,7 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) | |||
670 | case FIP_DT_LOGO: | 693 | case FIP_DT_LOGO: |
671 | case FIP_DT_ELP: | 694 | case FIP_DT_ELP: |
672 | default: | 695 | default: |
673 | LIBFCOE_FIP_DBG("unexpected descriptor type %x " | 696 | LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " |
674 | "in FIP adv\n", desc->fip_dtype); | 697 | "in FIP adv\n", desc->fip_dtype); |
675 | /* standard says ignore unknown descriptors >= 128 */ | 698 | /* standard says ignore unknown descriptors >= 128 */ |
676 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) | 699 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) |
@@ -687,15 +710,15 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) | |||
687 | return 0; | 710 | return 0; |
688 | 711 | ||
689 | len_err: | 712 | len_err: |
690 | LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n", | 713 | LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n", |
691 | desc->fip_dtype, dlen); | 714 | desc->fip_dtype, dlen); |
692 | return -EINVAL; | 715 | return -EINVAL; |
693 | } | 716 | } |
694 | 717 | ||
695 | /** | 718 | /** |
696 | * fcoe_ctlr_recv_adv() - Handle an incoming advertisement. | 719 | * fcoe_ctlr_recv_adv() - Handle an incoming advertisement |
697 | * @fip: FCoE controller. | 720 | * @fip: The FCoE controller receiving the advertisement |
698 | * @skb: Received FIP packet. | 721 | * @skb: The received FIP packet |
699 | */ | 722 | */ |
700 | static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | 723 | static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
701 | { | 724 | { |
@@ -706,7 +729,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
706 | int first = 0; | 729 | int first = 0; |
707 | int mtu_valid; | 730 | int mtu_valid; |
708 | 731 | ||
709 | if (fcoe_ctlr_parse_adv(skb, &new)) | 732 | if (fcoe_ctlr_parse_adv(fip, skb, &new)) |
710 | return; | 733 | return; |
711 | 734 | ||
712 | spin_lock_bh(&fip->lock); | 735 | spin_lock_bh(&fip->lock); |
@@ -752,7 +775,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
752 | mtu_valid = fcoe_ctlr_mtu_valid(fcf); | 775 | mtu_valid = fcoe_ctlr_mtu_valid(fcf); |
753 | fcf->time = jiffies; | 776 | fcf->time = jiffies; |
754 | if (!found) { | 777 | if (!found) { |
755 | LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n", | 778 | LIBFCOE_FIP_DBG(fip, "New FCF for fab %llx map %x val %d\n", |
756 | fcf->fabric_name, fcf->fc_map, mtu_valid); | 779 | fcf->fabric_name, fcf->fc_map, mtu_valid); |
757 | } | 780 | } |
758 | 781 | ||
@@ -778,7 +801,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
778 | */ | 801 | */ |
779 | if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) { | 802 | if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) { |
780 | fip->sel_time = jiffies + | 803 | fip->sel_time = jiffies + |
781 | msecs_to_jiffies(FCOE_CTLR_START_DELAY); | 804 | msecs_to_jiffies(FCOE_CTLR_START_DELAY); |
782 | if (!timer_pending(&fip->timer) || | 805 | if (!timer_pending(&fip->timer) || |
783 | time_before(fip->sel_time, fip->timer.expires)) | 806 | time_before(fip->sel_time, fip->timer.expires)) |
784 | mod_timer(&fip->timer, fip->sel_time); | 807 | mod_timer(&fip->timer, fip->sel_time); |
@@ -788,15 +811,15 @@ out: | |||
788 | } | 811 | } |
789 | 812 | ||
790 | /** | 813 | /** |
791 | * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame. | 814 | * fcoe_ctlr_recv_els() - Handle an incoming FIP encapsulated ELS frame |
792 | * @fip: FCoE controller. | 815 | * @fip: The FCoE controller which received the packet |
793 | * @skb: Received FIP packet. | 816 | * @skb: The received FIP packet |
794 | */ | 817 | */ |
795 | static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | 818 | static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) |
796 | { | 819 | { |
797 | struct fc_lport *lp = fip->lp; | 820 | struct fc_lport *lport = fip->lp; |
798 | struct fip_header *fiph; | 821 | struct fip_header *fiph; |
799 | struct fc_frame *fp; | 822 | struct fc_frame *fp = (struct fc_frame *)skb; |
800 | struct fc_frame_header *fh = NULL; | 823 | struct fc_frame_header *fh = NULL; |
801 | struct fip_desc *desc; | 824 | struct fip_desc *desc; |
802 | struct fip_encaps *els; | 825 | struct fip_encaps *els; |
@@ -831,10 +854,11 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
831 | ((struct fip_mac_desc *)desc)->fd_mac, | 854 | ((struct fip_mac_desc *)desc)->fd_mac, |
832 | ETH_ALEN); | 855 | ETH_ALEN); |
833 | if (!is_valid_ether_addr(granted_mac)) { | 856 | if (!is_valid_ether_addr(granted_mac)) { |
834 | LIBFCOE_FIP_DBG("Invalid MAC address " | 857 | LIBFCOE_FIP_DBG(fip, "Invalid MAC address " |
835 | "in FIP ELS\n"); | 858 | "in FIP ELS\n"); |
836 | goto drop; | 859 | goto drop; |
837 | } | 860 | } |
861 | memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); | ||
838 | break; | 862 | break; |
839 | case FIP_DT_FLOGI: | 863 | case FIP_DT_FLOGI: |
840 | case FIP_DT_FDISC: | 864 | case FIP_DT_FDISC: |
@@ -850,7 +874,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
850 | els_dtype = desc->fip_dtype; | 874 | els_dtype = desc->fip_dtype; |
851 | break; | 875 | break; |
852 | default: | 876 | default: |
853 | LIBFCOE_FIP_DBG("unexpected descriptor type %x " | 877 | LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " |
854 | "in FIP adv\n", desc->fip_dtype); | 878 | "in FIP adv\n", desc->fip_dtype); |
855 | /* standard says ignore unknown descriptors >= 128 */ | 879 | /* standard says ignore unknown descriptors >= 128 */ |
856 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) | 880 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) |
@@ -867,11 +891,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
867 | 891 | ||
868 | if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP && | 892 | if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP && |
869 | fip->flogi_oxid == ntohs(fh->fh_ox_id) && | 893 | fip->flogi_oxid == ntohs(fh->fh_ox_id) && |
870 | els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) { | 894 | els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) |
871 | fip->flogi_oxid = FC_XID_UNKNOWN; | 895 | fip->flogi_oxid = FC_XID_UNKNOWN; |
872 | fip->update_mac(fip, fip->data_src_addr, granted_mac); | ||
873 | memcpy(fip->data_src_addr, granted_mac, ETH_ALEN); | ||
874 | } | ||
875 | 896 | ||
876 | /* | 897 | /* |
877 | * Convert skb into an fc_frame containing only the ELS. | 898 | * Convert skb into an fc_frame containing only the ELS. |
@@ -882,32 +903,32 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
882 | fc_frame_init(fp); | 903 | fc_frame_init(fp); |
883 | fr_sof(fp) = FC_SOF_I3; | 904 | fr_sof(fp) = FC_SOF_I3; |
884 | fr_eof(fp) = FC_EOF_T; | 905 | fr_eof(fp) = FC_EOF_T; |
885 | fr_dev(fp) = lp; | 906 | fr_dev(fp) = lport; |
886 | 907 | ||
887 | stats = fc_lport_get_stats(lp); | 908 | stats = fc_lport_get_stats(lport); |
888 | stats->RxFrames++; | 909 | stats->RxFrames++; |
889 | stats->RxWords += skb->len / FIP_BPW; | 910 | stats->RxWords += skb->len / FIP_BPW; |
890 | 911 | ||
891 | fc_exch_recv(lp, fp); | 912 | fc_exch_recv(lport, fp); |
892 | return; | 913 | return; |
893 | 914 | ||
894 | len_err: | 915 | len_err: |
895 | LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n", | 916 | LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n", |
896 | desc->fip_dtype, dlen); | 917 | desc->fip_dtype, dlen); |
897 | drop: | 918 | drop: |
898 | kfree_skb(skb); | 919 | kfree_skb(skb); |
899 | } | 920 | } |
900 | 921 | ||
901 | /** | 922 | /** |
902 | * fcoe_ctlr_recv_els() - Handle an incoming link reset frame. | 923 | * fcoe_ctlr_recv_els() - Handle an incoming link reset frame |
903 | * @fip: FCoE controller. | 924 | * @fip: The FCoE controller that received the frame |
904 | * @fh: Received FIP header. | 925 | * @fh: The received FIP header |
905 | * | 926 | * |
906 | * There may be multiple VN_Port descriptors. | 927 | * There may be multiple VN_Port descriptors. |
907 | * The overall length has already been checked. | 928 | * The overall length has already been checked. |
908 | */ | 929 | */ |
909 | static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | 930 | static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, |
910 | struct fip_header *fh) | 931 | struct fip_header *fh) |
911 | { | 932 | { |
912 | struct fip_desc *desc; | 933 | struct fip_desc *desc; |
913 | struct fip_mac_desc *mp; | 934 | struct fip_mac_desc *mp; |
@@ -916,13 +937,13 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
916 | size_t rlen; | 937 | size_t rlen; |
917 | size_t dlen; | 938 | size_t dlen; |
918 | struct fcoe_fcf *fcf = fip->sel_fcf; | 939 | struct fcoe_fcf *fcf = fip->sel_fcf; |
919 | struct fc_lport *lp = fip->lp; | 940 | struct fc_lport *lport = fip->lp; |
920 | u32 desc_mask; | 941 | u32 desc_mask; |
921 | 942 | ||
922 | LIBFCOE_FIP_DBG("Clear Virtual Link received\n"); | 943 | LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); |
923 | if (!fcf) | 944 | if (!fcf) |
924 | return; | 945 | return; |
925 | if (!fcf || !fc_host_port_id(lp->host)) | 946 | if (!fcf || !fc_host_port_id(lport->host)) |
926 | return; | 947 | return; |
927 | 948 | ||
928 | /* | 949 | /* |
@@ -958,9 +979,10 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
958 | if (dlen < sizeof(*vp)) | 979 | if (dlen < sizeof(*vp)) |
959 | return; | 980 | return; |
960 | if (compare_ether_addr(vp->fd_mac, | 981 | if (compare_ether_addr(vp->fd_mac, |
961 | fip->data_src_addr) == 0 && | 982 | fip->get_src_addr(lport)) == 0 && |
962 | get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn && | 983 | get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn && |
963 | ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host)) | 984 | ntoh24(vp->fd_fc_id) == |
985 | fc_host_port_id(lport->host)) | ||
964 | desc_mask &= ~BIT(FIP_DT_VN_ID); | 986 | desc_mask &= ~BIT(FIP_DT_VN_ID); |
965 | break; | 987 | break; |
966 | default: | 988 | default: |
@@ -977,33 +999,39 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
977 | * reset only if all required descriptors were present and valid. | 999 | * reset only if all required descriptors were present and valid. |
978 | */ | 1000 | */ |
979 | if (desc_mask) { | 1001 | if (desc_mask) { |
980 | LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask); | 1002 | LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n", |
1003 | desc_mask); | ||
981 | } else { | 1004 | } else { |
982 | LIBFCOE_FIP_DBG("performing Clear Virtual Link\n"); | 1005 | LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); |
983 | fcoe_ctlr_reset(fip, FIP_ST_ENABLED); | 1006 | |
1007 | spin_lock_bh(&fip->lock); | ||
1008 | fc_lport_get_stats(lport)->VLinkFailureCount++; | ||
1009 | fcoe_ctlr_reset(fip); | ||
1010 | spin_unlock_bh(&fip->lock); | ||
1011 | |||
1012 | fc_lport_reset(fip->lp); | ||
1013 | fcoe_ctlr_solicit(fip, NULL); | ||
984 | } | 1014 | } |
985 | } | 1015 | } |
986 | 1016 | ||
987 | /** | 1017 | /** |
988 | * fcoe_ctlr_recv() - Receive a FIP frame. | 1018 | * fcoe_ctlr_recv() - Receive a FIP packet |
989 | * @fip: FCoE controller. | 1019 | * @fip: The FCoE controller that received the packet |
990 | * @skb: Received FIP packet. | 1020 | * @skb: The received FIP packet |
991 | * | 1021 | * |
992 | * This is called from NET_RX_SOFTIRQ. | 1022 | * This may be called from either NET_RX_SOFTIRQ or IRQ. |
993 | */ | 1023 | */ |
994 | void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) | 1024 | void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) |
995 | { | 1025 | { |
996 | spin_lock_bh(&fip->fip_recv_list.lock); | 1026 | skb_queue_tail(&fip->fip_recv_list, skb); |
997 | __skb_queue_tail(&fip->fip_recv_list, skb); | ||
998 | spin_unlock_bh(&fip->fip_recv_list.lock); | ||
999 | schedule_work(&fip->recv_work); | 1027 | schedule_work(&fip->recv_work); |
1000 | } | 1028 | } |
1001 | EXPORT_SYMBOL(fcoe_ctlr_recv); | 1029 | EXPORT_SYMBOL(fcoe_ctlr_recv); |
1002 | 1030 | ||
1003 | /** | 1031 | /** |
1004 | * fcoe_ctlr_recv_handler() - Receive a FIP frame. | 1032 | * fcoe_ctlr_recv_handler() - Receive a FIP frame |
1005 | * @fip: FCoE controller. | 1033 | * @fip: The FCoE controller that received the frame |
1006 | * @skb: Received FIP packet. | 1034 | * @skb: The received FIP frame |
1007 | * | 1035 | * |
1008 | * Returns non-zero if the frame is dropped. | 1036 | * Returns non-zero if the frame is dropped. |
1009 | */ | 1037 | */ |
@@ -1038,7 +1066,7 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
1038 | fip->map_dest = 0; | 1066 | fip->map_dest = 0; |
1039 | fip->state = FIP_ST_ENABLED; | 1067 | fip->state = FIP_ST_ENABLED; |
1040 | state = FIP_ST_ENABLED; | 1068 | state = FIP_ST_ENABLED; |
1041 | LIBFCOE_FIP_DBG("Using FIP mode\n"); | 1069 | LIBFCOE_FIP_DBG(fip, "Using FIP mode\n"); |
1042 | } | 1070 | } |
1043 | spin_unlock_bh(&fip->lock); | 1071 | spin_unlock_bh(&fip->lock); |
1044 | if (state != FIP_ST_ENABLED) | 1072 | if (state != FIP_ST_ENABLED) |
@@ -1060,8 +1088,8 @@ drop: | |||
1060 | } | 1088 | } |
1061 | 1089 | ||
1062 | /** | 1090 | /** |
1063 | * fcoe_ctlr_select() - Select the best FCF, if possible. | 1091 | * fcoe_ctlr_select() - Select the best FCF (if possible) |
1064 | * @fip: FCoE controller. | 1092 | * @fip: The FCoE controller |
1065 | * | 1093 | * |
1066 | * If there are conflicting advertisements, no FCF can be chosen. | 1094 | * If there are conflicting advertisements, no FCF can be chosen. |
1067 | * | 1095 | * |
@@ -1073,11 +1101,11 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
1073 | struct fcoe_fcf *best = NULL; | 1101 | struct fcoe_fcf *best = NULL; |
1074 | 1102 | ||
1075 | list_for_each_entry(fcf, &fip->fcfs, list) { | 1103 | list_for_each_entry(fcf, &fip->fcfs, list) { |
1076 | LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x " | 1104 | LIBFCOE_FIP_DBG(fip, "consider FCF for fab %llx VFID %d map %x " |
1077 | "val %d\n", fcf->fabric_name, fcf->vfid, | 1105 | "val %d\n", fcf->fabric_name, fcf->vfid, |
1078 | fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); | 1106 | fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); |
1079 | if (!fcoe_ctlr_fcf_usable(fcf)) { | 1107 | if (!fcoe_ctlr_fcf_usable(fcf)) { |
1080 | LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid " | 1108 | LIBFCOE_FIP_DBG(fip, "FCF for fab %llx map %x %svalid " |
1081 | "%savailable\n", fcf->fabric_name, | 1109 | "%savailable\n", fcf->fabric_name, |
1082 | fcf->fc_map, (fcf->flags & FIP_FL_SOL) | 1110 | fcf->fc_map, (fcf->flags & FIP_FL_SOL) |
1083 | ? "" : "in", (fcf->flags & FIP_FL_AVAIL) | 1111 | ? "" : "in", (fcf->flags & FIP_FL_AVAIL) |
@@ -1091,7 +1119,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
1091 | if (fcf->fabric_name != best->fabric_name || | 1119 | if (fcf->fabric_name != best->fabric_name || |
1092 | fcf->vfid != best->vfid || | 1120 | fcf->vfid != best->vfid || |
1093 | fcf->fc_map != best->fc_map) { | 1121 | fcf->fc_map != best->fc_map) { |
1094 | LIBFCOE_FIP_DBG("Conflicting fabric, VFID, " | 1122 | LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, " |
1095 | "or FC-MAP\n"); | 1123 | "or FC-MAP\n"); |
1096 | return; | 1124 | return; |
1097 | } | 1125 | } |
@@ -1102,8 +1130,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
1102 | } | 1130 | } |
1103 | 1131 | ||
1104 | /** | 1132 | /** |
1105 | * fcoe_ctlr_timeout() - FIP timer function. | 1133 | * fcoe_ctlr_timeout() - FIP timeout handler |
1106 | * @arg: &fcoe_ctlr pointer. | 1134 | * @arg: The FCoE controller that timed out |
1107 | * | 1135 | * |
1108 | * Ages FCFs. Triggers FCF selection if possible. Sends keep-alives. | 1136 | * Ages FCFs. Triggers FCF selection if possible. Sends keep-alives. |
1109 | */ | 1137 | */ |
@@ -1113,8 +1141,6 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1113 | struct fcoe_fcf *sel; | 1141 | struct fcoe_fcf *sel; |
1114 | struct fcoe_fcf *fcf; | 1142 | struct fcoe_fcf *fcf; |
1115 | unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1143 | unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1116 | u8 send_ctlr_ka; | ||
1117 | u8 send_port_ka; | ||
1118 | 1144 | ||
1119 | spin_lock_bh(&fip->lock); | 1145 | spin_lock_bh(&fip->lock); |
1120 | if (fip->state == FIP_ST_DISABLED) { | 1146 | if (fip->state == FIP_ST_DISABLED) { |
@@ -1140,53 +1166,47 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1140 | fip->lp->host->host_no, sel->fcf_mac); | 1166 | fip->lp->host->host_no, sel->fcf_mac); |
1141 | memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); | 1167 | memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); |
1142 | fip->port_ka_time = jiffies + | 1168 | fip->port_ka_time = jiffies + |
1143 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1169 | msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1144 | fip->ctlr_ka_time = jiffies + sel->fka_period; | 1170 | fip->ctlr_ka_time = jiffies + sel->fka_period; |
1145 | fip->link = 1; | ||
1146 | } else { | 1171 | } else { |
1147 | printk(KERN_NOTICE "libfcoe: host%d: " | 1172 | printk(KERN_NOTICE "libfcoe: host%d: " |
1148 | "FIP Fibre-Channel Forwarder timed out. " | 1173 | "FIP Fibre-Channel Forwarder timed out. " |
1149 | "Starting FCF discovery.\n", | 1174 | "Starting FCF discovery.\n", |
1150 | fip->lp->host->host_no); | 1175 | fip->lp->host->host_no); |
1151 | fip->link = 0; | 1176 | fip->reset_req = 1; |
1177 | schedule_work(&fip->link_work); | ||
1152 | } | 1178 | } |
1153 | schedule_work(&fip->link_work); | ||
1154 | } | 1179 | } |
1155 | 1180 | ||
1156 | send_ctlr_ka = 0; | 1181 | if (sel && !sel->fd_flags) { |
1157 | send_port_ka = 0; | ||
1158 | if (sel) { | ||
1159 | if (time_after_eq(jiffies, fip->ctlr_ka_time)) { | 1182 | if (time_after_eq(jiffies, fip->ctlr_ka_time)) { |
1160 | fip->ctlr_ka_time = jiffies + sel->fka_period; | 1183 | fip->ctlr_ka_time = jiffies + sel->fka_period; |
1161 | send_ctlr_ka = 1; | 1184 | fip->send_ctlr_ka = 1; |
1162 | } | 1185 | } |
1163 | if (time_after(next_timer, fip->ctlr_ka_time)) | 1186 | if (time_after(next_timer, fip->ctlr_ka_time)) |
1164 | next_timer = fip->ctlr_ka_time; | 1187 | next_timer = fip->ctlr_ka_time; |
1165 | 1188 | ||
1166 | if (time_after_eq(jiffies, fip->port_ka_time)) { | 1189 | if (time_after_eq(jiffies, fip->port_ka_time)) { |
1167 | fip->port_ka_time += jiffies + | 1190 | fip->port_ka_time += jiffies + |
1168 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1191 | msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1169 | send_port_ka = 1; | 1192 | fip->send_port_ka = 1; |
1170 | } | 1193 | } |
1171 | if (time_after(next_timer, fip->port_ka_time)) | 1194 | if (time_after(next_timer, fip->port_ka_time)) |
1172 | next_timer = fip->port_ka_time; | 1195 | next_timer = fip->port_ka_time; |
1173 | mod_timer(&fip->timer, next_timer); | 1196 | mod_timer(&fip->timer, next_timer); |
1174 | } else if (fip->sel_time) { | 1197 | } else if (fip->sel_time) { |
1175 | next_timer = fip->sel_time + | 1198 | next_timer = fip->sel_time + |
1176 | msecs_to_jiffies(FCOE_CTLR_START_DELAY); | 1199 | msecs_to_jiffies(FCOE_CTLR_START_DELAY); |
1177 | mod_timer(&fip->timer, next_timer); | 1200 | mod_timer(&fip->timer, next_timer); |
1178 | } | 1201 | } |
1202 | if (fip->send_ctlr_ka || fip->send_port_ka) | ||
1203 | schedule_work(&fip->link_work); | ||
1179 | spin_unlock_bh(&fip->lock); | 1204 | spin_unlock_bh(&fip->lock); |
1180 | |||
1181 | if (send_ctlr_ka) | ||
1182 | fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr); | ||
1183 | if (send_port_ka) | ||
1184 | fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr); | ||
1185 | } | 1205 | } |
1186 | 1206 | ||
1187 | /** | 1207 | /** |
1188 | * fcoe_ctlr_link_work() - worker thread function for link changes. | 1208 | * fcoe_ctlr_link_work() - Worker thread function for link changes |
1189 | * @work: pointer to link_work member inside &fcoe_ctlr. | 1209 | * @work: Handle to a FCoE controller |
1190 | * | 1210 | * |
1191 | * See if the link status has changed and if so, report it. | 1211 | * See if the link status has changed and if so, report it. |
1192 | * | 1212 | * |
@@ -1196,27 +1216,49 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1196 | static void fcoe_ctlr_link_work(struct work_struct *work) | 1216 | static void fcoe_ctlr_link_work(struct work_struct *work) |
1197 | { | 1217 | { |
1198 | struct fcoe_ctlr *fip; | 1218 | struct fcoe_ctlr *fip; |
1219 | struct fc_lport *vport; | ||
1220 | u8 *mac; | ||
1199 | int link; | 1221 | int link; |
1200 | int last_link; | 1222 | int last_link; |
1223 | int reset; | ||
1201 | 1224 | ||
1202 | fip = container_of(work, struct fcoe_ctlr, link_work); | 1225 | fip = container_of(work, struct fcoe_ctlr, link_work); |
1203 | spin_lock_bh(&fip->lock); | 1226 | spin_lock_bh(&fip->lock); |
1204 | last_link = fip->last_link; | 1227 | last_link = fip->last_link; |
1205 | link = fip->link; | 1228 | link = fip->link; |
1206 | fip->last_link = link; | 1229 | fip->last_link = link; |
1230 | reset = fip->reset_req; | ||
1231 | fip->reset_req = 0; | ||
1207 | spin_unlock_bh(&fip->lock); | 1232 | spin_unlock_bh(&fip->lock); |
1208 | 1233 | ||
1209 | if (last_link != link) { | 1234 | if (last_link != link) { |
1210 | if (link) | 1235 | if (link) |
1211 | fc_linkup(fip->lp); | 1236 | fc_linkup(fip->lp); |
1212 | else | 1237 | else |
1213 | fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); | 1238 | fc_linkdown(fip->lp); |
1239 | } else if (reset && link) | ||
1240 | fc_lport_reset(fip->lp); | ||
1241 | |||
1242 | if (fip->send_ctlr_ka) { | ||
1243 | fip->send_ctlr_ka = 0; | ||
1244 | fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr); | ||
1245 | } | ||
1246 | if (fip->send_port_ka) { | ||
1247 | fip->send_port_ka = 0; | ||
1248 | mutex_lock(&fip->lp->lp_mutex); | ||
1249 | mac = fip->get_src_addr(fip->lp); | ||
1250 | fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac); | ||
1251 | list_for_each_entry(vport, &fip->lp->vports, list) { | ||
1252 | mac = fip->get_src_addr(vport); | ||
1253 | fcoe_ctlr_send_keep_alive(fip, vport, 1, mac); | ||
1254 | } | ||
1255 | mutex_unlock(&fip->lp->lp_mutex); | ||
1214 | } | 1256 | } |
1215 | } | 1257 | } |
1216 | 1258 | ||
1217 | /** | 1259 | /** |
1218 | * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames. | 1260 | * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames |
1219 | * @recv_work: pointer to recv_work member inside &fcoe_ctlr. | 1261 | * @recv_work: Handle to a FCoE controller |
1220 | */ | 1262 | */ |
1221 | static void fcoe_ctlr_recv_work(struct work_struct *recv_work) | 1263 | static void fcoe_ctlr_recv_work(struct work_struct *recv_work) |
1222 | { | 1264 | { |
@@ -1224,20 +1266,14 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) | |||
1224 | struct sk_buff *skb; | 1266 | struct sk_buff *skb; |
1225 | 1267 | ||
1226 | fip = container_of(recv_work, struct fcoe_ctlr, recv_work); | 1268 | fip = container_of(recv_work, struct fcoe_ctlr, recv_work); |
1227 | spin_lock_bh(&fip->fip_recv_list.lock); | 1269 | while ((skb = skb_dequeue(&fip->fip_recv_list))) |
1228 | while ((skb = __skb_dequeue(&fip->fip_recv_list))) { | ||
1229 | spin_unlock_bh(&fip->fip_recv_list.lock); | ||
1230 | fcoe_ctlr_recv_handler(fip, skb); | 1270 | fcoe_ctlr_recv_handler(fip, skb); |
1231 | spin_lock_bh(&fip->fip_recv_list.lock); | ||
1232 | } | ||
1233 | spin_unlock_bh(&fip->fip_recv_list.lock); | ||
1234 | } | 1271 | } |
1235 | 1272 | ||
1236 | /** | 1273 | /** |
1237 | * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request. | 1274 | * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response |
1238 | * @fip: FCoE controller. | 1275 | * @fip: The FCoE controller |
1239 | * @fp: FC frame. | 1276 | * @fp: The FC frame to snoop |
1240 | * @sa: Ethernet source MAC address from received FCoE frame. | ||
1241 | * | 1277 | * |
1242 | * Snoop potential response to FLOGI or even incoming FLOGI. | 1278 | * Snoop potential response to FLOGI or even incoming FLOGI. |
1243 | * | 1279 | * |
@@ -1245,15 +1281,18 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) | |||
1245 | * by fip->flogi_oxid != FC_XID_UNKNOWN. | 1281 | * by fip->flogi_oxid != FC_XID_UNKNOWN. |
1246 | * | 1282 | * |
1247 | * The caller is responsible for freeing the frame. | 1283 | * The caller is responsible for freeing the frame. |
1284 | * Fill in the granted_mac address. | ||
1248 | * | 1285 | * |
1249 | * Return non-zero if the frame should not be delivered to libfc. | 1286 | * Return non-zero if the frame should not be delivered to libfc. |
1250 | */ | 1287 | */ |
1251 | int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) | 1288 | int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, |
1289 | struct fc_frame *fp) | ||
1252 | { | 1290 | { |
1253 | struct fc_frame_header *fh; | 1291 | struct fc_frame_header *fh; |
1254 | u8 op; | 1292 | u8 op; |
1255 | u8 mac[ETH_ALEN]; | 1293 | u8 *sa; |
1256 | 1294 | ||
1295 | sa = eth_hdr(&fp->skb)->h_source; | ||
1257 | fh = fc_frame_header_get(fp); | 1296 | fh = fc_frame_header_get(fp); |
1258 | if (fh->fh_type != FC_TYPE_ELS) | 1297 | if (fh->fh_type != FC_TYPE_ELS) |
1259 | return 0; | 1298 | return 0; |
@@ -1268,7 +1307,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) | |||
1268 | return -EINVAL; | 1307 | return -EINVAL; |
1269 | } | 1308 | } |
1270 | fip->state = FIP_ST_NON_FIP; | 1309 | fip->state = FIP_ST_NON_FIP; |
1271 | LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n"); | 1310 | LIBFCOE_FIP_DBG(fip, |
1311 | "received FLOGI LS_ACC using non-FIP mode\n"); | ||
1272 | 1312 | ||
1273 | /* | 1313 | /* |
1274 | * FLOGI accepted. | 1314 | * FLOGI accepted. |
@@ -1283,11 +1323,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) | |||
1283 | fip->map_dest = 0; | 1323 | fip->map_dest = 0; |
1284 | } | 1324 | } |
1285 | fip->flogi_oxid = FC_XID_UNKNOWN; | 1325 | fip->flogi_oxid = FC_XID_UNKNOWN; |
1286 | memcpy(mac, fip->data_src_addr, ETH_ALEN); | ||
1287 | fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id); | ||
1288 | spin_unlock_bh(&fip->lock); | 1326 | spin_unlock_bh(&fip->lock); |
1289 | 1327 | fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id); | |
1290 | fip->update_mac(fip, mac, fip->data_src_addr); | ||
1291 | } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { | 1328 | } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { |
1292 | /* | 1329 | /* |
1293 | * Save source MAC for point-to-point responses. | 1330 | * Save source MAC for point-to-point responses. |
@@ -1297,7 +1334,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) | |||
1297 | memcpy(fip->dest_addr, sa, ETH_ALEN); | 1334 | memcpy(fip->dest_addr, sa, ETH_ALEN); |
1298 | fip->map_dest = 0; | 1335 | fip->map_dest = 0; |
1299 | if (fip->state == FIP_ST_NON_FIP) | 1336 | if (fip->state == FIP_ST_NON_FIP) |
1300 | LIBFCOE_FIP_DBG("received FLOGI REQ, " | 1337 | LIBFCOE_FIP_DBG(fip, "received FLOGI REQ, " |
1301 | "using non-FIP mode\n"); | 1338 | "using non-FIP mode\n"); |
1302 | fip->state = FIP_ST_NON_FIP; | 1339 | fip->state = FIP_ST_NON_FIP; |
1303 | } | 1340 | } |
@@ -1308,10 +1345,10 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) | |||
1308 | EXPORT_SYMBOL(fcoe_ctlr_recv_flogi); | 1345 | EXPORT_SYMBOL(fcoe_ctlr_recv_flogi); |
1309 | 1346 | ||
1310 | /** | 1347 | /** |
1311 | * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN. | 1348 | * fcoe_wwn_from_mac() - Converts a 48-bit IEEE MAC address to a 64-bit FC WWN |
1312 | * @mac: mac address | 1349 | * @mac: The MAC address to convert |
1313 | * @scheme: check port | 1350 | * @scheme: The scheme to use when converting |
1314 | * @port: port indicator for converting | 1351 | * @port: The port indicator for converting |
1315 | * | 1352 | * |
1316 | * Returns: u64 fc world wide name | 1353 | * Returns: u64 fc world wide name |
1317 | */ | 1354 | */ |
@@ -1349,24 +1386,26 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], | |||
1349 | EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); | 1386 | EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); |
1350 | 1387 | ||
1351 | /** | 1388 | /** |
1352 | * fcoe_libfc_config() - sets up libfc related properties for lport | 1389 | * fcoe_libfc_config() - Sets up libfc related properties for local port |
1353 | * @lp: ptr to the fc_lport | 1390 | * @lp: The local port to configure libfc for |
1354 | * @tt: libfc function template | 1391 | * @tt: The libfc function template |
1355 | * | 1392 | * |
1356 | * Returns : 0 for success | 1393 | * Returns : 0 for success |
1357 | */ | 1394 | */ |
1358 | int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt) | 1395 | int fcoe_libfc_config(struct fc_lport *lport, |
1396 | struct libfc_function_template *tt) | ||
1359 | { | 1397 | { |
1360 | /* Set the function pointers set by the LLDD */ | 1398 | /* Set the function pointers set by the LLDD */ |
1361 | memcpy(&lp->tt, tt, sizeof(*tt)); | 1399 | memcpy(&lport->tt, tt, sizeof(*tt)); |
1362 | if (fc_fcp_init(lp)) | 1400 | if (fc_fcp_init(lport)) |
1363 | return -ENOMEM; | 1401 | return -ENOMEM; |
1364 | fc_exch_init(lp); | 1402 | fc_exch_init(lport); |
1365 | fc_elsct_init(lp); | 1403 | fc_elsct_init(lport); |
1366 | fc_lport_init(lp); | 1404 | fc_lport_init(lport); |
1367 | fc_rport_init(lp); | 1405 | fc_rport_init(lport); |
1368 | fc_disc_init(lp); | 1406 | fc_disc_init(lport); |
1369 | 1407 | ||
1370 | return 0; | 1408 | return 0; |
1371 | } | 1409 | } |
1372 | EXPORT_SYMBOL_GPL(fcoe_libfc_config); | 1410 | EXPORT_SYMBOL_GPL(fcoe_libfc_config); |
1411 | |||