forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SCSI] cxgb3i: Add cxgb3i iSCSI driver.
This patch implements the cxgb3i iscsi connection acceleration for the open-iscsi initiator. The cxgb3i driver offers the iscsi PDU based offload: - digest insertion and verification - payload direct-placement into host memory buffer. Signed-off-by: Karen Xie <[email protected]> Signed-off-by: James Bottomley <[email protected]>
- Loading branch information
Karen Xie
authored and
James Bottomley
committed
Dec 30, 2008
1 parent
b632ade
commit c367346
Showing
14 changed files
with
4,873 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
Chelsio S3 iSCSI Driver for Linux | ||
|
||
Introduction | ||
============ | ||
|
||
The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc. | ||
series of products) supports iSCSI acceleration and iSCSI Direct Data Placement | ||
(DDP) where the hardware handles the expensive byte touching operations, such | ||
as CRC computation and verification, and direct DMA to the final host memory | ||
destination: | ||
|
||
- iSCSI PDU digest generation and verification | ||
|
||
On transmitting, Chelsio S3 h/w computes and inserts the Header and | ||
Data digest into the PDUs. | ||
On receiving, Chelsio S3 h/w computes and verifies the Header and | ||
Data digest of the PDUs. | ||
|
||
- Direct Data Placement (DDP) | ||
|
||
S3 h/w can directly place the iSCSI Data-In or Data-Out PDU's | ||
payload into pre-posted final destination host-memory buffers based | ||
on the Initiator Task Tag (ITT) in Data-In or Target Task Tag (TTT) | ||
in Data-Out PDUs. | ||
|
||
- PDU Transmit and Recovery | ||
|
||
On transmitting, S3 h/w accepts the complete PDU (header + data) | ||
from the host driver, computes and inserts the digests, decomposes | ||
the PDU into multiple TCP segments if necessary, and transmit all | ||
the TCP segments onto the wire. It handles TCP retransmission if | ||
needed. | ||
|
||
On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP | ||
segments, separating the header and data, calculating and verifying | ||
the digests, then forwards the header to the host. The payload data, | ||
if possible, will be directly placed into the pre-posted host DDP | ||
buffer. Otherwise, the payload data will be sent to the host too. | ||
|
||
The cxgb3i driver interfaces with open-iscsi initiator and provides the iSCSI | ||
acceleration through Chelsio hardware wherever applicable. | ||
|
||
Using the cxgb3i Driver | ||
======================= | ||
|
||
The following steps need to be taken to accelerates the open-iscsi initiator: | ||
|
||
1. Load the cxgb3i driver: "modprobe cxgb3i" | ||
|
||
The cxgb3i module registers a new transport class "cxgb3i" with open-iscsi. | ||
|
||
* in the case of recompiling the kernel, the cxgb3i selection is located at | ||
Device Drivers | ||
SCSI device support ---> | ||
[*] SCSI low-level drivers ---> | ||
<M> Chelsio S3xx iSCSI support | ||
|
||
2. Create an interface file located under /etc/iscsi/ifaces/ for the new | ||
transport class "cxgb3i". | ||
|
||
The content of the file should be in the following format: | ||
iface.transport_name = cxgb3i | ||
iface.net_ifacename = <ethX> | ||
iface.ipaddress = <iscsi ip address> | ||
|
||
* if iface.ipaddress is specified, <iscsi ip address> needs to be either the | ||
same as the ethX's ip address or an address on the same subnet. Make | ||
sure the ip address is unique in the network. | ||
|
||
3. edit /etc/iscsi/iscsid.conf | ||
The default setting for MaxRecvDataSegmentLength (131072) is too big, | ||
replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no | ||
bigger than 15360 (for example 8192): | ||
|
||
node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192 | ||
|
||
* The login would fail for a normal session if MaxRecvDataSegmentLength is | ||
too big. A error message in the format of | ||
"cxgb3i: ERR! MaxRecvSegmentLength <X> too big. Need to be <= <Y>." | ||
would be logged to dmesg. | ||
|
||
4. To direct open-iscsi traffic to go through cxgb3i's accelerated path, | ||
"-I <iface file name>" option needs to be specified with most of the | ||
iscsiadm command. <iface file name> is the transport interface file created | ||
in step 2. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3 | ||
|
||
cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o | ||
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i_ddp.o cxgb3i.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
config SCSI_CXGB3_ISCSI | ||
tristate "Chelsio S3xx iSCSI support" | ||
select CHELSIO_T3 | ||
select SCSI_ISCSI_ATTRS | ||
---help--- | ||
This driver supports iSCSI offload for the Chelsio S3 series devices. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* cxgb3i.h: Chelsio S3xx iSCSI driver. | ||
* | ||
* Copyright (c) 2008 Chelsio Communications, Inc. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation. | ||
* | ||
* Written by: Karen Xie ([email protected]) | ||
*/ | ||
|
||
#ifndef __CXGB3I_H__ | ||
#define __CXGB3I_H__ | ||
|
||
#include <linux/module.h> | ||
#include <linux/moduleparam.h> | ||
#include <linux/errno.h> | ||
#include <linux/types.h> | ||
#include <linux/list.h> | ||
#include <linux/netdevice.h> | ||
#include <linux/scatterlist.h> | ||
#include <scsi/libiscsi_tcp.h> | ||
|
||
/* from cxgb3 LLD */ | ||
#include "common.h" | ||
#include "t3_cpl.h" | ||
#include "t3cdev.h" | ||
#include "cxgb3_ctl_defs.h" | ||
#include "cxgb3_offload.h" | ||
#include "firmware_exports.h" | ||
|
||
#include "cxgb3i_offload.h" | ||
#include "cxgb3i_ddp.h" | ||
|
||
#define CXGB3I_SCSI_QDEPTH_DFLT 128 | ||
#define CXGB3I_MAX_TARGET CXGB3I_MAX_CONN | ||
#define CXGB3I_MAX_LUN 512 | ||
#define ISCSI_PDU_NONPAYLOAD_MAX \ | ||
(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + 2*ISCSI_DIGEST_SIZE) | ||
|
||
struct cxgb3i_adapter; | ||
struct cxgb3i_hba; | ||
struct cxgb3i_endpoint; | ||
|
||
/** | ||
* struct cxgb3i_hba - cxgb3i iscsi structure (per port) | ||
* | ||
* @snic: cxgb3i adapter containing this port | ||
* @ndev: pointer to netdev structure | ||
* @shost: pointer to scsi host structure | ||
*/ | ||
struct cxgb3i_hba { | ||
struct cxgb3i_adapter *snic; | ||
struct net_device *ndev; | ||
struct Scsi_Host *shost; | ||
}; | ||
|
||
/** | ||
* struct cxgb3i_adapter - cxgb3i adapter structure (per pci) | ||
* | ||
* @listhead: list head to link elements | ||
* @lock: lock for this structure | ||
* @tdev: pointer to t3cdev used by cxgb3 driver | ||
* @pdev: pointer to pci dev | ||
* @hba_cnt: # of hbas (the same as # of ports) | ||
* @hba: all the hbas on this adapter | ||
* @tx_max_size: max. tx packet size supported | ||
* @rx_max_size: max. rx packet size supported | ||
* @tag_format: ddp tag format settings | ||
*/ | ||
struct cxgb3i_adapter { | ||
struct list_head list_head; | ||
spinlock_t lock; | ||
struct t3cdev *tdev; | ||
struct pci_dev *pdev; | ||
unsigned char hba_cnt; | ||
struct cxgb3i_hba *hba[MAX_NPORTS]; | ||
|
||
unsigned int tx_max_size; | ||
unsigned int rx_max_size; | ||
|
||
struct cxgb3i_tag_format tag_format; | ||
}; | ||
|
||
/** | ||
* struct cxgb3i_conn - cxgb3i iscsi connection | ||
* | ||
* @listhead: list head to link elements | ||
* @cep: pointer to iscsi_endpoint structure | ||
* @conn: pointer to iscsi_conn structure | ||
* @hba: pointer to the hba this conn. is going through | ||
* @task_idx_bits: # of bits needed for session->cmds_max | ||
*/ | ||
struct cxgb3i_conn { | ||
struct list_head list_head; | ||
struct cxgb3i_endpoint *cep; | ||
struct iscsi_conn *conn; | ||
struct cxgb3i_hba *hba; | ||
unsigned int task_idx_bits; | ||
}; | ||
|
||
/** | ||
* struct cxgb3i_endpoint - iscsi tcp endpoint | ||
* | ||
* @c3cn: the h/w tcp connection representation | ||
* @hba: pointer to the hba this conn. is going through | ||
* @cconn: pointer to the associated cxgb3i iscsi connection | ||
*/ | ||
struct cxgb3i_endpoint { | ||
struct s3_conn *c3cn; | ||
struct cxgb3i_hba *hba; | ||
struct cxgb3i_conn *cconn; | ||
}; | ||
|
||
int cxgb3i_iscsi_init(void); | ||
void cxgb3i_iscsi_cleanup(void); | ||
|
||
struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *); | ||
void cxgb3i_adapter_remove(struct t3cdev *); | ||
int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *); | ||
void cxgb3i_adapter_ulp_cleanup(struct cxgb3i_adapter *); | ||
|
||
struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *); | ||
struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *, | ||
struct net_device *); | ||
void cxgb3i_hba_host_remove(struct cxgb3i_hba *); | ||
|
||
int cxgb3i_pdu_init(void); | ||
void cxgb3i_pdu_cleanup(void); | ||
void cxgb3i_conn_cleanup_task(struct iscsi_task *); | ||
int cxgb3i_conn_alloc_pdu(struct iscsi_task *, u8); | ||
int cxgb3i_conn_init_pdu(struct iscsi_task *, unsigned int, unsigned int); | ||
int cxgb3i_conn_xmit_pdu(struct iscsi_task *); | ||
|
||
void cxgb3i_release_itt(struct iscsi_task *task, itt_t hdr_itt); | ||
int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt); | ||
|
||
#endif |
Oops, something went wrong.