diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe_sw.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe_sw.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c index da210eba1941..2bbbe3c0cc7b 100644 --- a/drivers/scsi/fcoe/fcoe_sw.c +++ b/drivers/scsi/fcoe/fcoe_sw.c | |||
@@ -133,6 +133,13 @@ static int fcoe_sw_lport_config(struct fc_lport *lp) | |||
133 | /* lport fc_lport related configuration */ | 133 | /* lport fc_lport related configuration */ |
134 | fc_lport_config(lp); | 134 | fc_lport_config(lp); |
135 | 135 | ||
136 | /* offload related configuration */ | ||
137 | lp->crc_offload = 0; | ||
138 | lp->seq_offload = 0; | ||
139 | lp->lro_enabled = 0; | ||
140 | lp->lro_xid = 0; | ||
141 | lp->lso_max = 0; | ||
142 | |||
136 | return 0; | 143 | return 0; |
137 | } | 144 | } |
138 | 145 | ||
@@ -186,7 +193,27 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
186 | if (fc->real_dev->features & NETIF_F_SG) | 193 | if (fc->real_dev->features & NETIF_F_SG) |
187 | lp->sg_supp = 1; | 194 | lp->sg_supp = 1; |
188 | 195 | ||
189 | 196 | #ifdef NETIF_F_FCOE_CRC | |
197 | if (netdev->features & NETIF_F_FCOE_CRC) { | ||
198 | lp->crc_offload = 1; | ||
199 | printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n", | ||
200 | netdev->name); | ||
201 | } | ||
202 | #endif | ||
203 | #ifdef NETIF_F_FSO | ||
204 | if (netdev->features & NETIF_F_FSO) { | ||
205 | lp->seq_offload = 1; | ||
206 | lp->lso_max = netdev->gso_max_size; | ||
207 | printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n", | ||
208 | netdev->name, lp->lso_max); | ||
209 | } | ||
210 | #endif | ||
211 | if (netdev->fcoe_ddp_xid) { | ||
212 | lp->lro_enabled = 1; | ||
213 | lp->lro_xid = netdev->fcoe_ddp_xid; | ||
214 | printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n", | ||
215 | netdev->name, lp->lro_xid); | ||
216 | } | ||
190 | skb_queue_head_init(&fc->fcoe_pending_queue); | 217 | skb_queue_head_init(&fc->fcoe_pending_queue); |
191 | fc->fcoe_pending_queue_active = 0; | 218 | fc->fcoe_pending_queue_active = 0; |
192 | 219 | ||
@@ -346,8 +373,46 @@ static int fcoe_sw_destroy(struct net_device *netdev) | |||
346 | return 0; | 373 | return 0; |
347 | } | 374 | } |
348 | 375 | ||
376 | /* | ||
377 | * fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device | ||
378 | * @lp: the corresponding fc_lport | ||
379 | * @xid: the exchange id for this ddp transfer | ||
380 | * @sgl: the scatterlist describing this transfer | ||
381 | * @sgc: number of sg items | ||
382 | * | ||
383 | * Returns : 0 no ddp | ||
384 | */ | ||
385 | static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid, | ||
386 | struct scatterlist *sgl, unsigned int sgc) | ||
387 | { | ||
388 | struct net_device *n = fcoe_netdev(lp); | ||
389 | |||
390 | if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup) | ||
391 | return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * fcoe_sw_ddp_done - calls LLD's ddp_done through net_device | ||
398 | * @lp: the corresponding fc_lport | ||
399 | * @xid: the exchange id for this ddp transfer | ||
400 | * | ||
401 | * Returns : the length of data that have been completed by ddp | ||
402 | */ | ||
403 | static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid) | ||
404 | { | ||
405 | struct net_device *n = fcoe_netdev(lp); | ||
406 | |||
407 | if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done) | ||
408 | return n->netdev_ops->ndo_fcoe_ddp_done(n, xid); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
349 | static struct libfc_function_template fcoe_sw_libfc_fcn_templ = { | 412 | static struct libfc_function_template fcoe_sw_libfc_fcn_templ = { |
350 | .frame_send = fcoe_xmit, | 413 | .frame_send = fcoe_xmit, |
414 | .ddp_setup = fcoe_sw_ddp_setup, | ||
415 | .ddp_done = fcoe_sw_ddp_done, | ||
351 | }; | 416 | }; |
352 | 417 | ||
353 | /** | 418 | /** |