aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2011-02-01 02:22:16 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-07 21:04:35 -0500
commit68a683cf6a5ff09faa366fc1fcf967add0211fe8 (patch)
treece031702ba79d9039bb4f0843a8f056885ba94e4
parent4ea09c9caaebc98d06a39c435d4359912cfbb5e2 (diff)
ixgbe: add support to FCoE DDP in target mode
Add support to the ndo_fcoe_ddp_target() to allow the Intel 82599 device to also provide DDP offload capability when the upper FCoE protocol stack is operating as a target. Signed-off-by: Yi Zou <yi.zou@intel.com> Signed-off-by: Kiran Patil <kiran.patil@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c86
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h4
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1
4 files changed, 81 insertions, 12 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index b60b81bc2b15..1e546fc127d0 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -552,6 +552,8 @@ extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
552 struct sk_buff *skb); 552 struct sk_buff *skb);
553extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, 553extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
554 struct scatterlist *sgl, unsigned int sgc); 554 struct scatterlist *sgl, unsigned int sgc);
555extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
556 struct scatterlist *sgl, unsigned int sgc);
555extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); 557extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
556extern int ixgbe_fcoe_enable(struct net_device *netdev); 558extern int ixgbe_fcoe_enable(struct net_device *netdev);
557extern int ixgbe_fcoe_disable(struct net_device *netdev); 559extern int ixgbe_fcoe_disable(struct net_device *netdev);
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 27203c87ea14..00af15a9cdc6 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -135,22 +135,19 @@ out_ddp_put:
135 return len; 135 return len;
136} 136}
137 137
138
138/** 139/**
139 * ixgbe_fcoe_ddp_get - called to set up ddp context 140 * ixgbe_fcoe_ddp_setup - called to set up ddp context
140 * @netdev: the corresponding net_device 141 * @netdev: the corresponding net_device
141 * @xid: the exchange id requesting ddp 142 * @xid: the exchange id requesting ddp
142 * @sgl: the scatter-gather list for this request 143 * @sgl: the scatter-gather list for this request
143 * @sgc: the number of scatter-gather items 144 * @sgc: the number of scatter-gather items
144 * 145 *
145 * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
146 * and is expected to be called from ULD, e.g., FCP layer of libfc
147 * to set up ddp for the corresponding xid of the given sglist for
148 * the corresponding I/O.
149 *
150 * Returns : 1 for success and 0 for no ddp 146 * Returns : 1 for success and 0 for no ddp
151 */ 147 */
152int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, 148static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
153 struct scatterlist *sgl, unsigned int sgc) 149 struct scatterlist *sgl, unsigned int sgc,
150 int target_mode)
154{ 151{
155 struct ixgbe_adapter *adapter; 152 struct ixgbe_adapter *adapter;
156 struct ixgbe_hw *hw; 153 struct ixgbe_hw *hw;
@@ -164,7 +161,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
164 unsigned int lastsize; 161 unsigned int lastsize;
165 unsigned int thisoff = 0; 162 unsigned int thisoff = 0;
166 unsigned int thislen = 0; 163 unsigned int thislen = 0;
167 u32 fcbuff, fcdmarw, fcfltrw; 164 u32 fcbuff, fcdmarw, fcfltrw, fcrxctl;
168 dma_addr_t addr = 0; 165 dma_addr_t addr = 0;
169 166
170 if (!netdev || !sgl) 167 if (!netdev || !sgl)
@@ -275,6 +272,9 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
275 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); 272 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
276 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); 273 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
277 fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); 274 fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
275 /* Set WRCONTX bit to allow DDP for target */
276 if (target_mode)
277 fcbuff |= (IXGBE_FCBUFF_WRCONTX);
278 fcbuff |= (IXGBE_FCBUFF_VALID); 278 fcbuff |= (IXGBE_FCBUFF_VALID);
279 279
280 fcdmarw = xid; 280 fcdmarw = xid;
@@ -287,6 +287,16 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
287 /* program DMA context */ 287 /* program DMA context */
288 hw = &adapter->hw; 288 hw = &adapter->hw;
289 spin_lock_bh(&fcoe->lock); 289 spin_lock_bh(&fcoe->lock);
290
291 /* turn on last frame indication for target mode as FCP_RSPtarget is
292 * supposed to send FCP_RSP when it is done. */
293 if (target_mode && !test_bit(__IXGBE_FCOE_TARGET, &fcoe->mode)) {
294 set_bit(__IXGBE_FCOE_TARGET, &fcoe->mode);
295 fcrxctl = IXGBE_READ_REG(hw, IXGBE_FCRXCTRL);
296 fcrxctl |= IXGBE_FCRXCTRL_LASTSEQH;
297 IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, fcrxctl);
298 }
299
290 IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32)); 300 IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32));
291 IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32); 301 IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);
292 IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff); 302 IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);
@@ -295,6 +305,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
295 IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0); 305 IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);
296 IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID); 306 IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);
297 IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw); 307 IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);
308
298 spin_unlock_bh(&fcoe->lock); 309 spin_unlock_bh(&fcoe->lock);
299 310
300 return 1; 311 return 1;
@@ -309,6 +320,47 @@ out_noddp_unmap:
309} 320}
310 321
311/** 322/**
323 * ixgbe_fcoe_ddp_get - called to set up ddp context in initiator mode
324 * @netdev: the corresponding net_device
325 * @xid: the exchange id requesting ddp
326 * @sgl: the scatter-gather list for this request
327 * @sgc: the number of scatter-gather items
328 *
329 * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
330 * and is expected to be called from ULD, e.g., FCP layer of libfc
331 * to set up ddp for the corresponding xid of the given sglist for
332 * the corresponding I/O.
333 *
334 * Returns : 1 for success and 0 for no ddp
335 */
336int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
337 struct scatterlist *sgl, unsigned int sgc)
338{
339 return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);
340}
341
342/**
343 * ixgbe_fcoe_ddp_target - called to set up ddp context in target mode
344 * @netdev: the corresponding net_device
345 * @xid: the exchange id requesting ddp
346 * @sgl: the scatter-gather list for this request
347 * @sgc: the number of scatter-gather items
348 *
349 * This is the implementation of net_device_ops.ndo_fcoe_ddp_target
350 * and is expected to be called from ULD, e.g., FCP layer of libfc
351 * to set up ddp for the corresponding xid of the given sglist for
352 * the corresponding I/O. The DDP in target mode is a write I/O request
353 * from the initiator.
354 *
355 * Returns : 1 for success and 0 for no ddp
356 */
357int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
358 struct scatterlist *sgl, unsigned int sgc)
359{
360 return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);
361}
362
363/**
312 * ixgbe_fcoe_ddp - check ddp status and mark it done 364 * ixgbe_fcoe_ddp - check ddp status and mark it done
313 * @adapter: ixgbe adapter 365 * @adapter: ixgbe adapter
314 * @rx_desc: advanced rx descriptor 366 * @rx_desc: advanced rx descriptor
@@ -331,6 +383,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
331 struct ixgbe_fcoe *fcoe; 383 struct ixgbe_fcoe *fcoe;
332 struct ixgbe_fcoe_ddp *ddp; 384 struct ixgbe_fcoe_ddp *ddp;
333 struct fc_frame_header *fh; 385 struct fc_frame_header *fh;
386 struct fcoe_crc_eof *crc;
334 387
335 if (!ixgbe_rx_is_fcoe(rx_desc)) 388 if (!ixgbe_rx_is_fcoe(rx_desc))
336 goto ddp_out; 389 goto ddp_out;
@@ -384,7 +437,18 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
384 else if (ddp->len) 437 else if (ddp->len)
385 rc = ddp->len; 438 rc = ddp->len;
386 } 439 }
387 440 /* In target mode, check the last data frame of the sequence.
441 * For DDP in target mode, data is already DDPed but the header
442 * indication of the last data frame ould allow is to tell if we
443 * got all the data and the ULP can send FCP_RSP back, as this is
444 * not a full fcoe frame, we fill the trailer here so it won't be
445 * dropped by the ULP stack.
446 */
447 if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
448 (fctl & FC_FC_END_SEQ)) {
449 crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
450 crc->fcoe_eof = FC_EOF_T;
451 }
388ddp_out: 452ddp_out:
389 return rc; 453 return rc;
390} 454}
@@ -840,5 +904,3 @@ int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
840 } 904 }
841 return rc; 905 return rc;
842} 906}
843
844
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
index 02a00d2415d9..5a650a4ace66 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -52,6 +52,9 @@
52/* fcerr */ 52/* fcerr */
53#define IXGBE_FCERR_BADCRC 0x00100000 53#define IXGBE_FCERR_BADCRC 0x00100000
54 54
55/* FCoE DDP for target mode */
56#define __IXGBE_FCOE_TARGET 1
57
55struct ixgbe_fcoe_ddp { 58struct ixgbe_fcoe_ddp {
56 int len; 59 int len;
57 u32 err; 60 u32 err;
@@ -66,6 +69,7 @@ struct ixgbe_fcoe {
66 u8 tc; 69 u8 tc;
67 u8 up; 70 u8 up;
68#endif 71#endif
72 unsigned long mode;
69 atomic_t refcnt; 73 atomic_t refcnt;
70 spinlock_t lock; 74 spinlock_t lock;
71 struct pci_pool *pool; 75 struct pci_pool *pool;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 32231ffe0717..5e8c39decca1 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7019,6 +7019,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
7019#endif 7019#endif
7020#ifdef IXGBE_FCOE 7020#ifdef IXGBE_FCOE
7021 .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get, 7021 .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
7022 .ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target,
7022 .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put, 7023 .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
7023 .ndo_fcoe_enable = ixgbe_fcoe_enable, 7024 .ndo_fcoe_enable = ixgbe_fcoe_enable,
7024 .ndo_fcoe_disable = ixgbe_fcoe_disable, 7025 .ndo_fcoe_disable = ixgbe_fcoe_disable,