Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Yi Zou and committed by
Jeff Kirsher
68a683cf 4ea09c9c

+81 -12
+2
drivers/net/ixgbe/ixgbe.h
··· 552 552 struct sk_buff *skb); 553 553 extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, 554 554 struct scatterlist *sgl, unsigned int sgc); 555 + extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, 556 + struct scatterlist *sgl, unsigned int sgc); 555 557 extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); 556 558 extern int ixgbe_fcoe_enable(struct net_device *netdev); 557 559 extern int ixgbe_fcoe_disable(struct net_device *netdev);
+74 -12
drivers/net/ixgbe/ixgbe_fcoe.c
··· 135 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 141 * @netdev: the corresponding net_device 141 142 * @xid: the exchange id requesting ddp 142 143 * @sgl: the scatter-gather list for this request 143 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 146 * Returns : 1 for success and 0 for no ddp 151 147 */ 152 - int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, 153 - struct scatterlist *sgl, unsigned int sgc) 148 + static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, 149 + struct scatterlist *sgl, unsigned int sgc, 150 + int target_mode) 154 151 { 155 152 struct ixgbe_adapter *adapter; 156 153 struct ixgbe_hw *hw; ··· 161 164 unsigned int lastsize; 162 165 unsigned int thisoff = 0; 163 166 unsigned int thislen = 0; 164 - u32 fcbuff, fcdmarw, fcfltrw; 167 + u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; 165 168 dma_addr_t addr = 0; 166 169 167 170 if (!netdev || !sgl) ··· 272 275 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); 273 276 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); 274 277 fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); 278 + /* Set WRCONTX bit to allow DDP for target */ 279 + if (target_mode) 280 + fcbuff |= (IXGBE_FCBUFF_WRCONTX); 275 281 fcbuff |= (IXGBE_FCBUFF_VALID); 276 282 277 283 fcdmarw = xid; ··· 287 287 /* program DMA context */ 288 288 hw = &adapter->hw; 289 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 300 IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32)); 291 301 IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32); 292 302 IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff); ··· 305 295 IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0); 306 296 IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID); 307 297 IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw); 298 + 308 299 spin_unlock_bh(&fcoe->lock); 309 300 310 301 return 1; ··· 317 306 out_noddp_unmap: 318 307 pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); 319 308 return 0; 309 + } 310 + 311 + /** 312 + * ixgbe_fcoe_ddp_get - called to set up ddp context in initiator mode 313 + * @netdev: the corresponding net_device 314 + * @xid: the exchange id requesting ddp 315 + * @sgl: the scatter-gather list for this request 316 + * @sgc: the number of scatter-gather items 317 + * 318 + * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup 319 + * and is expected to be called from ULD, e.g., FCP layer of libfc 320 + * to set up ddp for the corresponding xid of the given sglist for 321 + * the corresponding I/O. 322 + * 323 + * Returns : 1 for success and 0 for no ddp 324 + */ 325 + int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, 326 + struct scatterlist *sgl, unsigned int sgc) 327 + { 328 + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0); 329 + } 330 + 331 + /** 332 + * ixgbe_fcoe_ddp_target - called to set up ddp context in target mode 333 + * @netdev: the corresponding net_device 334 + * @xid: the exchange id requesting ddp 335 + * @sgl: the scatter-gather list for this request 336 + * @sgc: the number of scatter-gather items 337 + * 338 + * This is the implementation of net_device_ops.ndo_fcoe_ddp_target 339 + * and is expected to be called from ULD, e.g., FCP layer of libfc 340 + * to set up ddp for the corresponding xid of the given sglist for 341 + * the corresponding I/O. The DDP in target mode is a write I/O request 342 + * from the initiator. 343 + * 344 + * Returns : 1 for success and 0 for no ddp 345 + */ 346 + int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, 347 + struct scatterlist *sgl, unsigned int sgc) 348 + { 349 + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1); 320 350 } 321 351 322 352 /** ··· 383 331 struct ixgbe_fcoe *fcoe; 384 332 struct ixgbe_fcoe_ddp *ddp; 385 333 struct fc_frame_header *fh; 334 + struct fcoe_crc_eof *crc; 386 335 387 336 if (!ixgbe_rx_is_fcoe(rx_desc)) 388 337 goto ddp_out; ··· 437 384 else if (ddp->len) 438 385 rc = ddp->len; 439 386 } 440 - 387 + /* In target mode, check the last data frame of the sequence. 388 + * For DDP in target mode, data is already DDPed but the header 389 + * indication of the last data frame ould allow is to tell if we 390 + * got all the data and the ULP can send FCP_RSP back, as this is 391 + * not a full fcoe frame, we fill the trailer here so it won't be 392 + * dropped by the ULP stack. 393 + */ 394 + if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && 395 + (fctl & FC_FC_END_SEQ)) { 396 + crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); 397 + crc->fcoe_eof = FC_EOF_T; 398 + } 441 399 ddp_out: 442 400 return rc; 443 401 } ··· 904 840 } 905 841 return rc; 906 842 } 907 - 908 -
+4
drivers/net/ixgbe/ixgbe_fcoe.h
··· 52 52 /* fcerr */ 53 53 #define IXGBE_FCERR_BADCRC 0x00100000 54 54 55 + /* FCoE DDP for target mode */ 56 + #define __IXGBE_FCOE_TARGET 1 57 + 55 58 struct ixgbe_fcoe_ddp { 56 59 int len; 57 60 u32 err; ··· 69 66 u8 tc; 70 67 u8 up; 71 68 #endif 69 + unsigned long mode; 72 70 atomic_t refcnt; 73 71 spinlock_t lock; 74 72 struct pci_pool *pool;
+1
drivers/net/ixgbe/ixgbe_main.c
··· 7019 7019 #endif 7020 7020 #ifdef IXGBE_FCOE 7021 7021 .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get, 7022 + .ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target, 7022 7023 .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put, 7023 7024 .ndo_fcoe_enable = ixgbe_fcoe_enable, 7024 7025 .ndo_fcoe_disable = ixgbe_fcoe_disable,