提交 e777d192 编写于 作者: L Linus Torvalds

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull first round of SCSI updates from James Bottomley:
 "This patch set includes two large new drivers: mpt3sas (for the next
  gen fusion SAS hardware) and csiostor a FCoE offload driver for the
  Chelsio converged network cards (this includes some net changes which
  I've OK'd with DaveM).

  The rest of the patch is driver updates (qla2xxx, lpfc, hptiop,
  be2iscsi) plus a few assorted updates and bug fixes.

  We also have a Power Management rework in the Upper Layer Drivers
  preparatory to doing ACPI zero power optical devices, but the actual
  enabler is still being worked on.

  Signed-off-by: James Bottomley <JBottomley@Parallels.com>"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (72 commits)
  [SCSI] mpt3sas: add new driver supporting 12GB SAS
  [SCSI] scsi_transport_sas: add 12GB definitions for mpt3sas
  [SCSI] miscdevice: Adding support for MPT3SAS_MINOR(222)
  [SCSI] csiostor: remove unneeded memset()
  [SCSI] csiostor: Fix sparse warnings.
  [SCSI] qla2xxx: Display that driver is operating in legacy interrupt mode.
  [SCSI] qla2xxx: Dont clear drv active on iospace config failure.
  [SCSI] qla2xxx: Fix typo in qla2xxx driver.
  [SCSI] qla2xxx: Update ql2xextended_error_logging parameter description with new option.
  [SCSI] qla2xxx: Parameterize the link speed of hba rather than fcport.
  [SCSI] qla2xxx: Add 16Gb/s case to get port speed capability.
  [SCSI] qla2xxx: Move marking fcport online ahead of setting iiDMA speed.
  [SCSI] qla2xxx: Add acquiring of risc semaphore before doing ISP reset.
  [SCSI] qla2xxx: Ignore driver ack bit if corresponding presence bit is not set.
  [SCSI] qla2xxx: Fix typo in qla83xx_fw_dump function.
  [SCSI] qla2xxx: Add Gen3 PCIe speed 8GT/s to the log message.
  [SCSI] qla2xxx: Use correct Request-Q-Out register during bidirectional request processing
  [SCSI] qla2xxx: Move noisy Start scsi failed messages to verbose logging level.
  [SCSI] qla2xxx: Fix coccinelle warnings in qla2x00_relogin.
  [SCSI] qla2xxx: No fcport FC-4 type assignment in GA_NXT response.
  ...
......@@ -37,7 +37,7 @@ For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0:
0x40 Inbound Queue Port
0x44 Outbound Queue Port
For Marvell IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
For Marvell not Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
BAR0 offset Register
0x20400 Inbound Doorbell Register
......@@ -55,9 +55,31 @@ For Marvell IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
0x40-0x1040 Inbound Queue
0x1040-0x2040 Outbound Queue
For Marvell Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
I/O Request Workflow
----------------------
BAR0 offset Register
0x0 IOP configuration information.
BAR1 offset Register
0x4000 Inbound List Base Address Low
0x4004 Inbound List Base Address High
0x4018 Inbound List Write Pointer
0x402C Inbound List Configuration and Control
0x4050 Outbound List Base Address Low
0x4054 Outbound List Base Address High
0x4058 Outbound List Copy Pointer Shadow Base Address Low
0x405C Outbound List Copy Pointer Shadow Base Address High
0x4088 Outbound List Interrupt Cause
0x408C Outbound List Interrupt Enable
0x1020C PCIe Function 0 Interrupt Enable
0x10400 PCIe Function 0 to CPU Message A
0x10420 CPU to PCIe Function 0 Message A
0x10480 CPU to PCIe Function 0 Doorbell
0x10484 CPU to PCIe Function 0 Doorbell Enable
I/O Request Workflow of Not Marvell Frey
------------------------------------------
All queued requests are handled via inbound/outbound queue port.
A request packet can be allocated in either IOP or host memory.
......@@ -101,6 +123,45 @@ register 0. An outbound message with the same value indicates the completion
of an inbound message.
I/O Request Workflow of Marvell Frey
--------------------------------------
All queued requests are handled via inbound/outbound list.
To send a request to the controller:
- Allocate a free request in host DMA coherent memory.
Requests allocated in host memory must be aligned on 32-bytes boundary.
- Fill the request with index of the request in the flag.
Fill a free inbound list unit with the physical address and the size of
the request.
Set up the inbound list write pointer with the index of previous unit,
round to 0 if the index reaches the supported count of requests.
- Post the inbound list writer pointer to IOP.
- The IOP process the request. When the request is completed, the flag of
the request with or-ed IOPMU_QUEUE_MASK_HOST_BITS will be put into a
free outbound list unit and the index of the outbound list unit will be
put into the copy pointer shadow register. An outbound interrupt will be
generated.
- The host read the outbound list copy pointer shadow register and compare
with previous saved read ponter N. If they are different, the host will
read the (N+1)th outbound list unit.
The host get the index of the request from the (N+1)th outbound list
unit and complete the request.
Non-queued requests (reset communication/reset/flush etc) can be sent via PCIe
Function 0 to CPU Message A register. The CPU to PCIe Function 0 Message register
with the same value indicates the completion of message.
User-level Interface
---------------------
......@@ -112,7 +173,7 @@ The driver exposes following sysfs attributes:
-----------------------------------------------------------------------------
Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved.
Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -4655,13 +4655,16 @@ S: Maintained
F: fs/logfs/
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Eric Moore <Eric.Moore@lsi.com>
M: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
M: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
M: support@lsi.com
L: DL-MPTFusionLinux@lsi.com
L: linux-scsi@vger.kernel.org
W: http://www.lsilogic.com/support
S: Supported
F: drivers/message/fusion/
F: drivers/scsi/mpt2sas/
F: drivers/scsi/mpt3sas/
LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
M: Matthew Wilcox <matthew@wil.cx>
......
......@@ -3203,7 +3203,7 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
memset(c, 0, sizeof(*c));
c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST | FW_CMD_READ);
c->retval_len16 = htonl(FW_LEN16(*c));
c->cfvalid_to_len16 = htonl(FW_LEN16(*c));
ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), c);
if (ret < 0)
return ret;
......@@ -3397,7 +3397,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST |
FW_CMD_READ);
caps_cmd.retval_len16 =
caps_cmd.cfvalid_to_len16 =
htonl(FW_CAPS_CONFIG_CMD_CFVALID |
FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) |
FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) |
......@@ -3422,7 +3422,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST |
FW_CMD_WRITE);
caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd),
NULL);
if (ret < 0)
......@@ -3497,7 +3497,7 @@ static int adap_init0_no_config(struct adapter *adapter, int reset)
memset(&caps_cmd, 0, sizeof(caps_cmd));
caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST | FW_CMD_READ);
caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd),
&caps_cmd);
if (ret < 0)
......@@ -3929,7 +3929,7 @@ static int adap_init0(struct adapter *adap)
memset(&caps_cmd, 0, sizeof(caps_cmd));
caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST | FW_CMD_READ);
caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
&caps_cmd);
if (ret < 0)
......
......@@ -508,7 +508,7 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{
if (q->pend_cred >= 8) {
wmb();
t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO |
t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) |
QID(q->cntxt_id) | PIDX(q->pend_cred / 8));
q->pend_cred &= 7;
}
......@@ -2082,10 +2082,10 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
goto fl_nomem;
flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc);
c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN |
c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN(1) |
FW_IQ_CMD_FL0FETCHRO(1) |
FW_IQ_CMD_FL0DATARO(1) |
FW_IQ_CMD_FL0PADEN);
FW_IQ_CMD_FL0PADEN(1));
c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) |
FW_IQ_CMD_FL0FBMAX(3));
c.fl0size = htons(flsz);
......
......@@ -648,12 +648,12 @@ static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
if (!byte_cnt || byte_cnt > 4)
return -EINVAL;
if (t4_read_reg(adapter, SF_OP) & BUSY)
if (t4_read_reg(adapter, SF_OP) & SF_BUSY)
return -EBUSY;
cont = cont ? SF_CONT : 0;
lock = lock ? SF_LOCK : 0;
t4_write_reg(adapter, SF_OP, lock | cont | BYTECNT(byte_cnt - 1));
ret = t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
ret = t4_wait_op_done(adapter, SF_OP, SF_BUSY, 0, SF_ATTEMPTS, 5);
if (!ret)
*valp = t4_read_reg(adapter, SF_DATA);
return ret;
......@@ -676,14 +676,14 @@ static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
{
if (!byte_cnt || byte_cnt > 4)
return -EINVAL;
if (t4_read_reg(adapter, SF_OP) & BUSY)
if (t4_read_reg(adapter, SF_OP) & SF_BUSY)
return -EBUSY;
cont = cont ? SF_CONT : 0;
lock = lock ? SF_LOCK : 0;
t4_write_reg(adapter, SF_DATA, val);
t4_write_reg(adapter, SF_OP, lock |
cont | BYTECNT(byte_cnt - 1) | OP_WR);
return t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
return t4_wait_op_done(adapter, SF_OP, SF_BUSY, 0, SF_ATTEMPTS, 5);
}
/**
......@@ -2252,14 +2252,14 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
t4_write_reg(adap, EPIO_REG(DATA0), mask0);
t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i) | EPIOWR);
t4_read_reg(adap, EPIO_REG(OP)); /* flush */
if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY)
return -ETIMEDOUT;
/* write CRC */
t4_write_reg(adap, EPIO_REG(DATA0), crc);
t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i + 32) | EPIOWR);
t4_read_reg(adap, EPIO_REG(OP)); /* flush */
if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY)
return -ETIMEDOUT;
}
#undef EPIO_REG
......@@ -2405,7 +2405,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
retry:
memset(&c, 0, sizeof(c));
INIT_CMD(c, HELLO, WRITE);
c.err_to_mbasyncnot = htonl(
c.err_to_clearinit = htonl(
FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) |
FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) |
FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox :
......@@ -2426,7 +2426,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
return ret;
}
v = ntohl(c.err_to_mbasyncnot);
v = ntohl(c.err_to_clearinit);
master_mbox = FW_HELLO_CMD_MBMASTER_GET(v);
if (state) {
if (v & FW_HELLO_CMD_ERR)
......@@ -2774,7 +2774,7 @@ int t4_fw_config_file(struct adapter *adap, unsigned int mbox,
htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST |
FW_CMD_READ);
caps_cmd.retval_len16 =
caps_cmd.cfvalid_to_len16 =
htonl(FW_CAPS_CONFIG_CMD_CFVALID |
FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) |
FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) |
......@@ -2797,7 +2797,7 @@ int t4_fw_config_file(struct adapter *adap, unsigned int mbox,
htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST |
FW_CMD_WRITE);
caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
return t4_wr_mbox(adap, mbox, &caps_cmd, sizeof(caps_cmd), NULL);
}
......
......@@ -658,6 +658,7 @@ struct ulptx_sgl {
__be32 cmd_nsge;
#define ULPTX_CMD(x) ((x) << 24)
#define ULPTX_NSGE(x) ((x) << 0)
#define ULPTX_MORE (1U << 23)
__be32 len0;
__be64 addr0;
struct ulptx_sge_pair sge[0];
......
......@@ -67,7 +67,7 @@
#define QID_MASK 0xffff8000U
#define QID_SHIFT 15
#define QID(x) ((x) << QID_SHIFT)
#define DBPRIO 0x00004000U
#define DBPRIO(x) ((x) << 14)
#define PIDX_MASK 0x00003fffU
#define PIDX_SHIFT 0
#define PIDX(x) ((x) << PIDX_SHIFT)
......@@ -193,6 +193,12 @@
#define SGE_FL_BUFFER_SIZE1 0x1048
#define SGE_FL_BUFFER_SIZE2 0x104c
#define SGE_FL_BUFFER_SIZE3 0x1050
#define SGE_FL_BUFFER_SIZE4 0x1054
#define SGE_FL_BUFFER_SIZE5 0x1058
#define SGE_FL_BUFFER_SIZE6 0x105c
#define SGE_FL_BUFFER_SIZE7 0x1060
#define SGE_FL_BUFFER_SIZE8 0x1064
#define SGE_INGRESS_RX_THRESHOLD 0x10a0
#define THRESHOLD_0_MASK 0x3f000000U
#define THRESHOLD_0_SHIFT 24
......@@ -217,6 +223,17 @@
#define EGRTHRESHOLD(x) ((x) << EGRTHRESHOLDshift)
#define EGRTHRESHOLD_GET(x) (((x) & EGRTHRESHOLD_MASK) >> EGRTHRESHOLDshift)
#define SGE_DBFIFO_STATUS 0x10a4
#define HP_INT_THRESH_SHIFT 28
#define HP_INT_THRESH_MASK 0xfU
#define HP_INT_THRESH(x) ((x) << HP_INT_THRESH_SHIFT)
#define LP_INT_THRESH_SHIFT 12
#define LP_INT_THRESH_MASK 0xfU
#define LP_INT_THRESH(x) ((x) << LP_INT_THRESH_SHIFT)
#define SGE_DOORBELL_CONTROL 0x10a8
#define ENABLE_DROP (1 << 13)
#define SGE_TIMER_VALUE_0_AND_1 0x10b8
#define TIMERVALUE0_MASK 0xffff0000U
#define TIMERVALUE0_SHIFT 16
......@@ -277,6 +294,10 @@
#define A_SGE_CTXT_CMD 0x11fc
#define A_SGE_DBQ_CTXT_BADDR 0x1084
#define PCIE_PF_CFG 0x40
#define AIVEC(x) ((x) << 4)
#define AIVEC_MASK 0x3ffU
#define PCIE_PF_CLI 0x44
#define PCIE_INT_CAUSE 0x3004
#define UNXSPLCPLERR 0x20000000U
......@@ -322,6 +343,13 @@
#define PCIE_MEM_ACCESS_OFFSET 0x306c
#define PCIE_FW 0x30b8
#define PCIE_FW_ERR 0x80000000U
#define PCIE_FW_INIT 0x40000000U
#define PCIE_FW_HALT 0x20000000U
#define PCIE_FW_MASTER_VLD 0x00008000U
#define PCIE_FW_MASTER(x) ((x) << 12)
#define PCIE_FW_MASTER_MASK 0x7
#define PCIE_FW_MASTER_GET(x) (((x) >> 12) & PCIE_FW_MASTER_MASK)
#define PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS 0x5908
#define RNPP 0x80000000U
......@@ -432,6 +460,9 @@
#define MBOWNER(x) ((x) << MBOWNER_SHIFT)
#define MBOWNER_GET(x) (((x) & MBOWNER_MASK) >> MBOWNER_SHIFT)
#define CIM_PF_HOST_INT_ENABLE 0x288
#define MBMSGRDYINTEN(x) ((x) << 19)
#define CIM_PF_HOST_INT_CAUSE 0x28c
#define MBMSGRDYINT 0x00080000U
......@@ -922,7 +953,7 @@
#define SF_DATA 0x193f8
#define SF_OP 0x193fc
#define BUSY 0x80000000U
#define SF_BUSY 0x80000000U
#define SF_LOCK 0x00000010U
#define SF_CONT 0x00000008U
#define BYTECNT_MASK 0x00000006U
......@@ -981,6 +1012,7 @@
#define I2CM 0x00000002U
#define CIM 0x00000001U
#define PL_INT_ENABLE 0x19410
#define PL_INT_MAP0 0x19414
#define PL_RST 0x19428
#define PIORST 0x00000002U
......
......@@ -68,6 +68,7 @@ struct fw_wr_hdr {
};
#define FW_WR_OP(x) ((x) << 24)
#define FW_WR_OP_GET(x) (((x) >> 24) & 0xff)
#define FW_WR_ATOMIC(x) ((x) << 23)
#define FW_WR_FLUSH(x) ((x) << 22)
#define FW_WR_COMPL(x) ((x) << 21)
......@@ -222,6 +223,7 @@ struct fw_cmd_hdr {
#define FW_CMD_OP(x) ((x) << 24)
#define FW_CMD_OP_GET(x) (((x) >> 24) & 0xff)
#define FW_CMD_REQUEST (1U << 23)
#define FW_CMD_REQUEST_GET(x) (((x) >> 23) & 0x1)
#define FW_CMD_READ (1U << 22)
#define FW_CMD_WRITE (1U << 21)
#define FW_CMD_EXEC (1U << 20)
......@@ -229,6 +231,7 @@ struct fw_cmd_hdr {
#define FW_CMD_RETVAL(x) ((x) << 8)
#define FW_CMD_RETVAL_GET(x) (((x) >> 8) & 0xff)
#define FW_CMD_LEN16(x) ((x) << 0)
#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16)
enum fw_ldst_addrspc {
FW_LDST_ADDRSPC_FIRMWARE = 0x0001,
......@@ -241,7 +244,8 @@ enum fw_ldst_addrspc {
FW_LDST_ADDRSPC_TP_MIB = 0x0012,
FW_LDST_ADDRSPC_MDIO = 0x0018,
FW_LDST_ADDRSPC_MPS = 0x0020,
FW_LDST_ADDRSPC_FUNC = 0x0028
FW_LDST_ADDRSPC_FUNC = 0x0028,
FW_LDST_ADDRSPC_FUNC_PCIE = 0x0029,
};
enum fw_ldst_mps_fid {
......@@ -303,6 +307,16 @@ struct fw_ldst_cmd {
__be64 data0;
__be64 data1;
} func;
struct fw_ldst_pcie {
u8 ctrl_to_fn;
u8 bnum;
u8 r;
u8 ext_r;
u8 select_naccess;
u8 pcie_fn;
__be16 nset_pkd;
__be32 data[12];
} pcie;
} u;
};
......@@ -312,6 +326,9 @@ struct fw_ldst_cmd {
#define FW_LDST_CMD_FID(x) ((x) << 15)
#define FW_LDST_CMD_CTL(x) ((x) << 0)
#define FW_LDST_CMD_RPLCPF(x) ((x) << 0)
#define FW_LDST_CMD_LC (1U << 4)
#define FW_LDST_CMD_NACCESS(x) ((x) << 0)
#define FW_LDST_CMD_FN(x) ((x) << 0)
struct fw_reset_cmd {
__be32 op_to_write;
......@@ -333,7 +350,7 @@ enum fw_hellow_cmd {
struct fw_hello_cmd {
__be32 op_to_write;
__be32 retval_len16;
__be32 err_to_mbasyncnot;
__be32 err_to_clearinit;
#define FW_HELLO_CMD_ERR (1U << 31)
#define FW_HELLO_CMD_INIT (1U << 30)
#define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29)
......@@ -343,6 +360,7 @@ struct fw_hello_cmd {
#define FW_HELLO_CMD_MBMASTER(x) ((x) << FW_HELLO_CMD_MBMASTER_SHIFT)
#define FW_HELLO_CMD_MBMASTER_GET(x) \
(((x) >> FW_HELLO_CMD_MBMASTER_SHIFT) & FW_HELLO_CMD_MBMASTER_MASK)
#define FW_HELLO_CMD_MBASYNCNOTINT(x) ((x) << 23)
#define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20)
#define FW_HELLO_CMD_STAGE(x) ((x) << 17)
#define FW_HELLO_CMD_CLEARINIT (1U << 16)
......@@ -428,6 +446,7 @@ enum fw_caps_config_iscsi {
enum fw_caps_config_fcoe {
FW_CAPS_CONFIG_FCOE_INITIATOR = 0x00000001,
FW_CAPS_CONFIG_FCOE_TARGET = 0x00000002,
FW_CAPS_CONFIG_FCOE_CTRL_OFLD = 0x00000004,
};
enum fw_memtype_cf {
......@@ -440,7 +459,7 @@ enum fw_memtype_cf {
struct fw_caps_config_cmd {
__be32 op_to_write;
__be32 retval_len16;
__be32 cfvalid_to_len16;
__be32 r2;
__be32 hwmbitmap;
__be16 nbmcaps;
......@@ -701,8 +720,8 @@ struct fw_iq_cmd {
#define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6)
#define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4)
#define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3)
#define FW_IQ_CMD_FL0PADEN (1U << 2)
#define FW_IQ_CMD_FL0PACKEN (1U << 1)
#define FW_IQ_CMD_FL0PADEN(x) ((x) << 2)
#define FW_IQ_CMD_FL0PACKEN(x) ((x) << 1)
#define FW_IQ_CMD_FL0CONGEN (1U << 0)
#define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15)
......@@ -1190,6 +1209,14 @@ enum fw_port_dcb_cfg_rc {
FW_PORT_DCB_CFG_ERROR = 0x1
};
enum fw_port_dcb_type {
FW_PORT_DCB_TYPE_PGID = 0x00,
FW_PORT_DCB_TYPE_PGRATE = 0x01,
FW_PORT_DCB_TYPE_PRIORATE = 0x02,
FW_PORT_DCB_TYPE_PFC = 0x03,
FW_PORT_DCB_TYPE_APP_ID = 0x04,
};
struct fw_port_cmd {
__be32 op_to_portid;
__be32 action_to_len16;
......@@ -1257,6 +1284,7 @@ struct fw_port_cmd {
#define FW_PORT_CMD_TXIPG(x) ((x) << 19)
#define FW_PORT_CMD_LSTATUS (1U << 31)
#define FW_PORT_CMD_LSTATUS_GET(x) (((x) >> 31) & 0x1)
#define FW_PORT_CMD_LSPEED(x) ((x) << 24)
#define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f)
#define FW_PORT_CMD_TXPAUSE (1U << 23)
......@@ -1305,6 +1333,9 @@ enum fw_port_module_type {
FW_PORT_MOD_TYPE_TWINAX_PASSIVE,
FW_PORT_MOD_TYPE_TWINAX_ACTIVE,
FW_PORT_MOD_TYPE_LRM,
FW_PORT_MOD_TYPE_ERROR = FW_PORT_CMD_MODTYPE_MASK - 3,
FW_PORT_MOD_TYPE_UNKNOWN = FW_PORT_CMD_MODTYPE_MASK - 2,
FW_PORT_MOD_TYPE_NOTSUPPORTED = FW_PORT_CMD_MODTYPE_MASK - 1,
FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK
};
......
......@@ -536,7 +536,7 @@ static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl)
if (fl->pend_cred >= FL_PER_EQ_UNIT) {
wmb();
t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
DBPRIO |
DBPRIO(1) |
QID(fl->cntxt_id) |
PIDX(fl->pend_cred / FL_PER_EQ_UNIT));
fl->pend_cred %= FL_PER_EQ_UNIT;
......@@ -952,7 +952,7 @@ static inline void ring_tx_db(struct adapter *adapter, struct sge_txq *tq,
* Warn if we write doorbells with the wrong priority and write
* descriptors before telling HW.
*/
WARN_ON((QID(tq->cntxt_id) | PIDX(n)) & DBPRIO);
WARN_ON((QID(tq->cntxt_id) | PIDX(n)) & DBPRIO(1));
wmb();
t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
QID(tq->cntxt_id) | PIDX(n));
......@@ -2126,8 +2126,8 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq,
cmd.iqns_to_fl0congen =
cpu_to_be32(
FW_IQ_CMD_FL0HOSTFCMODE(SGE_HOSTFCMODE_NONE) |
FW_IQ_CMD_FL0PACKEN |
FW_IQ_CMD_FL0PADEN);
FW_IQ_CMD_FL0PACKEN(1) |
FW_IQ_CMD_FL0PADEN(1));
cmd.fl0dcaen_to_fl0cidxfthresh =
cpu_to_be16(
FW_IQ_CMD_FL0FBMIN(SGE_FETCHBURSTMIN_64B) |
......
......@@ -603,6 +603,7 @@ config SCSI_ARCMSR
source "drivers/scsi/megaraid/Kconfig.megaraid"
source "drivers/scsi/mpt2sas/Kconfig"
source "drivers/scsi/mpt3sas/Kconfig"
source "drivers/scsi/ufs/Kconfig"
config SCSI_HPTIOP
......@@ -1812,6 +1813,7 @@ config SCSI_VIRTIO
This is the virtual HBA driver for virtio. If the kernel will
be used in a virtual machine, say Y or M.
source "drivers/scsi/csiostor/Kconfig"
endif # SCSI_LOWLEVEL
......
......@@ -90,6 +90,7 @@ obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_QLA_ISCSI) += libiscsi.o qla4xxx/
obj-$(CONFIG_SCSI_LPFC) += lpfc/
obj-$(CONFIG_SCSI_BFA_FC) += bfa/
obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor/
obj-$(CONFIG_SCSI_PAS16) += pas16.o
obj-$(CONFIG_SCSI_T128) += t128.o
obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
......@@ -106,6 +107,7 @@ obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/
obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
......
......@@ -132,11 +132,13 @@ struct inquiry_data {
* M O D U L E G L O B A L S
*/
static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max);
static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new);
static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *sgmap);
static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg);
static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg);
static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,
struct aac_raw_io2 *rio2, int sg_max);
static int aac_convert_sgraw2(struct aac_raw_io2 *rio2,
int pages, int nseg, int nseg_new);
static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
#ifdef AAC_DETAILED_STATUS_INFO
static char *aac_get_status_string(u32 status);
......@@ -971,6 +973,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
{
struct aac_dev *dev = fib->dev;
u16 fibsize, command;
long ret;
aac_fib_init(fib);
if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
......@@ -982,7 +985,10 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
readcmd2->byteCount = cpu_to_le32(count<<9);
readcmd2->cid = cpu_to_le16(scmd_id(cmd));
readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
aac_build_sgraw2(cmd, readcmd2, dev->scsi_host_ptr->sg_tablesize);
ret = aac_build_sgraw2(cmd, readcmd2,
dev->scsi_host_ptr->sg_tablesize);
if (ret < 0)
return ret;
command = ContainerRawIo2;
fibsize = sizeof(struct aac_raw_io2) +
((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
......@@ -996,7 +1002,9 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
readcmd->bpTotal = 0;
readcmd->bpComplete = 0;
aac_build_sgraw(cmd, &readcmd->sg);
ret = aac_build_sgraw(cmd, &readcmd->sg);
if (ret < 0)
return ret;
command = ContainerRawIo;
fibsize = sizeof(struct aac_raw_io) +
((le32_to_cpu(readcmd->sg.count)-1) * sizeof(struct sgentryraw));
......@@ -1019,6 +1027,8 @@ static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
{
u16 fibsize;
struct aac_read64 *readcmd;
long ret;
aac_fib_init(fib);
readcmd = (struct aac_read64 *) fib_data(fib);
readcmd->command = cpu_to_le32(VM_CtHostRead64);
......@@ -1028,7 +1038,9 @@ static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
readcmd->pad = 0;
readcmd->flags = 0;
aac_build_sg64(cmd, &readcmd->sg);
ret = aac_build_sg64(cmd, &readcmd->sg);
if (ret < 0)
return ret;
fibsize = sizeof(struct aac_read64) +
((le32_to_cpu(readcmd->sg.count) - 1) *
sizeof (struct sgentry64));
......@@ -1050,6 +1062,8 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
{
u16 fibsize;
struct aac_read *readcmd;
long ret;
aac_fib_init(fib);
readcmd = (struct aac_read *) fib_data(fib);
readcmd->command = cpu_to_le32(VM_CtBlockRead);
......@@ -1057,7 +1071,9 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->count = cpu_to_le32(count * 512);
aac_build_sg(cmd, &readcmd->sg);
ret = aac_build_sg(cmd, &readcmd->sg);
if (ret < 0)
return ret;
fibsize = sizeof(struct aac_read) +
((le32_to_cpu(readcmd->sg.count) - 1) *
sizeof (struct sgentry));
......@@ -1079,6 +1095,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
{
struct aac_dev *dev = fib->dev;
u16 fibsize, command;
long ret;
aac_fib_init(fib);
if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
......@@ -1093,7 +1110,10 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
cpu_to_le16(RIO2_IO_TYPE_WRITE|RIO2_IO_SUREWRITE) :
cpu_to_le16(RIO2_IO_TYPE_WRITE);
aac_build_sgraw2(cmd, writecmd2, dev->scsi_host_ptr->sg_tablesize);
ret = aac_build_sgraw2(cmd, writecmd2,
dev->scsi_host_ptr->sg_tablesize);
if (ret < 0)
return ret;
command = ContainerRawIo2;
fibsize = sizeof(struct aac_raw_io2) +
((le32_to_cpu(writecmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
......@@ -1110,7 +1130,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
cpu_to_le16(RIO_TYPE_WRITE);
writecmd->bpTotal = 0;
writecmd->bpComplete = 0;
aac_build_sgraw(cmd, &writecmd->sg);
ret = aac_build_sgraw(cmd, &writecmd->sg);
if (ret < 0)
return ret;
command = ContainerRawIo;
fibsize = sizeof(struct aac_raw_io) +
((le32_to_cpu(writecmd->sg.count)-1) * sizeof (struct sgentryraw));
......@@ -1133,6 +1155,8 @@ static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba,
{
u16 fibsize;
struct aac_write64 *writecmd;
long ret;
aac_fib_init(fib);
writecmd = (struct aac_write64 *) fib_data(fib);
writecmd->command = cpu_to_le32(VM_CtHostWrite64);
......@@ -1142,7 +1166,9 @@ static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba,
writecmd->pad = 0;
writecmd->flags = 0;
aac_build_sg64(cmd, &writecmd->sg);
ret = aac_build_sg64(cmd, &writecmd->sg);
if (ret < 0)
return ret;
fibsize = sizeof(struct aac_write64) +
((le32_to_cpu(writecmd->sg.count) - 1) *
sizeof (struct sgentry64));
......@@ -1164,6 +1190,8 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
{
u16 fibsize;
struct aac_write *writecmd;
long ret;
aac_fib_init(fib);
writecmd = (struct aac_write *) fib_data(fib);
writecmd->command = cpu_to_le32(VM_CtBlockWrite);
......@@ -1173,7 +1201,9 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
writecmd->sg.count = cpu_to_le32(1);
/* ->stable is not used - it did mean which type of write */
aac_build_sg(cmd, &writecmd->sg);
ret = aac_build_sg(cmd, &writecmd->sg);
if (ret < 0)
return ret;
fibsize = sizeof(struct aac_write) +
((le32_to_cpu(writecmd->sg.count) - 1) *
sizeof (struct sgentry));
......@@ -1235,8 +1265,11 @@ static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
{
u16 fibsize;
struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
long ret;
aac_build_sg64(cmd, (struct sgmap64*) &srbcmd->sg);
ret = aac_build_sg64(cmd, (struct sgmap64 *) &srbcmd->sg);
if (ret < 0)
return ret;
srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
......@@ -1263,8 +1296,11 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
{
u16 fibsize;
struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
long ret;
aac_build_sg(cmd, (struct sgmap*)&srbcmd->sg);
ret = aac_build_sg(cmd, (struct sgmap *)&srbcmd->sg);
if (ret < 0)
return ret;
srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
......@@ -2870,7 +2906,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
return -1;
}
static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *psg)
{
struct aac_dev *dev;
unsigned long byte_count = 0;
......@@ -2883,7 +2919,8 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
psg->sg[0].count = 0;
nseg = scsi_dma_map(scsicmd);
BUG_ON(nseg < 0);
if (nseg < 0)
return nseg;
if (nseg) {
struct scatterlist *sg;
int i;
......@@ -2912,7 +2949,7 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
}
static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg)
static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg)
{
struct aac_dev *dev;
unsigned long byte_count = 0;
......@@ -2927,7 +2964,8 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
psg->sg[0].count = 0;
nseg = scsi_dma_map(scsicmd);
BUG_ON(nseg < 0);
if (nseg < 0)
return nseg;
if (nseg) {
struct scatterlist *sg;
int i;
......@@ -2957,7 +2995,7 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
return byte_count;
}
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg)
static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg)
{
unsigned long byte_count = 0;
int nseg;
......@@ -2972,7 +3010,8 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
psg->sg[0].flags = 0;
nseg = scsi_dma_map(scsicmd);
BUG_ON(nseg < 0);
if (nseg < 0)
return nseg;
if (nseg) {
struct scatterlist *sg;
int i;
......@@ -3005,13 +3044,15 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
return byte_count;
}
static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max)
static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,
struct aac_raw_io2 *rio2, int sg_max)
{
unsigned long byte_count = 0;
int nseg;
nseg = scsi_dma_map(scsicmd);
BUG_ON(nseg < 0);
if (nseg < 0)
return nseg;
if (nseg) {
struct scatterlist *sg;
int i, conformable = 0;
......
......@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 29800
# define AAC_DRIVER_BUILD 29801
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -28,7 +28,7 @@
/* BladeEngine Generation numbers */
#define BE_GEN2 2
#define BE_GEN3 3
#define BE_GEN4 4
struct be_dma_mem {
void *va;
dma_addr_t dma;
......@@ -84,9 +84,12 @@ static inline void queue_tail_inc(struct be_queue_info *q)
/*ISCSI */
struct be_eq_obj {
bool todo_mcc_cq;
bool todo_cq;
struct be_queue_info q;
struct beiscsi_hba *phba;
struct be_queue_info *cq;
struct work_struct work_cqs; /* Work Item */
struct blk_iopoll iopoll;
};
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -56,7 +56,7 @@ int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
writel(pconline0, (void *)pci_online0_offset);
writel(pconline1, (void *)pci_online1_offset);
sreset = BE2_SET_RESET;
sreset |= BE2_SET_RESET;
writel(sreset, (void *)pci_reset_offset);
i = 0;
......@@ -133,6 +133,87 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
return tag;
}
/*
* beiscsi_mccq_compl()- Wait for completion of MBX
* @phba: Driver private structure
* @tag: Tag for the MBX Command
* @wrb: the WRB used for the MBX Command
* @cmd_hdr: IOCTL Hdr for the MBX Cmd
*
* Waits for MBX completion with the passed TAG.
*
* return
* Success: 0
* Failure: Non-Zero
**/
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb,
void *cmd_hdr)
{
int rc = 0;
uint32_t mcc_tag_response;
uint16_t status = 0, addl_status = 0, wrb_num = 0;
struct be_mcc_wrb *temp_wrb;
struct be_cmd_req_hdr *ioctl_hdr;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
if (beiscsi_error(phba))
return -EIO;
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag],
msecs_to_jiffies(
BEISCSI_HOST_MBX_TIMEOUT));
if (rc <= 0) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Completion timed out\n");
rc = -EAGAIN;
goto release_mcc_tag;
} else
rc = 0;
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
status = (mcc_tag_response & CQE_STATUS_MASK);
addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >>
CQE_STATUS_ADDL_SHIFT);
if (cmd_hdr) {
ioctl_hdr = (struct be_cmd_req_hdr *)cmd_hdr;
} else {
wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >>
CQE_STATUS_WRB_SHIFT;
temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
ioctl_hdr = embedded_payload(temp_wrb);
if (wrb)
*wrb = temp_wrb;
}
if (status || addl_status) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Failed for "
"Subsys : %d Opcode : %d with "
"Status : %d and Extd_Status : %d\n",
ioctl_hdr->subsystem,
ioctl_hdr->opcode,
status, addl_status);
rc = -EAGAIN;
}
release_mcc_tag:
/* Release the MCC entry */
free_mcc_tag(&phba->ctrl, tag);
return rc;
}
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
{
spin_lock(&ctrl->mbox_lock);
......@@ -168,11 +249,24 @@ static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
compl->flags = 0;
}
/*
* be_mcc_compl_process()- Check the MBX comapletion status
* @ctrl: Function specific MBX data structure
* @compl: Completion status of MBX Command
*
* Check for the MBX completion status when BMBX method used
*
* return
* Success: Zero
* Failure: Non-Zero
**/
static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
struct be_mcc_compl *compl)
{
u16 compl_status, extd_status;
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
be_dws_le_to_cpu(compl, 4);
......@@ -184,7 +278,10 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : error in cmd completion: status(compl/extd)=%d/%d\n",
"BC_%d : error in cmd completion: "
"Subsystem : %d Opcode : %d "
"status(compl/extd)=%d/%d\n",
hdr->subsystem, hdr->opcode,
compl_status, extd_status);
return -EBUSY;
......@@ -314,11 +411,24 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
return status;
}
/* Wait till no more pending mcc requests are present */
/*
* be_mcc_wait_compl()- Wait for MBX completion
* @phba: driver private structure
*
* Wait till no more pending mcc requests are present
*
* return
* Success: 0
* Failure: Non-Zero
*
**/
static int be_mcc_wait_compl(struct beiscsi_hba *phba)
{
int i, status;
for (i = 0; i < mcc_timeout; i++) {
if (beiscsi_error(phba))
return -EIO;
status = beiscsi_process_mcc(phba);
if (status)
return status;
......@@ -330,51 +440,83 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
if (i == mcc_timeout) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : mccq poll timed out\n");
"BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
beiscsi_ue_detect(phba);
return -EBUSY;
}
return 0;
}
/* Notify MCC requests and wait for completion */
/*
* be_mcc_notify_wait()- Notify and wait for Compl
* @phba: driver private structure
*
* Notify MCC requests and wait for completion
*
* return
* Success: 0
* Failure: Non-Zero
**/
int be_mcc_notify_wait(struct beiscsi_hba *phba)
{
be_mcc_notify(phba);
return be_mcc_wait_compl(phba);
}
/*
* be_mbox_db_ready_wait()- Check ready status
* @ctrl: Function specific MBX data structure
*
* Check for the ready status of FW to send BMBX
* commands to adapter.
*
* return
* Success: 0
* Failure: Non-Zero
**/
static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
{
#define long_delay 2000
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
int cnt = 0, wait = 5; /* in usecs */
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
int wait = 0;
u32 ready;
do {
if (beiscsi_error(phba))
return -EIO;
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
if (ready)
break;
if (cnt > 12000000) {
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
if (wait > BEISCSI_HOST_MBX_TIMEOUT) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : mbox_db poll timed out\n");
"BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
beiscsi_ue_detect(phba);
return -EBUSY;
}
if (cnt > 50) {
wait = long_delay;
mdelay(long_delay / 1000);
} else
udelay(wait);
cnt += wait;
mdelay(1);
wait++;
} while (true);
return 0;
}
/*
* be_mbox_notify: Notify adapter of new BMBX command
* @ctrl: Function specific MBX data structure
*
* Ring doorbell to inform adapter of a BMBX command
* to process
*
* return
* Success: 0
* Failure: Non-Zero
**/
int be_mbox_notify(struct be_ctrl_info *ctrl)
{
int status;
......@@ -391,13 +533,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
iowrite32(val, db);
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : be_mbox_db_ready_wait failed\n");
if (status)
return status;
}
val = 0;
val &= ~MPU_MAILBOX_DB_RDY_MASK;
val &= ~MPU_MAILBOX_DB_HI_MASK;
......@@ -405,13 +543,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
iowrite32(val, db);
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : be_mbox_db_ready_wait failed\n");
if (status)
return status;
}
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, &mbox->compl);
be_mcc_compl_use(compl);
......@@ -499,7 +633,7 @@ void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
req_hdr->opcode = opcode;
req_hdr->subsystem = subsystem;
req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
req_hdr->timeout = 120;
req_hdr->timeout = BEISCSI_FW_MBX_TIMEOUT;
}
static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
......@@ -649,18 +783,34 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
OPCODE_COMMON_CQ_CREATE, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
if (chip_skh_r(ctrl->pdev)) {
req->hdr.version = MBX_CMD_VER2;
req->page_size = 1;
AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
ctxt, coalesce_wm);
AMAP_SET_BITS(struct amap_cq_context_v2, nodelay,
ctxt, no_delay);
AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
__ilog2_u32(cq->len / 256));
AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context_v2, armed, ctxt, 1);
} else {
AMAP_SET_BITS(struct amap_cq_context, coalescwm,
ctxt, coalesce_wm);
AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
__ilog2_u32(cq->len / 256));
AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
PCI_FUNC(ctrl->pdev->devfn));
}
AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
__ilog2_u32(cq->len / 256));
AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
PCI_FUNC(ctrl->pdev->devfn));
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -57,6 +57,16 @@ struct be_mcc_wrb {
#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
#define CQE_STATUS_EXTD_MASK 0xFFFF
#define CQE_STATUS_EXTD_SHIFT 16 /* bits 0 - 15 */
#define CQE_STATUS_ADDL_MASK 0xFF00
#define CQE_STATUS_MASK 0xFF
#define CQE_STATUS_ADDL_SHIFT 0x08
#define CQE_STATUS_WRB_MASK 0xFF0000
#define CQE_STATUS_WRB_SHIFT 16
#define BEISCSI_HOST_MBX_TIMEOUT (110 * 1000)
#define BEISCSI_FW_MBX_TIMEOUT 100
/* MBOX Command VER */
#define MBX_CMD_VER2 0x02
struct be_mcc_compl {
u32 status; /* dword 0 */
......@@ -183,7 +193,8 @@ struct be_cmd_req_hdr {
u8 domain; /* dword 0 */
u32 timeout; /* dword 1 */
u32 request_length; /* dword 2 */
u32 rsvd0; /* dword 3 */
u8 version; /* dword 3 */
u8 rsvd0[3]; /* dword 3 */
};
struct be_cmd_resp_hdr {
......@@ -483,10 +494,28 @@ struct amap_cq_context {
u8 rsvd5[32]; /* dword 3 */
} __packed;
struct amap_cq_context_v2 {
u8 rsvd0[12]; /* dword 0 */
u8 coalescwm[2]; /* dword 0 */
u8 nodelay; /* dword 0 */
u8 rsvd1[12]; /* dword 0 */
u8 count[2]; /* dword 0 */
u8 valid; /* dword 0 */
u8 rsvd2; /* dword 0 */
u8 eventable; /* dword 0 */
u8 eqid[16]; /* dword 1 */
u8 rsvd3[15]; /* dword 1 */
u8 armed; /* dword 1 */
u8 cqecount[16];/* dword 2 */
u8 rsvd4[16]; /* dword 2 */
u8 rsvd5[32]; /* dword 3 */
};
struct be_cmd_req_cq_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
u16 rsvd0;
u8 page_size;
u8 rsvd0;
u8 context[sizeof(struct amap_cq_context) / 8];
struct phys_addr pages[4];
} __packed;
......@@ -663,6 +692,9 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb, void *cmd_va);
/*ISCSI Functuions */
int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
......@@ -804,6 +836,59 @@ struct amap_sol_cqe_ring {
u8 valid; /* dword 3 */
} __packed;
struct amap_sol_cqe_v2 {
u8 hw_sts[8]; /* dword 0 */
u8 i_sts[8]; /* dword 0 */
u8 wrb_index[16]; /* dword 0 */
u8 i_exp_cmd_sn[32]; /* dword 1 */
u8 code[6]; /* dword 2 */
u8 cmd_cmpl; /* dword 2 */
u8 rsvd0; /* dword 2 */
u8 i_cmd_wnd[8]; /* dword 2 */
u8 cid[13]; /* dword 2 */
u8 u; /* dword 2 */
u8 o; /* dword 2 */
u8 s; /* dword 2 */
u8 i_res_cnt[31]; /* dword 3 */
u8 valid; /* dword 3 */
} __packed;
struct common_sol_cqe {
u32 exp_cmdsn;
u32 res_cnt;
u16 wrb_index;
u16 cid;
u8 hw_sts;
u8 cmd_wnd;
u8 res_flag; /* the s feild of structure */
u8 i_resp; /* for skh if cmd_complete is set then i_sts is response */
u8 i_flags; /* for skh or the u and o feilds */
u8 i_sts; /* for skh if cmd_complete is not-set then i_sts is status */
};
/*** iSCSI ack/driver message completions ***/
struct amap_it_dmsg_cqe {
u8 ack_num[32]; /* DWORD 0 */
u8 pdu_bytes_rcvd[32]; /* DWORD 1 */
u8 code[6]; /* DWORD 2 */
u8 cid[10]; /* DWORD 2 */
u8 wrb_idx[8]; /* DWORD 2 */
u8 rsvd0[8]; /* DWORD 2*/
u8 rsvd1[31]; /* DWORD 3*/
u8 valid; /* DWORD 3 */
} __packed;
struct amap_it_dmsg_cqe_v2 {
u8 ack_num[32]; /* DWORD 0 */
u8 pdu_bytes_rcvd[32]; /* DWORD 1 */
u8 code[6]; /* DWORD 2 */
u8 rsvd0[10]; /* DWORD 2 */
u8 wrb_idx[16]; /* DWORD 2 */
u8 rsvd1[16]; /* DWORD 3 */
u8 cid[13]; /* DWORD 3 */
u8 rsvd2[2]; /* DWORD 3 */
u8 valid; /* DWORD 3 */
} __packed;
/**
......@@ -992,8 +1077,6 @@ struct be_cmd_get_all_if_id_req {
#define CONNECTION_UPLOAD_ABORT_WITH_SEQ 4 /* Abortive upload with reset,
* sequence number by driver */
/* Returns byte size of given field with a structure. */
/* Returns the number of items in the field array. */
#define BE_NUMBER_OF_FIELD(_type_, _field_) \
(FIELD_SIZEOF(_type_, _field_)/sizeof((((_type_ *)0)->_field_[0])))\
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -531,9 +531,9 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
break;
case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
if (!if_info.dhcp_state)
len = sprintf(buf, "static");
len = sprintf(buf, "static\n");
else
len = sprintf(buf, "dhcp");
len = sprintf(buf, "dhcp\n");
break;
case ISCSI_NET_PARAM_IPV4_SUBNET:
len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
......@@ -541,7 +541,7 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
case ISCSI_NET_PARAM_VLAN_ENABLED:
len = sprintf(buf, "%s\n",
(if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
? "Disabled" : "Enabled");
? "Disabled\n" : "Enabled\n");
break;
case ISCSI_NET_PARAM_VLAN_ID:
if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
......@@ -586,7 +586,7 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface,
len = be2iscsi_get_if_param(phba, iface, param, buf);
break;
case ISCSI_NET_PARAM_IFACE_ENABLE:
len = sprintf(buf, "enabled");
len = sprintf(buf, "enabled\n");
break;
case ISCSI_NET_PARAM_IPV4_GW:
memset(&gateway, 0, sizeof(gateway));
......@@ -690,11 +690,9 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
{
int rc;
unsigned int tag, wrb_num;
unsigned short status, extd_status;
unsigned int tag;
struct be_mcc_wrb *wrb;
struct be_cmd_hba_name *resp;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
tag = be_cmd_get_initname(phba);
if (!tag) {
......@@ -702,26 +700,16 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
"BS_%d : Getting Initiator Name Failed\n");
return -EBUSY;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
}
if (status || extd_status) {
rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : MailBox Command Failed with "
"status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
"BS_%d : Initiator Name MBX Failed\n");
return rc;
}
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
resp = embedded_payload(wrb);
rc = sprintf(buf, "%s\n", resp->initiator_name);
return rc;
......@@ -731,7 +719,6 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
* beiscsi_get_port_state - Get the Port State
* @shost : pointer to scsi_host structure
*
* returns number of bytes
*/
static void beiscsi_get_port_state(struct Scsi_Host *shost)
{
......@@ -750,13 +737,12 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost)
*/
static int beiscsi_get_port_speed(struct Scsi_Host *shost)
{
unsigned int tag, wrb_num;
unsigned short status, extd_status;
int rc;
unsigned int tag;
struct be_mcc_wrb *wrb;
struct be_cmd_ntwk_link_status_resp *resp;
struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct iscsi_cls_host *ihost = shost->shost_data;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
tag = be_cmd_get_port_speed(phba);
if (!tag) {
......@@ -764,26 +750,14 @@ static int beiscsi_get_port_speed(struct Scsi_Host *shost)
"BS_%d : Getting Port Speed Failed\n");
return -EBUSY;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
}
rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : MailBox Command Failed with "
"status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
"BS_%d : Port Speed MBX Failed\n");
return rc;
}
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
resp = embedded_payload(wrb);
switch (resp->mac_speed) {
......@@ -937,6 +911,14 @@ static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
session->initial_r2t_en);
AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
session->imm_data_en);
AMAP_SET_BITS(struct amap_beiscsi_offload_params,
data_seq_inorder, params,
session->dataseq_inorder_en);
AMAP_SET_BITS(struct amap_beiscsi_offload_params,
pdu_seq_inorder, params,
session->pdu_inorder_en);
AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params,
session->max_r2t);
AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
(conn->exp_statsn - 1));
}
......@@ -1027,12 +1009,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
{
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
struct beiscsi_hba *phba = beiscsi_ep->phba;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
struct be_mcc_wrb *wrb;
struct tcp_connect_and_offload_out *ptcpcnct_out;
unsigned short status, extd_status;
struct be_dma_mem nonemb_cmd;
unsigned int tag, wrb_num;
unsigned int tag;
int ret = -ENOMEM;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
......@@ -1084,35 +1064,26 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
return -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
}
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
ret = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (ret) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : mgmt_open_connection Failed"
" status = %d extd_status = %d\n",
status, extd_status);
"BS_%d : mgmt_open_connection Failed");
free_mcc_tag(&phba->ctrl, tag);
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
goto free_ep;
} else {
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
ptcpcnct_out = embedded_payload(wrb);
beiscsi_ep = ep->dd_data;
beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
beiscsi_ep->cid_vld = 1;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : mgmt_open_connection Success\n");
}
ptcpcnct_out = embedded_payload(wrb);
beiscsi_ep = ep->dd_data;
beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
beiscsi_ep->cid_vld = 1;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : mgmt_open_connection Success\n");
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
return 0;
......@@ -1150,8 +1121,8 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
if (phba->state != BE_ADAPTER_UP) {
ret = -EBUSY;
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : The Adapter state is Not UP\n");
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
"BS_%d : The Adapter Port state is Down!!!\n");
return ERR_PTR(ret);
}
......@@ -1216,11 +1187,9 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
beiscsi_ep->ep_cid);
ret = -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
ret = beiscsi_mccq_compl(phba, tag, NULL, NULL);
return ret;
}
......@@ -1281,12 +1250,9 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : mgmt_invalidate_connection Failed for cid=%d\n",
beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
beiscsi_mccq_compl(phba, tag, NULL, NULL);
beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
beiscsi_free_ep(beiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......
此差异已折叠。
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -36,12 +36,13 @@
#include "be.h"
#define DRV_NAME "be2iscsi"
#define BUILD_STR "4.4.58.0"
#define BUILD_STR "10.0.272.0"
#define BE_NAME "Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver"
#define BE_VENDOR_ID 0x19A2
#define ELX_VENDOR_ID 0x10DF
/* DEVICE ID's for BE2 */
#define BE_DEVICE_ID1 0x212
#define OC_DEVICE_ID1 0x702
......@@ -51,6 +52,9 @@
#define BE_DEVICE_ID2 0x222
#define OC_DEVICE_ID3 0x712
/* DEVICE ID for SKH */
#define OC_SKH_ID1 0x722
#define BE2_IO_DEPTH 1024
#define BE2_MAX_SESSIONS 256
#define BE2_CMDS_PER_CXN 128
......@@ -60,7 +64,11 @@
#define BE2_DEFPDU_HDR_SZ 64
#define BE2_DEFPDU_DATA_SZ 8192
#define MAX_CPUS 31
#define MAX_CPUS 64
#define BEISCSI_MAX_NUM_CPUS 7
#define OC_SKH_MAX_NUM_CPUS 63
#define BEISCSI_SGLIST_ELEMENTS 30
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
......@@ -257,6 +265,7 @@ struct invalidate_command_table {
unsigned short cid;
} __packed;
#define chip_skh_r(pdev) (pdev->device == OC_SKH_ID1)
struct beiscsi_hba {
struct hba_parameters params;
struct hwi_controller *phwi_ctrlr;
......@@ -270,12 +279,11 @@ struct beiscsi_hba {
struct be_bus_address pci_pa; /* CSR */
/* PCI representation of our HBA */
struct pci_dev *pcidev;
unsigned int state;
unsigned short asic_revision;
unsigned int num_cpus;
unsigned int nxt_cqid;
struct msix_entry msix_entries[MAX_CPUS + 1];
char *msi_name[MAX_CPUS + 1];
struct msix_entry msix_entries[MAX_CPUS];
char *msi_name[MAX_CPUS];
bool msix_enabled;
struct be_mem_descriptor *init_mem;
......@@ -325,12 +333,14 @@ struct beiscsi_hba {
spinlock_t cid_lock;
} fw_config;
unsigned int state;
bool fw_timeout;
bool ue_detected;
struct delayed_work beiscsi_hw_check_task;
u8 mac_address[ETH_ALEN];
unsigned short todo_cq;
unsigned short todo_mcc_cq;
char wq_name[20];
struct workqueue_struct *wq; /* The actuak work queue */
struct work_struct work_cqs; /* The work being queued */
struct be_ctrl_info ctrl;
unsigned int generation;
unsigned int interface_handle;
......@@ -338,7 +348,10 @@ struct beiscsi_hba {
struct invalidate_command_table inv_tbl[128];
unsigned int attr_log_enable;
int (*iotask_fn)(struct iscsi_task *,
struct scatterlist *sg,
uint32_t num_sg, uint32_t xferlen,
uint32_t writedir);
};
struct beiscsi_session {
......@@ -410,6 +423,9 @@ struct beiscsi_io_task {
struct be_cmd_bhs *cmd_bhs;
struct be_bus_address bhs_pa;
unsigned short bhs_len;
dma_addr_t mtask_addr;
uint32_t mtask_data_count;
uint8_t wrb_type;
};
struct be_nonio_bhs {
......@@ -457,6 +473,9 @@ struct beiscsi_offload_params {
#define OFFLD_PARAMS_HDE 0x00000008
#define OFFLD_PARAMS_IR2T 0x00000010
#define OFFLD_PARAMS_IMD 0x00000020
#define OFFLD_PARAMS_DATA_SEQ_INORDER 0x00000040
#define OFFLD_PARAMS_PDU_SEQ_INORDER 0x00000080
#define OFFLD_PARAMS_MAX_R2T 0x00FFFF00
/**
* Pseudo amap definition in which each bit of the actual structure is defined
......@@ -471,7 +490,10 @@ struct amap_beiscsi_offload_params {
u8 hde[1];
u8 ir2t[1];
u8 imd[1];
u8 pad[26];
u8 data_seq_inorder[1];
u8 pdu_seq_inorder[1];
u8 max_r2t[16];
u8 pad[8];
u8 exp_statsn[32];
};
......@@ -569,6 +591,20 @@ struct amap_i_t_dpdu_cqe {
u8 valid;
} __packed;
struct amap_i_t_dpdu_cqe_v2 {
u8 db_addr_hi[32]; /* DWORD 0 */
u8 db_addr_lo[32]; /* DWORD 1 */
u8 code[6]; /* DWORD 2 */
u8 num_cons; /* DWORD 2*/
u8 rsvd0[8]; /* DWORD 2 */
u8 dpl[17]; /* DWORD 2 */
u8 index[16]; /* DWORD 3 */
u8 cid[13]; /* DWORD 3 */
u8 rsvd1; /* DWORD 3 */
u8 final; /* DWORD 3 */
u8 valid; /* DWORD 3 */
} __packed;
#define CQE_VALID_MASK 0x80000000
#define CQE_CODE_MASK 0x0000003F
#define CQE_CID_MASK 0x0000FFC0
......@@ -617,6 +653,11 @@ struct iscsi_wrb {
} __packed;
#define WRB_TYPE_MASK 0xF0000000
#define SKH_WRB_TYPE_OFFSET 27
#define BE_WRB_TYPE_OFFSET 28
#define ADAPTER_SET_WRB_TYPE(pwrb, wrb_type, type_offset) \
(pwrb->dw[0] |= (wrb_type << type_offset))
/**
* Pseudo amap definition in which each bit of the actual structure is defined
......@@ -663,12 +704,57 @@ struct amap_iscsi_wrb {
} __packed;
struct amap_iscsi_wrb_v2 {
u8 r2t_exp_dtl[25]; /* DWORD 0 */
u8 rsvd0[2]; /* DWORD 0*/
u8 type[5]; /* DWORD 0 */
u8 ptr2nextwrb[8]; /* DWORD 1 */
u8 wrb_idx[8]; /* DWORD 1 */
u8 lun[16]; /* DWORD 1 */
u8 sgl_idx[16]; /* DWORD 2 */
u8 ref_sgl_icd_idx[16]; /* DWORD 2 */
u8 exp_data_sn[32]; /* DWORD 3 */
u8 iscsi_bhs_addr_hi[32]; /* DWORD 4 */
u8 iscsi_bhs_addr_lo[32]; /* DWORD 5 */
u8 cq_id[16]; /* DWORD 6 */
u8 rsvd1[16]; /* DWORD 6 */
u8 cmdsn_itt[32]; /* DWORD 7 */
u8 sge0_addr_hi[32]; /* DWORD 8 */
u8 sge0_addr_lo[32]; /* DWORD 9 */
u8 sge0_offset[24]; /* DWORD 10 */
u8 rsvd2[7]; /* DWORD 10 */
u8 sge0_last; /* DWORD 10 */
u8 sge0_len[17]; /* DWORD 11 */
u8 rsvd3[7]; /* DWORD 11 */
u8 diff_enbl; /* DWORD 11 */
u8 u_run; /* DWORD 11 */
u8 o_run; /* DWORD 11 */
u8 invalid; /* DWORD 11 */
u8 dsp; /* DWORD 11 */
u8 dmsg; /* DWORD 11 */
u8 rsvd4; /* DWORD 11 */
u8 lt; /* DWORD 11 */
u8 sge1_addr_hi[32]; /* DWORD 12 */
u8 sge1_addr_lo[32]; /* DWORD 13 */
u8 sge1_r2t_offset[24]; /* DWORD 14 */
u8 rsvd5[7]; /* DWORD 14 */
u8 sge1_last; /* DWORD 14 */
u8 sge1_len[17]; /* DWORD 15 */
u8 rsvd6[15]; /* DWORD 15 */
} __packed;
struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
void
free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
void beiscsi_process_all_cqs(struct work_struct *work);
static inline bool beiscsi_error(struct beiscsi_hba *phba)
{
return phba->ue_detected || phba->fw_timeout;
}
struct pdu_nop_out {
u32 dw[12];
};
......@@ -728,6 +814,7 @@ struct iscsi_target_context_update_wrb {
* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field
*/
#define BE_TGT_CTX_UPDT_CMD 0x07
struct amap_iscsi_target_context_update_wrb {
u8 lun[14]; /* DWORD 0 */
u8 lt; /* DWORD 0 */
......@@ -773,6 +860,47 @@ struct amap_iscsi_target_context_update_wrb {
} __packed;
#define BEISCSI_MAX_RECV_DATASEG_LEN (64 * 1024)
#define BEISCSI_MAX_CXNS 1
struct amap_iscsi_target_context_update_wrb_v2 {
u8 max_burst_length[24]; /* DWORD 0 */
u8 rsvd0[3]; /* DWORD 0 */
u8 type[5]; /* DWORD 0 */
u8 ptr2nextwrb[8]; /* DWORD 1 */
u8 wrb_idx[8]; /* DWORD 1 */
u8 rsvd1[16]; /* DWORD 1 */
u8 max_send_data_segment_length[24]; /* DWORD 2 */
u8 rsvd2[8]; /* DWORD 2 */
u8 first_burst_length[24]; /* DWORD 3 */
u8 rsvd3[8]; /* DOWRD 3 */
u8 max_r2t[16]; /* DWORD 4 */
u8 rsvd4[10]; /* DWORD 4 */
u8 hde; /* DWORD 4 */
u8 dde; /* DWORD 4 */
u8 erl[2]; /* DWORD 4 */
u8 imd; /* DWORD 4 */
u8 ir2t; /* DWORD 4 */
u8 stat_sn[32]; /* DWORD 5 */
u8 rsvd5[32]; /* DWORD 6 */
u8 rsvd6[32]; /* DWORD 7 */
u8 max_recv_dataseg_len[24]; /* DWORD 8 */
u8 rsvd7[8]; /* DWORD 8 */
u8 rsvd8[32]; /* DWORD 9 */
u8 rsvd9[32]; /* DWORD 10 */
u8 max_cxns[16]; /* DWORD 11 */
u8 rsvd10[11]; /* DWORD 11*/
u8 invld; /* DWORD 11 */
u8 rsvd11;/* DWORD 11*/
u8 dmsg; /* DWORD 11 */
u8 data_seq_inorder; /* DWORD 11 */
u8 pdu_seq_inorder; /* DWORD 11 */
u8 rsvd12[32]; /*DWORD 12 */
u8 rsvd13[32]; /* DWORD 13 */
u8 rsvd14[32]; /* DWORD 14 */
u8 rsvd15[32]; /* DWORD 15 */
} __packed;
struct be_ring {
u32 pages; /* queue size in pages */
u32 id; /* queue id assigned by beklib */
......@@ -837,7 +965,7 @@ struct hwi_context_memory {
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
struct be_eq_obj be_eq[MAX_CPUS];
struct be_queue_info be_cq[MAX_CPUS];
struct be_queue_info be_cq[MAX_CPUS - 1];
struct be_queue_info be_def_hdrq;
struct be_queue_info be_def_dataq;
......
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -22,6 +22,138 @@
#include <scsi/scsi_bsg_iscsi.h>
#include "be_mgmt.h"
#include "be_iscsi.h"
#include "be_main.h"
/* UE Status Low CSR */
static const char * const desc_ue_status_low[] = {
"CEV",
"CTX",
"DBUF",
"ERX",
"Host",
"MPU",
"NDMA",
"PTC ",
"RDMA ",
"RXF ",
"RXIPS ",
"RXULP0 ",
"RXULP1 ",
"RXULP2 ",
"TIM ",
"TPOST ",
"TPRE ",
"TXIPS ",
"TXULP0 ",
"TXULP1 ",
"UC ",
"WDMA ",
"TXULP2 ",
"HOST1 ",
"P0_OB_LINK ",
"P1_OB_LINK ",
"HOST_GPIO ",
"MBOX ",
"AXGMAC0",
"AXGMAC1",
"JTAG",
"MPU_INTPEND"
};
/* UE Status High CSR */
static const char * const desc_ue_status_hi[] = {
"LPCMEMHOST",
"MGMT_MAC",
"PCS0ONLINE",
"MPU_IRAM",
"PCS1ONLINE",
"PCTL0",
"PCTL1",
"PMEM",
"RR",
"TXPB",
"RXPP",
"XAUI",
"TXP",
"ARM",
"IPC",
"HOST2",
"HOST3",
"HOST4",
"HOST5",
"HOST6",
"HOST7",
"HOST8",
"HOST9",
"NETC",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown"
};
/*
* beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
* @phba: Driver priv structure
*
* Read registers linked to UE and check for the UE status
**/
void beiscsi_ue_detect(struct beiscsi_hba *phba)
{
uint32_t ue_hi = 0, ue_lo = 0;
uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
uint8_t i = 0;
if (phba->ue_detected)
return;
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_LOW, &ue_lo);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_MASK_LOW,
&ue_mask_lo);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_HIGH,
&ue_hi);
pci_read_config_dword(phba->pcidev,
PCICFG_UE_STATUS_MASK_HI,
&ue_mask_hi);
ue_lo = (ue_lo & ~ue_mask_lo);
ue_hi = (ue_hi & ~ue_mask_hi);
if (ue_lo || ue_hi) {
phba->ue_detected = true;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : Error detected on the adapter\n");
}
if (ue_lo) {
for (i = 0; ue_lo; ue_lo >>= 1, i++) {
if (ue_lo & 1)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG,
"BG_%d : UE_LOW %s bit set\n",
desc_ue_status_low[i]);
}
}
if (ue_hi) {
for (i = 0; ue_hi; ue_hi >>= 1, i++) {
if (ue_hi & 1)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG,
"BG_%d : UE_HIGH %s bit set\n",
desc_ue_status_hi[i]);
}
}
}
/**
* mgmt_reopen_session()- Reopen a session based on reopen_type
......@@ -575,13 +707,20 @@ unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
return status;
}
/*
* mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
* @phba: Driver priv structure
* @nonemb_cmd: Address of the MBX command issued
* @resp_buf: Buffer to copy the MBX cmd response
* @resp_buf_len: respone lenght to be copied
*
**/
static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
struct be_dma_mem *nonemb_cmd, void *resp_buf,
int resp_buf_len)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
unsigned short status, extd_status;
struct be_sge *sge;
unsigned int tag;
int rc = 0;
......@@ -599,31 +738,25 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
sge->len = cpu_to_le32(nonemb_cmd->size);
be_mcc_notify(phba);
spin_unlock(&ctrl->mbox_lock);
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : mgmt_exec_nonemb_cmd Failed status = %d"
"extd_status = %d\n", status, extd_status);
"BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
rc = -EIO;
goto free_tag;
goto free_cmd;
}
if (resp_buf)
memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
free_tag:
free_mcc_tag(&phba->ctrl, tag);
free_cmd:
pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
nonemb_cmd->va, nonemb_cmd->dma);
......@@ -1009,10 +1142,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
{
struct be_cmd_get_boot_target_resp *boot_resp;
struct be_mcc_wrb *wrb;
unsigned int tag, wrb_num;
unsigned int tag;
uint8_t boot_retry = 3;
unsigned short status, extd_status;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
int rc;
do {
/* Get the Boot Target Session Handle and Count*/
......@@ -1022,24 +1154,16 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
"BG_%d : Getting Boot Target Info Failed\n");
return -EAGAIN;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
}
rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_get_boot_target Failed"
" status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
"BG_%d : MBX CMD get_boot_target Failed\n");
return -EBUSY;
}
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
boot_resp = embedded_payload(wrb);
/* Check if the there are any Boot targets configured */
......@@ -1064,24 +1188,15 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_reopen_session Failed\n");
return -EAGAIN;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
}
rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_reopen_session Failed"
" status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EBUSY;
"BG_%d : mgmt_reopen_session Failed");
return rc;
}
free_mcc_tag(&phba->ctrl, tag);
} while (--boot_retry);
/* Couldn't log into the boot target */
......@@ -1106,8 +1221,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
int mgmt_set_vlan(struct beiscsi_hba *phba,
uint16_t vlan_tag)
{
unsigned int tag, wrb_num;
unsigned short status, extd_status;
int rc;
unsigned int tag;
struct be_mcc_wrb *wrb = NULL;
tag = be_cmd_set_vlan(phba, vlan_tag);
if (!tag) {
......@@ -1115,24 +1231,208 @@ int mgmt_set_vlan(struct beiscsi_hba *phba,
(BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
"BG_%d : VLAN Setting Failed\n");
return -EBUSY;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
}
if (status || extd_status) {
rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
(BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
"BS_%d : status : %d extd_status : %d\n",
status, extd_status);
"BS_%d : VLAN MBX Cmd Failed\n");
return rc;
}
return rc;
}
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
/**
* beiscsi_drvr_ver_disp()- Display the driver Name and Version
* @dev: ptr to device not used.
* @attr: device attribute, not used.
* @buf: contains formatted text driver name and version
*
* return
* size of the formatted string
**/
ssize_t
beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
}
/**
* beiscsi_adap_family_disp()- Display adapter family.
* @dev: ptr to device to get priv structure
* @attr: device attribute, not used.
* @buf: contains formatted text driver name and version
*
* return
* size of the formatted string
**/
ssize_t
beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
char *buf)
{
uint16_t dev_id = 0;
struct Scsi_Host *shost = class_to_shost(dev);
struct beiscsi_hba *phba = iscsi_host_priv(shost);
dev_id = phba->pcidev->device;
switch (dev_id) {
case BE_DEVICE_ID1:
case OC_DEVICE_ID1:
case OC_DEVICE_ID2:
return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
break;
case BE_DEVICE_ID2:
case OC_DEVICE_ID3:
return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
break;
case OC_SKH_ID1:
return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
break;
default:
return snprintf(buf, PAGE_SIZE,
"Unkown Adapter Family: 0x%x\n", dev_id);
break;
}
}
free_mcc_tag(&phba->ctrl, tag);
return 0;
void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle,
struct be_mem_descriptor *mem_descr)
{
struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
memset(pwrb, 0, sizeof(*pwrb));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
max_send_data_segment_length, pwrb,
params->dw[offsetof(struct amap_beiscsi_offload_params,
max_send_data_segment_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
BE_TGT_CTX_UPDT_CMD);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
first_burst_length,
pwrb,
params->dw[offsetof(struct amap_beiscsi_offload_params,
first_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
erl) / 32] & OFFLD_PARAMS_ERL));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
exp_statsn) / 32] + 1));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
pwrb, pwrb_handle->wrb_index);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
max_burst_length, pwrb, params->dw[offsetof
(struct amap_beiscsi_offload_params,
max_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
pwrb, pwrb_handle->nxt_wrb_index);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
session_state, pwrb, 0);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
pwrb, 1);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
pwrb, 0);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
0);
mem_descr += ISCSI_MEM_GLOBAL_HEADER;
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
pad_buffer_addr_hi, pwrb,
mem_descr->mem_array[0].bus_address.u.a32.address_hi);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
pad_buffer_addr_lo, pwrb,
mem_descr->mem_array[0].bus_address.u.a32.address_lo);
}
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle)
{
struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
memset(pwrb, 0, sizeof(*pwrb));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
max_burst_length, pwrb, params->dw[offsetof
(struct amap_beiscsi_offload_params,
max_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_burst_length, pwrb, params->dw[offsetof
(struct amap_beiscsi_offload_params,
max_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
type, pwrb,
BE_TGT_CTX_UPDT_CMD);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
ptr2nextwrb,
pwrb, pwrb_handle->nxt_wrb_index);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
pwrb, pwrb_handle->wrb_index);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_send_data_segment_length, pwrb,
params->dw[offsetof(struct amap_beiscsi_offload_params,
max_send_data_segment_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
first_burst_length, pwrb,
params->dw[offsetof(struct amap_beiscsi_offload_params,
first_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_recv_dataseg_len, pwrb, BEISCSI_MAX_RECV_DATASEG_LEN);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_cxns, pwrb, BEISCSI_MAX_CXNS);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
erl) / 32] & OFFLD_PARAMS_ERL));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
ir2t, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
data_seq_inorder,
pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
data_seq_inorder) / 32] &
OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
pdu_seq_inorder,
pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
pdu_seq_inorder) / 32] &
OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
max_r2t) / 32] &
OFFLD_PARAMS_MAX_R2T) >> 8);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
pwrb,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
exp_statsn) / 32] + 1));
}
/**
* Copyright (C) 2005 - 2011 Emulex
* Copyright (C) 2005 - 2012 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
......@@ -30,6 +30,12 @@
#define IP_V6_LEN 16
#define IP_V4_LEN 4
/* UE Status and Mask register */
#define PCICFG_UE_STATUS_LOW 0xA0
#define PCICFG_UE_STATUS_HIGH 0xA4
#define PCICFG_UE_STATUS_MASK_LOW 0xA8
#define PCICFG_UE_STATUS_MASK_HI 0xAC
/**
* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field
......@@ -301,4 +307,19 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba);
int mgmt_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
ssize_t beiscsi_drvr_ver_disp(struct device *dev,
struct device_attribute *attr, char *buf);
ssize_t beiscsi_adap_family_disp(struct device *dev,
struct device_attribute *attr, char *buf);
void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle,
struct be_mem_descriptor *mem_descr);
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle);
void beiscsi_ue_detect(struct beiscsi_hba *phba);
#endif
......@@ -800,7 +800,7 @@ extern struct device_attribute *bnx2i_dev_attributes[];
/*
* Function Prototypes
*/
extern void bnx2i_identify_device(struct bnx2i_hba *hba);
extern void bnx2i_identify_device(struct bnx2i_hba *hba, struct cnic_dev *dev);
extern void bnx2i_ulp_init(struct cnic_dev *dev);
extern void bnx2i_ulp_exit(struct cnic_dev *dev);
......
......@@ -79,42 +79,33 @@ static struct notifier_block bnx2i_cpu_notifier = {
/**
* bnx2i_identify_device - identifies NetXtreme II device type
* @hba: Adapter structure pointer
* @cnic: Corresponding cnic device
*
* This function identifies the NX2 device type and sets appropriate
* queue mailbox register access method, 5709 requires driver to
* access MBOX regs using *bin* mode
*/
void bnx2i_identify_device(struct bnx2i_hba *hba)
void bnx2i_identify_device(struct bnx2i_hba *hba, struct cnic_dev *dev)
{
hba->cnic_dev_type = 0;
if ((hba->pci_did == PCI_DEVICE_ID_NX2_5706) ||
(hba->pci_did == PCI_DEVICE_ID_NX2_5706S))
set_bit(BNX2I_NX2_DEV_5706, &hba->cnic_dev_type);
else if ((hba->pci_did == PCI_DEVICE_ID_NX2_5708) ||
(hba->pci_did == PCI_DEVICE_ID_NX2_5708S))
set_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type);
else if ((hba->pci_did == PCI_DEVICE_ID_NX2_5709) ||
(hba->pci_did == PCI_DEVICE_ID_NX2_5709S)) {
set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type);
hba->mail_queue_access = BNX2I_MQ_BIN_MODE;
} else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57711 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57711E ||
hba->pci_did == PCI_DEVICE_ID_NX2_57712 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57712E ||
hba->pci_did == PCI_DEVICE_ID_NX2_57800 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57800_MF ||
hba->pci_did == PCI_DEVICE_ID_NX2_57800_VF ||
hba->pci_did == PCI_DEVICE_ID_NX2_57810 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57810_MF ||
hba->pci_did == PCI_DEVICE_ID_NX2_57810_VF ||
hba->pci_did == PCI_DEVICE_ID_NX2_57840 ||
hba->pci_did == PCI_DEVICE_ID_NX2_57840_MF ||
hba->pci_did == PCI_DEVICE_ID_NX2_57840_VF)
if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
if (hba->pci_did == PCI_DEVICE_ID_NX2_5706 ||
hba->pci_did == PCI_DEVICE_ID_NX2_5706S) {
set_bit(BNX2I_NX2_DEV_5706, &hba->cnic_dev_type);
} else if (hba->pci_did == PCI_DEVICE_ID_NX2_5708 ||
hba->pci_did == PCI_DEVICE_ID_NX2_5708S) {
set_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type);
} else if (hba->pci_did == PCI_DEVICE_ID_NX2_5709 ||
hba->pci_did == PCI_DEVICE_ID_NX2_5709S) {
set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type);
hba->mail_queue_access = BNX2I_MQ_BIN_MODE;
}
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type);
else
} else {
printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n",
hba->pci_did);
}
}
......
......@@ -808,7 +808,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
hba->pci_func = PCI_FUNC(hba->pcidev->devfn);
hba->pci_devno = PCI_SLOT(hba->pcidev->devfn);
bnx2i_identify_device(hba);
bnx2i_identify_device(hba, cnic);
bnx2i_setup_host_queue_size(hba, shost);
hba->reg_base = pci_resource_start(hba->pcidev, 0);
......
config SCSI_CHELSIO_FCOE
tristate "Chelsio Communications FCoE support"
depends on PCI && SCSI
select SCSI_FC_ATTRS
select FW_LOADER
help
This driver supports FCoE Offload functionality over
Chelsio T4-based 10Gb Converged Network Adapters.
For general information about Chelsio and our products, visit
our website at <http://www.chelsio.com>.
For customer support, please visit our customer support page at
<http://www.chelsio.com/support.html>.
Please send feedback to <linux-bugs@chelsio.com>.
To compile this driver as a module choose M here; the module
will be called csiostor.
#
## Chelsio FCoE driver
#
##
ccflags-y += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4
obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor.o
csiostor-objs := csio_attr.o csio_init.o csio_lnode.o csio_scsi.o \
csio_hw.o csio_isr.o csio_mb.o csio_rnode.o csio_wr.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -689,6 +689,7 @@ struct lpfc_hba {
#define LPFC_FCF_PRIORITY 2 /* Priority fcf failover */
uint32_t cfg_fcf_failover_policy;
uint32_t cfg_fcp_io_sched;
uint32_t cfg_fcp2_no_tgt_reset;
uint32_t cfg_cr_delay;
uint32_t cfg_cr_count;
uint32_t cfg_multi_ring_support;
......@@ -714,6 +715,7 @@ struct lpfc_hba {
uint32_t cfg_log_verbose;
uint32_t cfg_aer_support;
uint32_t cfg_sriov_nr_virtfn;
uint32_t cfg_request_firmware_upgrade;
uint32_t cfg_iocb_cnt;
uint32_t cfg_suppress_link_up;
#define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */
......
此差异已折叠。
......@@ -468,3 +468,4 @@ void lpfc_sli4_node_prep(struct lpfc_hba *);
int lpfc_sli4_xri_sgl_update(struct lpfc_hba *);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *);
int lpfc_sli4_request_firmware_update(struct lpfc_hba *, uint8_t);
......@@ -634,7 +634,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* Check for retry */
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
(irsp->un.ulpWord[4] && IOERR_PARAM_MASK) !=
(irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
IOERR_NO_RESOURCES)
vport->fc_ns_retry++;
......
......@@ -1182,8 +1182,6 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
sp->cmn.w2.r_a_tov = 0;
sp->cmn.virtual_fabric_support = 0;
sp->cls1.classValid = 0;
sp->cls2.seqDelivery = 1;
sp->cls3.seqDelivery = 1;
if (sp->cmn.fcphLow < FC_PH3)
sp->cmn.fcphLow = FC_PH3;
if (sp->cmn.fcphHigh < FC_PH3)
......@@ -1198,7 +1196,13 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* Set the fcfi to the fcfi we registered with */
elsiocb->iocb.ulpContext = phba->fcf.fcfi;
}
/* Can't do SLI4 class2 without support sequence coalescing */
sp->cls2.classValid = 0;
sp->cls2.seqDelivery = 0;
} else {
/* Historical, setting sequential-delivery bit for SLI3 */
sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
sp->cls3.seqDelivery = (sp->cls3.classValid) ? 1 : 0;
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
sp->cmn.request_multiple_Nport = 1;
/* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
......
......@@ -3219,6 +3219,9 @@ struct wqe_common {
#define wqe_dif_SHIFT 0
#define wqe_dif_MASK 0x00000003
#define wqe_dif_WORD word7
#define LPFC_WQE_DIF_PASSTHRU 1
#define LPFC_WQE_DIF_STRIP 2
#define LPFC_WQE_DIF_INSERT 3
#define wqe_ct_SHIFT 2
#define wqe_ct_MASK 0x00000003
#define wqe_ct_WORD word7
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -69,7 +69,9 @@ struct lpfc_iocbq {
#define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */
#define DSS_SECURITY_OP 0x100 /* security IO */
#define LPFC_IO_ON_TXCMPLQ 0x200 /* The IO is still on the TXCMPLQ */
#define LPFC_IO_DIF 0x400 /* T10 DIF IO */
#define LPFC_IO_DIF_PASS 0x400 /* T10 DIF IO pass-thru prot */
#define LPFC_IO_DIF_STRIP 0x800 /* T10 DIF IO strip prot */
#define LPFC_IO_DIF_INSERT 0x1000 /* T10 DIF IO insert prot */
#define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */
#define LPFC_FIP_ELS_ID_SHIFT 14
......
此差异已折叠。
......@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "8.3.35"
#define LPFC_DRIVER_VERSION "8.3.36"
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册