[PATCH 3/3] ipr: Avoid target_destroy accessing memory after it was freed

2013-03-14 Thread wenxiong
Defined target_ids,array_ids and vsets_ids as unsigned long to avoid
target_destroy accessing memory after it was freed. 


Signed-off-by: Wen Xiong 
---
 drivers/scsi/ipr.c |   16 
 drivers/scsi/ipr.h |6 +++---
 2 files changed, 3 insertions(+), 19 deletions(-)

Index: b/drivers/scsi/ipr.c
===
--- a/drivers/scsi/ipr.c2013-03-14 13:16:03.398966326 -0500
+++ b/drivers/scsi/ipr.c2013-03-14 13:17:04.828022126 -0500
@@ -8972,19 +8972,6 @@ static int ipr_alloc_mem(struct ipr_ioa_
if (!ioa_cfg->res_entries)
goto out;
 
-   if (ioa_cfg->sis64) {
-   ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
- 
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
-   ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
-
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
-   ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
-   
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
-
-   if (!ioa_cfg->target_ids || !ioa_cfg->array_ids
-   || !ioa_cfg->vset_ids)
-   goto out_free_res_entries;
-   }
-
for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
list_add_tail(&ioa_cfg->res_entries[i].queue, 
&ioa_cfg->free_res_q);
ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
@@ -9081,9 +9068,6 @@ out_free_vpd_cbs:
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
 out_free_res_entries:
kfree(ioa_cfg->res_entries);
-   kfree(ioa_cfg->target_ids);
-   kfree(ioa_cfg->array_ids);
-   kfree(ioa_cfg->vset_ids);
goto out;
 }
 
Index: b/drivers/scsi/ipr.h
===
--- a/drivers/scsi/ipr.h2013-03-14 11:49:21.408965542 -0500
+++ b/drivers/scsi/ipr.h2013-03-14 13:16:20.131452448 -0500
@@ -1440,9 +1440,9 @@ struct ipr_ioa_cfg {
/*
 * Bitmaps for SIS64 generated target values
 */
-   unsigned long *target_ids;
-   unsigned long *array_ids;
-   unsigned long *vset_ids;
+   unsigned long target_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
+   unsigned long array_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
+   unsigned long vset_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
 
u16 type; /* CCIN of the card */
 

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] Fixed several ipr bugs when bring up an ipr adapter

2013-03-14 Thread wenxiong
-- 
Hi All,

These patches fixed several ipr bugs when brining up new adapters.

Let me know if you have any questions.

Thanks,
Wendy
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] ipr: dlpar failed when adding an adapter back

2013-03-14 Thread wenxiong
Reinitialize resource queue prior to freeing resource entries to ensure they
are not referenced. This fixes an issue with target_destoy accessing memory
after it was freed.

Signed-off-by: Wen Xiong 
---
 drivers/scsi/ipr.c |1 +
 1 file changed, 1 insertion(+)

Index: b/drivers/scsi/ipr.c
===
--- a/drivers/scsi/ipr.c2013-03-14 13:15:46.289276262 -0500
+++ b/drivers/scsi/ipr.c2013-03-14 13:16:03.398966326 -0500
@@ -9728,6 +9728,7 @@ static void __ipr_remove(struct pci_dev 
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
flush_work(&ioa_cfg->work_q);
+   INIT_LIST_HEAD(&ioa_cfg->used_res_q);
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 
spin_lock(&ipr_driver_lock);

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] ipr: fix addition of abort command to HRRQ free queue

2013-03-14 Thread wenxiong
From: Kleber Sacilotto de Souza 

The abort command issued by ipr_cancel_op() is being added to the wrong
HRRQ free queue after the command returns. Fix it by using the HRRQ
pointer in the ipr command struct itself.

Signed-off-by: Kleber Sacilotto de Souza 
Signed-off-by: Wen Xiong 
---
 drivers/scsi/ipr.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/drivers/scsi/ipr.c
===
--- a/drivers/scsi/ipr.c2013-03-14 11:49:29.819030052 -0500
+++ b/drivers/scsi/ipr.c2013-03-14 13:15:46.289276262 -0500
@@ -5148,7 +5148,7 @@ static int ipr_cancel_op(struct scsi_cmn
ipr_trace;
}
 
-   list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q);
+   list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
if (!ipr_is_naca_model(res))
res->needs_sync_complete = 1;
 

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] scsi_transport_fc: Make 'port_state' writeable

2013-03-14 Thread Steffen Maier

Just for my understanding:
So this is a bit like writing 0 into the failed attribute of a zfcp_port 
in sysfs (zfcp_sysfs_port_failed_store()) which forces a port reopen 
recovery including a sequence of fc_remote_port_delete and 
fc_remote_port_add?
If so, it sounds good to have this functionality for any FC LLD in 
common code.
(And I can think about deprecating parts of zfcp code, next we could 
consider the same for zfcp's forced LUN and adapter recovery or maybe 
this already exists as sdev's writable state attribute and the adapter 
recovery can be performed manually by walking all fc_rports writing 
their port_state.)


On 01/15/2013 04:02 PM, Hannes Reinecke wrote:

Multipath might detect a path down even though the LLDD
hasn't registered a link down event.
This patch makes the 'port_state' FC attribute writeable
to enforce a link down scenario in these cases, allowing
for a fast failover to the remaining ports.

Cc: Chad Dupuis 
Cc: Andrew Vasquez 
Cc: James Smart 
Cc: James Bottomley 
Cc: Mike Christie 
Signed-off-by: Hannes Reinecke 

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 5e1c6dd..4d28ee5 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -42,6 +42,8 @@
  #include "scsi_priv.h"
  #include "scsi_transport_fc_internal.h"

+static void fc_flush_devloss(struct Scsi_Host *shost);
+static void fc_flush_work(struct Scsi_Host *shost);
  static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
  static void fc_vport_sched_delete(struct work_struct *work);
  static int fc_vport_setup(struct Scsi_Host *shost, int channel,
@@ -949,7 +951,76 @@ show_fc_rport_roles (struct device *dev, struct 
device_attribute *attr,
  static FC_DEVICE_ATTR(rport, roles, S_IRUGO,
show_fc_rport_roles, NULL);

-fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
+static ssize_t
+store_fc_rport_port_state(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+   unsigned long flags;
+   struct fc_rport *rport = transport_class_to_rport(dev);
+   struct Scsi_Host *shost = rport_to_shost(rport);
+
+   spin_lock_irqsave(shost->host_lock, flags);
+   if (!strncmp(buf, "Blocked", 7)) {
+   if (rport->port_state != FC_PORTSTATE_ONLINE) {
+   spin_unlock_irqrestore(shost->host_lock, flags);
+   return -EBUSY;
+   }
+   spin_unlock_irqrestore(shost->host_lock, flags);
+   fc_remote_port_delete(rport);
+   } else if (!strncmp(buf, "Online", 6)) {
+   if (rport->port_state != FC_PORTSTATE_BLOCKED) {
+   spin_unlock_irqrestore(shost->host_lock, flags);
+   return -EBUSY;
+   }
+   /* Reset back to online for rescan */
+   rport->port_state = FC_PORTSTATE_ONLINE;
+   spin_unlock_irqrestore(shost->host_lock, flags);
+
+   if (!cancel_delayed_work(&rport->fail_io_work))
+   fc_flush_devloss(shost);
+   if (!cancel_delayed_work(&rport->dev_loss_work))
+   fc_flush_devloss(shost);
+
+   spin_lock_irqsave(shost->host_lock, flags);
+   rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+ FC_RPORT_DEVLOSS_PENDING |
+ FC_RPORT_DEVLOSS_CALLBK_DONE);
+   spin_unlock_irqrestore(shost->host_lock, flags);
+
+   /* ensure any stgt delete functions are done */
+   fc_flush_work(shost);
+
+   if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
+   scsi_target_unblock(&rport->dev, SDEV_RUNNING);
+   /* initiate a scan of the target */
+   spin_lock_irqsave(shost->host_lock, flags);
+   rport->flags |= FC_RPORT_SCAN_PENDING;
+   scsi_queue_work(shost, &rport->scan_work);
+   spin_unlock_irqrestore(shost->host_lock, flags);
+   }
+   } else
+   return -EINVAL;
+
+   return count;
+}
+
+static ssize_t
+show_fc_rport_port_state (struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct fc_rport *rport = transport_class_to_rport(dev);
+   const char *name;
+
+   name = get_fc_port_state_name(rport->port_state);
+   if (!name)
+   return -EINVAL;
+   return snprintf(buf, FC_PORTSTATE_MAX_NAMELEN, "%s\n", name);
+}
+
+static FC_DEVICE_ATTR(rport, port_state, S_IRUGO | S_IWUSR,
+   show_fc_rport_port_state, store_fc_rport_port_state);
+
  fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20);

  /*
@@ -2289,7 +2360,7 @@ fc_attach_transport(struct fc_function_template *ft)
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
 

RE: [PATCH v2 net-next 05/22] cxgb4: Add T5 write combining support

2013-03-14 Thread David Laight
> This patch implements a low latency Write Combining (aka Write Coalescing) 
> work
> request path. PCIE maps User Space Doorbell BAR2 region writes to the new
> interface to SGE. SGE pulls a new message from PCIE new interface and if its a
> coalesced write work request then pushes it for processing. This patch copies
> coalesced work request to memory mapped BAR2 space.
...
> + } else {
> + memset(data, 0, 2 * sizeof(u64));
> + *data += 2;
> + }

Using memset is overkill (or rather a big overhead if it isn't
detected by the compiler). Nothing wrong with:
(*data)[0] = 0;
(*data)[1] = 0;
*data += 2;
Actually, typing that, I realise that you should probably have
read *data into a local variable, and then updated it when finished.
Otherwise some of the accesses might be ones which force the
compiler to reload the value.

>  static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
>  {
> + unsigned int *wr, index;
> +
>   wmb();/* write descriptors before telling HW */
>   spin_lock(&q->db_lock);
>   if (!q->db_disabled) {
> - t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
> -  QID(q->cntxt_id) | PIDX(n));
> + if (is_t4(adap->chip)) {
> + t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
> +  QID(q->cntxt_id) | PIDX(n));
> + } else {
> + if (n == 1) {
> + index = q->pidx ? (q->pidx - 1) : (q->size - 1);
> + wr = (unsigned int *)&q->desc[index];
> + cxgb_pio_copy((u64 __iomem *)
> +   (adap->bar2 + q->udb + 64),
> +   (u64 *)wr);

Why all the casts on 'wr' ?

> + } else
> + writel(n,  adap->bar2 + q->udb + 8);
> + wmb();

Since you actually need memory barriers here on x86 you definitely
need a comment saying so, and it would (IMHO) better to use a
different define in the source (even if it is currently converted
to wmb() in a local header file).

Thinking further, for portability you might want to find some way
of abstracting the multi-word writes somehow.
For example, some of the ppc have a dma engine associated with the
PCIe master interface that can be used to generate large TLP.
The code would still want to spin waiting for the dma to complete
(since the transfer would be far faster than any interrupt path).

David



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 net-next 00/22] Add support for Chelsio T5 adapter

2013-03-14 Thread Steve Wise

Acked-by: Steve Wise 
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 net-next 00/22] Add support for Chelsio T5 adapter

2013-03-14 Thread David Miller
From: Vipul Pandya 
Date: Thu, 14 Mar 2013 20:38:46 +0530

> We request to merge this patch series via David Miller's net-next tree. We are
> copying respective maintainers of all the drivers for reviewing the changes.
> Kindly let us know in case of any review comments.

All applied to net-next, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 01/22] cxgb4: Add register definations for T5

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h |   94 ++
 1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h 
b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 83ec5f7..22cbcb3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -68,9 +68,14 @@
 #define  QID_SHIFT   15
 #define  QID(x)  ((x) << QID_SHIFT)
 #define  DBPRIO(x)   ((x) << 14)
+#define  DBTYPE(x)   ((x) << 13)
 #define  PIDX_MASK   0x3fffU
 #define  PIDX_SHIFT  0
 #define  PIDX(x) ((x) << PIDX_SHIFT)
+#define  S_PIDX_T5   0
+#define  M_PIDX_T5   0x1fffU
+#define  PIDX_T5(x)  (((x) >> S_PIDX_T5) & M_PIDX_T5)
+
 
 #define SGE_PF_GTS 0x4
 #define  INGRESSQID_MASK   0xU
@@ -152,6 +157,8 @@
 #define  QUEUESPERPAGEPF0_MASK   0x000fU
 #define  QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
 
+#define QUEUESPERPAGEPF14
+
 #define SGE_INT_CAUSE1 0x1024
 #define SGE_INT_CAUSE2 0x1030
 #define SGE_INT_CAUSE3 0x103c
@@ -272,17 +279,36 @@
 #define S_HP_INT_THRESH28
 #define M_HP_INT_THRESH 0xfU
 #define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH)
+#define S_LP_INT_THRESH_T518
+#define V_LP_INT_THRESH_T5(x) ((x) << S_LP_INT_THRESH_T5)
+#define M_LP_COUNT_T50x3U
+#define G_LP_COUNT_T5(x) (((x) >> S_LP_COUNT) & M_LP_COUNT_T5)
 #define M_HP_COUNT 0x7ffU
 #define S_HP_COUNT 16
 #define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
 #define S_LP_INT_THRESH12
 #define M_LP_INT_THRESH 0xfU
+#define M_LP_INT_THRESH_T50xfffU
 #define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
 #define M_LP_COUNT 0x7ffU
 #define S_LP_COUNT 0
 #define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
 #define A_SGE_DBFIFO_STATUS 0x10a4
 
+#define SGE_STAT_TOTAL 0x10e4
+#define SGE_STAT_MATCH 0x10e8
+
+#define SGE_STAT_CFG   0x10ec
+#define S_STATSOURCE_T59
+#define STATSOURCE_T5(x) ((x) << S_STATSOURCE_T5)
+
+#define SGE_DBFIFO_STATUS2 0x1118
+#define M_HP_COUNT_T50x3ffU
+#define G_HP_COUNT_T5(x) ((x)  & M_HP_COUNT_T5)
+#define S_HP_INT_THRESH_T510
+#define M_HP_INT_THRESH_T50xfU
+#define V_HP_INT_THRESH_T5(x) ((x) << S_HP_INT_THRESH_T5)
+
 #define S_ENABLE_DROP13
 #define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP)
 #define F_ENABLE_DROPV_ENABLE_DROP(1U)
@@ -331,8 +357,27 @@
 #define  MSIADDRHPERR  0x0002U
 #define  MSIADDRLPERR  0x0001U
 
+#define  READRSPERR  0x2000U
+#define  TRGT1GRPPERR0x1000U
+#define  IPSOTPERR   0x0800U
+#define  IPRXDATAGRPPERR 0x0200U
+#define  IPRXHDRGRPPERR  0x0100U
+#define  MAGRPPERR   0x0040U
+#define  VFIDPERR0x0020U
+#define  HREQWRPERR  0x0001U
+#define  DREQWRPERR  0x2000U
+#define  MSTTAGQPERR 0x0400U
+#define  PIOREQGRPPERR   0x0100U
+#define  PIOCPLGRPPERR   0x0080U
+#define  MSIXSTIPERR 0x0004U
+#define  MSTTIMEOUTPERR  0x0002U
+#define  MSTGRPPERR  0x0001U
+
 #define PCIE_NONFAT_ERR 0x3010
 #define PCIE_MEM_ACCESS_BASE_WIN 0x3068
+#define S_PCIEOFST   10
+#define M_PCIEOFST   0x3fU
+#define GET_PCIEOFST(x)  (((x) >> S_PCIEOFST) & M_PCIEOFST)
 #define  PCIEOFST_MASK   0xfc00U
 #define  BIR_MASK0x0300U
 #define  BIR_SHIFT   8
@@ -342,6 +387,9 @@
 #define  WINDOW(x)   ((x) << WINDOW_SHIFT)
 #define PCIE_MEM_ACCESS_OFFSET 0x306c
 
+#define S_PFNUM0
+#define V_PFNUM(x) ((x) << S_PFNUM)
+
 #define PCIE_FW 0x30b8
 #define  PCIE_FW_ERR   0x8000U
 #define  PCIE_FW_INIT  0x4000U
@@ -407,12 +455,18 @@
 
 #define MC_BIST_STATUS_RDATA 0x7688
 
+#define MA_EDRAM0_BAR 0x77c0
+#define MA_EDRAM1_BAR 0x77c4
+#define EDRAM_SIZE_MASK   0xfffU
+#define EDRAM_SIZE_GET(x) ((x) & EDRAM_SIZE_MASK)
+
 #define MA_EXT_MEMORY_BAR 0x77c8
 #define  EXT_MEM_SIZE_MASK   0x0fffU
 #define  EXT_MEM_SIZE_SHIFT  0
 #define  EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT)
 
 #define MA_TARGET_MEM_ENABLE 0x77d8
+#define  EXT_MEM1_ENABLE 0x0010U
 #define  EXT_MEM_ENABLE 0x0004U
 #define  EDRAM1_ENABLE  0x0002U
 #define  EDRAM0_ENABLE  0x0001U
@@ -431,6 +485,7 @@
 #define MA_PCIE_FW 0x30b8
 #define MA_PARITY_ERROR_STATUS 0x77f4
 
+#define MA_EXT_MEMORY1_BAR 0x7808
 #define EDC_0_BASE_ADDR 0x7900
 
 #define EDC_BIST_CMD 0x7904
@@ -801,6 +856,15 @@
 #define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c
 #define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610
 #define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614
+#define MAC_PORT_CFG2 0x818
+#define MAC_PORT_MAGIC_MACID_LO 0x824
+#define MAC_PORT_MAGIC_MACID_HI 0x828
+#define MAC_PORT_EPIO_DATA0 0x8c0
+#define MAC_PORT_EPIO_DATA1 0x8c4
+#define MAC_PORT_EPIO_DATA2 0x8c8
+#define MAC_PORT_EPIO_DATA3 0x8cc
+#define MAC_PORT_EPIO_OP 0x8d0
+
 #define MPS_CMN_CTL 0x9000
 #define  NU

[PATCH v2 net-next 05/22] cxgb4: Add T5 write combining support

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

This patch implements a low latency Write Combining (aka Write Coalescing) work
request path. PCIE maps User Space Doorbell BAR2 region writes to the new
interface to SGE. SGE pulls a new message from PCIE new interface and if its a
coalesced write work request then pushes it for processing. This patch copies
coalesced work request to memory mapped BAR2 space.

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h  |2 +
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   53 ++-
 drivers/net/ethernet/chelsio/cxgb4/sge.c|   52 +-
 3 files changed, 102 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index a91dea6..f8ff30e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -439,6 +439,7 @@ struct sge_txq {
spinlock_t db_lock;
int db_disabled;
unsigned short db_pidx;
+   u64 udb;
 };
 
 struct sge_eth_txq {/* state for an SGE Ethernet Tx queue */
@@ -543,6 +544,7 @@ enum chip_type {
 
 struct adapter {
void __iomem *regs;
+   void __iomem *bar2;
struct pci_dev *pdev;
struct device *pdev_dev;
unsigned int mbox;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 3d6d23a..ce1451c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1327,6 +1327,8 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ",
"GROpackets ",
"GROmerged  ",
+   "WriteCoalSuccess   ",
+   "WriteCoalFail  ",
 };
 
 static int get_sset_count(struct net_device *dev, int sset)
@@ -1422,11 +1424,25 @@ static void get_stats(struct net_device *dev, struct 
ethtool_stats *stats,
 {
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
+   u32 val1, val2;
 
t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data);
 
data += sizeof(struct port_stats) / sizeof(u64);
collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
+   data += sizeof(struct queue_port_stats) / sizeof(u64);
+   if (!is_t4(adapter->chip)) {
+   t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7));
+   val1 = t4_read_reg(adapter, SGE_STAT_TOTAL);
+   val2 = t4_read_reg(adapter, SGE_STAT_MATCH);
+   *data = val1 - val2;
+   data++;
+   *data = val2;
+   data++;
+   } else {
+   memset(data, 0, 2 * sizeof(u64));
+   *data += 2;
+   }
 }
 
 /*
@@ -5337,10 +5353,11 @@ static void free_some_resources(struct adapter *adapter)
 #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
 #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
   NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+#define SEGMENT_SIZE 128
 
 static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-   int func, i, err;
+   int func, i, err, s_qpp, qpp, num_seg;
struct port_info *pi;
bool highdma = false;
struct adapter *adapter = NULL;
@@ -5420,7 +5437,34 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
err = t4_prep_adapter(adapter);
if (err)
-   goto out_unmap_bar;
+   goto out_unmap_bar0;
+
+   if (!is_t4(adapter->chip)) {
+   s_qpp = QUEUESPERPAGEPF1 * adapter->fn;
+   qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter,
+ SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp);
+   num_seg = PAGE_SIZE / SEGMENT_SIZE;
+
+   /* Each segment size is 128B. Write coalescing is enabled only
+* when SGE_EGRESS_QUEUES_PER_PAGE_PF reg value for the
+* queue is less no of segments that can be accommodated in
+* a page size.
+*/
+   if (qpp > num_seg) {
+   dev_err(&pdev->dev,
+   "Incorrect number of egress queues per page\n");
+   err = -EINVAL;
+   goto out_unmap_bar0;
+   }
+   adapter->bar2 = ioremap_wc(pci_resource_start(pdev, 2),
+   pci_resource_len(pdev, 2));
+   if (!adapter->bar2) {
+   dev_err(&pdev->dev, "cannot map device bar2 region\n");
+   err = -ENOMEM;
+   goto out_unmap_bar0;
+   }
+   }
+
setup_memwin(adapter);
err = adap_init0(adapter);
setup_memwin_rdma(adapter)

[PATCH v2 net-next 22/22] csiostor: Cleanup chip specific operations.

2013-03-14 Thread Vipul Pandya
From: Arvind Bhushan 

This patch removes chip specific operations from the common hardware
paths, as well as the Makefile change to accomodate the new files.

Signed-off-by: Arvind Bhushan 
Signed-off-by: Naresh Kumar Inna 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/scsi/csiostor/Makefile|3 +-
 drivers/scsi/csiostor/csio_hw.c   |  559 -
 drivers/scsi/csiostor/csio_hw.h   |   47 ++--
 drivers/scsi/csiostor/csio_init.c |   48 +++-
 drivers/scsi/csiostor/csio_init.h |   29 +--
 drivers/scsi/csiostor/csio_wr.c   |   19 +-
 6 files changed, 193 insertions(+), 512 deletions(-)

diff --git a/drivers/scsi/csiostor/Makefile b/drivers/scsi/csiostor/Makefile
index b581966..913b9a9 100644
--- a/drivers/scsi/csiostor/Makefile
+++ b/drivers/scsi/csiostor/Makefile
@@ -8,4 +8,5 @@ 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
+   csio_hw.o csio_hw_t4.o csio_hw_t5.o csio_isr.o \
+   csio_mb.o csio_rnode.o csio_wr.o
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index bdd78fb..a0b4c89 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -61,7 +61,7 @@ int csio_msi = 2;
 static int dev_num;
 
 /* FCoE Adapter types & its description */
-static const struct csio_adap_desc csio_fcoe_adapters[] = {
+static const struct csio_adap_desc csio_t4_fcoe_adapters[] = {
{"T440-Dbg 10G", "Chelsio T440-Dbg 10G [FCoE]"},
{"T420-CR 10G", "Chelsio T420-CR 10G [FCoE]"},
{"T422-CR 10G/1G", "Chelsio T422-CR 10G/1G [FCoE]"},
@@ -77,7 +77,38 @@ static const struct csio_adap_desc csio_fcoe_adapters[] = {
{"B404-BT 1G", "Chelsio B404-BT 1G [FCoE]"},
{"T480-CR 10G", "Chelsio T480-CR 10G [FCoE]"},
{"T440-LP-CR 10G", "Chelsio T440-LP-CR 10G [FCoE]"},
-   {"T4 FPGA", "Chelsio T4 FPGA [FCoE]"}
+   {"AMSTERDAM 10G", "Chelsio AMSTERDAM 10G [FCoE]"},
+   {"HUAWEI T480 10G", "Chelsio HUAWEI T480 10G [FCoE]"},
+   {"HUAWEI T440 10G", "Chelsio HUAWEI T440 10G [FCoE]"},
+   {"HUAWEI STG 10G", "Chelsio HUAWEI STG 10G [FCoE]"},
+   {"ACROMAG XAUI 10G", "Chelsio ACROMAG XAUI 10G [FCoE]"},
+   {"ACROMAG SFP+ 10G", "Chelsio ACROMAG SFP+ 10G [FCoE]"},
+   {"QUANTA SFP+ 10G", "Chelsio QUANTA SFP+ 10G [FCoE]"},
+   {"HUAWEI 10Gbase-T", "Chelsio HUAWEI 10Gbase-T [FCoE]"},
+   {"HUAWEI T4TOE 10G", "Chelsio HUAWEI T4TOE 10G [FCoE]"}
+};
+
+static const struct csio_adap_desc csio_t5_fcoe_adapters[] = {
+   {"T580-Dbg 10G", "Chelsio T580-Dbg 10G [FCoE]"},
+   {"T520-CR 10G", "Chelsio T520-CR 10G [FCoE]"},
+   {"T522-CR 10G/1G", "Chelsio T452-CR 10G/1G [FCoE]"},
+   {"T540-CR 10G", "Chelsio T540-CR 10G [FCoE]"},
+   {"T520-BCH 10G", "Chelsio T520-BCH 10G [FCoE]"},
+   {"T540-BCH 10G", "Chelsio T540-BCH 10G [FCoE]"},
+   {"T540-CH 10G", "Chelsio T540-CH 10G [FCoE]"},
+   {"T520-SO 10G", "Chelsio T520-SO 10G [FCoE]"},
+   {"T520-CX4 10G", "Chelsio T520-CX4 10G [FCoE]"},
+   {"T520-BT 10G", "Chelsio T520-BT 10G [FCoE]"},
+   {"T504-BT 1G", "Chelsio T504-BT 1G [FCoE]"},
+   {"B520-SR 10G", "Chelsio B520-SR 10G [FCoE]"},
+   {"B504-BT 1G", "Chelsio B504-BT 1G [FCoE]"},
+   {"T580-CR 10G", "Chelsio T580-CR 10G [FCoE]"},
+   {"T540-LP-CR 10G", "Chelsio T540-LP-CR 10G [FCoE]"},
+   {"AMSTERDAM 10G", "Chelsio AMSTERDAM 10G [FCoE]"},
+   {"T580-LP-CR 40G", "Chelsio T580-LP-CR 40G [FCoE]"},
+   {"T520-LL-CR 10G", "Chelsio T520-LL-CR 10G [FCoE]"},
+   {"T560-CR 40G", "Chelsio T560-CR 40G [FCoE]"},
+   {"T580-CR 40G", "Chelsio T580-CR 40G [FCoE]"}
 };
 
 static void csio_mgmtm_cleanup(struct csio_mgmtm *);
@@ -124,7 +155,7 @@ int csio_is_hw_removing(struct csio_hw *hw)
  * at the time it indicated completion is stored there.  Returns 0 if the
  * operation completes and -EAGAIN otherwise.
  */
-static int
+int
 csio_hw_wait_op_done_val(struct csio_hw *hw, int reg, uint32_t mask,
 int polarity, int attempts, int delay, uint32_t *valp)
 {
@@ -145,6 +176,24 @@ csio_hw_wait_op_done_val(struct csio_hw *hw, int reg, 
uint32_t mask,
}
 }
 
+/*
+ * csio_hw_tp_wr_bits_indirect - set/clear bits in an indirect TP register
+ * @hw: the adapter
+ * @addr: the indirect TP register address
+ * @mask: specifies the field within the register to modify
+ * @val: new value for the field
+ *
+ * Sets a field of an indirect TP register to the given value.
+ */
+void
+csio_hw_tp_wr_bits_indirect(struct csio_hw *hw, unsigned int addr,
+   unsigned int mask, unsigned int val)
+{
+   csio_wr_reg32(hw, addr, TP_PIO_ADDR);
+   val |= csio_rd_reg32(hw, TP_PIO_DATA) & ~mask;
+   csio_wr_reg32(

[PATCH v2 net-next 21/22] csiostor: Header file modifications for chip support and bug fixes.

2013-03-14 Thread Vipul Pandya
From: Arvind Bhushan 

This patch defines the common operations to support multiple chips. It
includes common header file modifications to support the current chips
(T4 and T5). It also includes the following bug fixes:
- reconfirms the rnode state after an implicit logo.
- corrects the stats array size.
- sets up and checks flags correctly when coming up as master and finding
the card initialized

Reported-by: Dan Carpenter 
Signed-off-by: Arvind Bhushan 
Signed-off-by: Naresh Kumar Inna 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/scsi/csiostor/csio_hw_chip.h |  175 ++
 drivers/scsi/csiostor/csio_lnode.h   |2 +-
 drivers/scsi/csiostor/csio_rnode.c   |   10 ++-
 drivers/scsi/csiostor/csio_rnode.h   |2 +-
 drivers/scsi/csiostor/csio_wr.c  |   41 +---
 5 files changed, 212 insertions(+), 18 deletions(-)
 create mode 100644 drivers/scsi/csiostor/csio_hw_chip.h

diff --git a/drivers/scsi/csiostor/csio_hw_chip.h 
b/drivers/scsi/csiostor/csio_hw_chip.h
new file mode 100644
index 000..bca0de6
--- /dev/null
+++ b/drivers/scsi/csiostor/csio_hw_chip.h
@@ -0,0 +1,175 @@
+/*
+ * This file is part of the Chelsio FCoE driver for Linux.
+ *
+ * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CSIO_HW_CHIP_H__
+#define __CSIO_HW_CHIP_H__
+
+#include "csio_defs.h"
+
+/* FCoE device IDs for T4 */
+#define CSIO_DEVID_T440DBG_FCOE0x4600
+#define CSIO_DEVID_T420CR_FCOE 0x4601
+#define CSIO_DEVID_T422CR_FCOE 0x4602
+#define CSIO_DEVID_T440CR_FCOE 0x4603
+#define CSIO_DEVID_T420BCH_FCOE0x4604
+#define CSIO_DEVID_T440BCH_FCOE0x4605
+#define CSIO_DEVID_T440CH_FCOE 0x4606
+#define CSIO_DEVID_T420SO_FCOE 0x4607
+#define CSIO_DEVID_T420CX_FCOE 0x4608
+#define CSIO_DEVID_T420BT_FCOE 0x4609
+#define CSIO_DEVID_T404BT_FCOE 0x460A
+#define CSIO_DEVID_B420_FCOE   0x460B
+#define CSIO_DEVID_B404_FCOE   0x460C
+#define CSIO_DEVID_T480CR_FCOE 0x460D
+#define CSIO_DEVID_T440LPCR_FCOE   0x460E
+#define CSIO_DEVID_AMSTERDAM_T4_FCOE   0x460F
+#define CSIO_DEVID_HUAWEI_T480_FCOE0x4680
+#define CSIO_DEVID_HUAWEI_T440_FCOE0x4681
+#define CSIO_DEVID_HUAWEI_STG310_FCOE  0x4682
+#define CSIO_DEVID_ACROMAG_XMC_XAUI0x4683
+#define CSIO_DEVID_ACROMAG_XMC_SFP_FCOE0x4684
+#define CSIO_DEVID_QUANTA_MEZZ_SFP_FCOE0x4685
+#define CSIO_DEVID_HUAWEI_10GT_FCOE0x4686
+#define CSIO_DEVID_HUAWEI_T440_TOE_FCOE0x4687
+
+/* FCoE device IDs for T5 */
+#define CSIO_DEVID_T580DBG_FCOE0x5600
+#define CSIO_DEVID_T520CR_FCOE 0x5601
+#define CSIO_DEVID_T522CR_FCOE 0x5602
+#define CSIO_DEVID_T540CR_FCOE 0x5603
+#define CSIO_DEVID_T520BCH_FCOE0x5604
+#define CSIO_DEVID_T540BCH_FCOE0x5605
+#define CSIO_DEVID_T540CH_FCOE 0x5606
+#define CSIO_DEVID_T520SO_FCOE 0x5607
+#define CSIO_DEVID_T520CX_FCOE 0x5608
+#define CSIO_DEVID_T520BT_FCOE 0x5609
+#define CSIO_DEVID_T504BT_FCOE 0x560A
+#define CSIO_DEVID_B520_FCOE   0x560B
+#define CSIO_DEVID_B504_FCOE   0x560C
+#define CSIO_DEVID_T580CR2_FCOE0x560D
+#define CSIO_DEVID_T540LPCR_FCOE  

[PATCH v2 net-next 20/22] csiostor: Add T5 adapter operations.

2013-03-14 Thread Vipul Pandya
From: Arvind Bhushan 

This patch creates a new file for T5 adapter operations.

Signed-off-by: Arvind Bhushan 
Signed-off-by: Naresh Kumar Inna 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/scsi/csiostor/csio_hw_t5.c |  397 
 1 files changed, 397 insertions(+), 0 deletions(-)
 create mode 100644 drivers/scsi/csiostor/csio_hw_t5.c

diff --git a/drivers/scsi/csiostor/csio_hw_t5.c 
b/drivers/scsi/csiostor/csio_hw_t5.c
new file mode 100644
index 000..27745c1
--- /dev/null
+++ b/drivers/scsi/csiostor/csio_hw_t5.c
@@ -0,0 +1,397 @@
+/*
+ * This file is part of the Chelsio FCoE driver for Linux.
+ *
+ * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "csio_hw.h"
+#include "csio_init.h"
+
+static int
+csio_t5_set_mem_win(struct csio_hw *hw, uint32_t win)
+{
+   u32 mem_win_base;
+   /*
+* Truncation intentional: we only read the bottom 32-bits of the
+* 64-bit BAR0/BAR1 ...  We use the hardware backdoor mechanism to
+* read BAR0 instead of using pci_resource_start() because we could be
+* operating from within a Virtual Machine which is trapping our
+* accesses to our Configuration Space and we need to set up the PCI-E
+* Memory Window decoders with the actual addresses which will be
+* coming across the PCI-E link.
+*/
+
+   /* For T5, only relative offset inside the PCIe BAR is passed */
+   mem_win_base = MEMWIN_BASE;
+
+   /*
+* Set up memory window for accessing adapter memory ranges.  (Read
+* back MA register to ensure that changes propagate before we attempt
+* to use the new values.)
+*/
+   csio_wr_reg32(hw, mem_win_base | BIR(0) |
+ WINDOW(ilog2(MEMWIN_APERTURE) - 10),
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
+   csio_rd_reg32(hw,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
+
+   return 0;
+}
+
+/*
+ * Interrupt handler for the PCIE module.
+ */
+static void
+csio_t5_pcie_intr_handler(struct csio_hw *hw)
+{
+   static struct intr_info sysbus_intr_info[] = {
+   { RNPP, "RXNP array parity error", -1, 1 },
+   { RPCP, "RXPC array parity error", -1, 1 },
+   { RCIP, "RXCIF array parity error", -1, 1 },
+   { RCCP, "Rx completions control array parity error", -1, 1 },
+   { RFTP, "RXFT array parity error", -1, 1 },
+   { 0, NULL, 0, 0 }
+   };
+   static struct intr_info pcie_port_intr_info[] = {
+   { TPCP, "TXPC array parity error", -1, 1 },
+   { TNPP, "TXNP array parity error", -1, 1 },
+   { TFTP, "TXFT array parity error", -1, 1 },
+   { TCAP, "TXCA array parity error", -1, 1 },
+   { TCIP, "TXCIF array parity error", -1, 1 },
+   { RCAP, "RXCA array parity error", -1, 1 },
+   { OTDD, "outbound request TLP discarded", -1, 1 },
+   { RDPE, "Rx data parity error", -1, 1 },
+   { TDUE, "Tx uncorrectable data error", -1, 1 },
+   { 0, NULL, 0, 0 }
+   };
+
+   static struct intr_info pcie_intr_info[] = {
+   { MSTGRPPERR, "Master Response Read Queue parity error",
+   -1, 1 },
+   { MSTTIMEOUTPERR, "Master Timeout FIFO parity error", -1, 1 },
+   { MSIXSTIPERR, "MSI-X STI SRAM parity error", -1, 1 },
+   { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
+   { MSIXADDRHPERR, "MSI-X AddrH parit

[PATCH v2 net-next 19/22] csiostor: Segregate T4 adapter operations.

2013-03-14 Thread Vipul Pandya
From: Arvind Bhushan 

This patch separates T4 adapter operations into a new file.

Signed-off-by: Arvind Bhushan 
Signed-off-by: Naresh Kumar Inna 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/scsi/csiostor/csio_hw_t4.c |  403 
 1 files changed, 403 insertions(+), 0 deletions(-)
 create mode 100644 drivers/scsi/csiostor/csio_hw_t4.c

diff --git a/drivers/scsi/csiostor/csio_hw_t4.c 
b/drivers/scsi/csiostor/csio_hw_t4.c
new file mode 100644
index 000..89ecbac
--- /dev/null
+++ b/drivers/scsi/csiostor/csio_hw_t4.c
@@ -0,0 +1,403 @@
+/*
+ * This file is part of the Chelsio FCoE driver for Linux.
+ *
+ * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "csio_hw.h"
+#include "csio_init.h"
+
+/*
+ * Return the specified PCI-E Configuration Space register from our Physical
+ * Function.  We try first via a Firmware LDST Command since we prefer to let
+ * the firmware own all of these registers, but if that fails we go for it
+ * directly ourselves.
+ */
+static uint32_t
+csio_t4_read_pcie_cfg4(struct csio_hw *hw, int reg)
+{
+   u32 val = 0;
+   struct csio_mb *mbp;
+   int rv;
+   struct fw_ldst_cmd *ldst_cmd;
+
+   mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
+   if (!mbp) {
+   CSIO_INC_STATS(hw, n_err_nomem);
+   pci_read_config_dword(hw->pdev, reg, &val);
+   return val;
+   }
+
+   csio_mb_ldst(hw, mbp, CSIO_MB_DEFAULT_TMO, reg);
+   rv = csio_mb_issue(hw, mbp);
+
+   /*
+* If the LDST Command suucceeded, exctract the returned register
+* value.  Otherwise read it directly ourself.
+*/
+   if (rv == 0) {
+   ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb);
+   val = ntohl(ldst_cmd->u.pcie.data[0]);
+   } else
+   pci_read_config_dword(hw->pdev, reg, &val);
+
+   mempool_free(mbp, hw->mb_mempool);
+
+   return val;
+}
+
+static int
+csio_t4_set_mem_win(struct csio_hw *hw, uint32_t win)
+{
+   u32 bar0;
+   u32 mem_win_base;
+
+   /*
+* Truncation intentional: we only read the bottom 32-bits of the
+* 64-bit BAR0/BAR1 ...  We use the hardware backdoor mechanism to
+* read BAR0 instead of using pci_resource_start() because we could be
+* operating from within a Virtual Machine which is trapping our
+* accesses to our Configuration Space and we need to set up the PCI-E
+* Memory Window decoders with the actual addresses which will be
+* coming across the PCI-E link.
+*/
+   bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0);
+   bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
+
+   mem_win_base = bar0 + MEMWIN_BASE;
+
+   /*
+* Set up memory window for accessing adapter memory ranges.  (Read
+* back MA register to ensure that changes propagate before we attempt
+* to use the new values.)
+*/
+   csio_wr_reg32(hw, mem_win_base | BIR(0) |
+ WINDOW(ilog2(MEMWIN_APERTURE) - 10),
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
+   csio_rd_reg32(hw,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
+   return 0;
+}
+
+/*
+ * Interrupt handler for the PCIE module.
+ */
+static void
+csio_t4_pcie_intr_handler(struct csio_hw *hw)
+{
+   static struct intr_info sysbus_intr_info[] = {
+   { RNPP, "RXNP array parity error", -1, 1 },
+   { RPCP, "RXPC array parity error", -1, 1 },
+   { RCIP, "RXCIF array parity error", -1, 1 },
+   { RCC

[PATCH v2 net-next 18/22] RDMA/cxgb4: Fix onchip queue support for T5

2013-03-14 Thread Vipul Pandya
T5 adapter does not support onchip queue memory. Present logic fails to
allocate QP for T5 and returns an error. Also, if module parameter ocqp_support
is zero then we are unable to allocate QP which should not be the case. Ideally
if ocqp_support parameter is 0 or onchip queue support is disable then host QP
should be allocated before returning an error.

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/qp.c |   13 +
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 90833d7..9fe6f1e 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -140,7 +140,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq 
*wq,
int wr_len;
struct c4iw_wr_wait wr_wait;
struct sk_buff *skb;
-   int ret;
+   int ret = 0;
int eqsize;
 
wq->sq.qid = c4iw_get_qpid(rdev, uctx);
@@ -180,17 +180,14 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq 
*wq,
}
 
if (user) {
-   ret = alloc_oc_sq(rdev, &wq->sq);
-   if (ret)
+   if (alloc_oc_sq(rdev, &wq->sq) && alloc_host_sq(rdev, &wq->sq))
goto free_hwaddr;
-
-   ret = alloc_host_sq(rdev, &wq->sq);
-   if (ret)
-   goto free_sq;
-   } else
+   } else {
ret = alloc_host_sq(rdev, &wq->sq);
if (ret)
goto free_hwaddr;
+   }
+
memset(wq->sq.queue, 0, wq->sq.memsize);
dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr);
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 17/22] RDMA/cxgb4: Bump tcam_full stat and WR reply timeout

2013-03-14 Thread Vipul Pandya
Always bump the tcam_full stat. Also, bump wr reply timeout to 30 seconds.

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/cm.c   |2 +-
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 272bf78..8dcc84f 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -1693,9 +1693,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct 
sk_buff *skb)
case CPL_ERR_CONN_TIMEDOUT:
break;
case CPL_ERR_TCAM_FULL:
+   dev->rdev.stats.tcam_full++;
if (dev->rdev.lldi.enable_fw_ofld_conn) {
mutex_lock(&dev->rdev.stats.lock);
-   dev->rdev.stats.tcam_full++;
mutex_unlock(&dev->rdev.stats.lock);
send_fw_act_open_req(ep,
 GET_TID_TID(GET_AOPEN_ATID(
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h 
b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 08e406c..485183a 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -162,7 +162,7 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev)
return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5));
 }
 
-#define C4IW_WR_TO (10*HZ)
+#define C4IW_WR_TO (30*HZ)
 
 struct c4iw_wr_wait {
struct completion completion;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 15/22] RDMA/cxgb4: Use DSGLs for fastreg and adapter memory writes for T5.

2013-03-14 Thread Vipul Pandya
It enables direct DMA by HW to memory region PBL arrays and fast register PBL
arrays from host memory, vs the T4 way of passing these arrays in the WR itself.
The result is lower latency for memory registration, and larger PBL array
support for fast register operations.

This patch also updates ULP_TX_MEM_WRITE command fields for T5. Ordering bit of
ULP_TX_MEM_WRITE is at bit position 22 in T5 and at 23 in T4.

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/iw_cxgb4.h  |2 +-
 drivers/infiniband/hw/cxgb4/mem.c   |  138 --
 drivers/infiniband/hw/cxgb4/qp.c|   76 ++-
 drivers/infiniband/hw/cxgb4/t4.h|2 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h |8 ++
 5 files changed, 190 insertions(+), 36 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h 
b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 4dbe96a..08e406c 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -369,7 +369,6 @@ struct c4iw_fr_page_list {
DEFINE_DMA_UNMAP_ADDR(mapping);
dma_addr_t dma_addr;
struct c4iw_dev *dev;
-   int size;
 };
 
 static inline struct c4iw_fr_page_list *to_c4iw_fr_page_list(
@@ -940,6 +939,7 @@ extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
 extern int c4iw_max_read_depth;
 extern int db_fc_threshold;
 extern int db_coalescing_threshold;
+extern int use_dsgl;
 
 
 #endif
diff --git a/drivers/infiniband/hw/cxgb4/mem.c 
b/drivers/infiniband/hw/cxgb4/mem.c
index 903a92d..33db9ee 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -30,16 +30,76 @@
  * SOFTWARE.
  */
 
+#include 
+#include 
 #include 
 #include 
 
 #include "iw_cxgb4.h"
 
+int use_dsgl = 1;
+module_param(use_dsgl, int, 0644);
+MODULE_PARM_DESC(use_dsgl, "Use DSGL for PBL/FastReg (default=1)");
+
 #define T4_ULPTX_MIN_IO 32
 #define C4IW_MAX_INLINE_SIZE 96
+#define T4_ULPTX_MAX_DMA 1024
+#define C4IW_INLINE_THRESHOLD 128
 
-static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len,
-void *data)
+static int inline_threshold = C4IW_INLINE_THRESHOLD;
+module_param(inline_threshold, int, 0644);
+MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
+
+static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
+  u32 len, void *data, int wait)
+{
+   struct sk_buff *skb;
+   struct ulp_mem_io *req;
+   struct ulptx_sgl *sgl;
+   u8 wr_len;
+   int ret = 0;
+   struct c4iw_wr_wait wr_wait;
+
+   addr &= 0x7FF;
+
+   if (wait)
+   c4iw_init_wr_wait(&wr_wait);
+   wr_len = roundup(sizeof(*req) + sizeof(*sgl), 16);
+
+   skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL);
+   if (!skb)
+   return -ENOMEM;
+   set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
+
+   req = (struct ulp_mem_io *)__skb_put(skb, wr_len);
+   memset(req, 0, wr_len);
+   INIT_ULPTX_WR(req, wr_len, 0, 0);
+   req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) |
+   (wait ? FW_WR_COMPL(1) : 0));
+   req->wr.wr_lo = wait ? (__force __be64)&wr_wait : 0;
+   req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16)));
+   req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE));
+   req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1));
+   req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN(len>>5));
+   req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), 16));
+   req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR(addr));
+
+   sgl = (struct ulptx_sgl *)(req + 1);
+   sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_DSGL) |
+   ULPTX_NSGE(1));
+   sgl->len0 = cpu_to_be32(len);
+   sgl->addr0 = cpu_to_be64(virt_to_phys(data));
+
+   ret = c4iw_ofld_send(rdev, skb);
+   if (ret)
+   return ret;
+   if (wait)
+   ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__);
+   return ret;
+}
+
+static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len,
+ void *data)
 {
struct sk_buff *skb;
struct ulp_mem_io *req;
@@ -47,6 +107,12 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 
addr, u32 len,
u8 wr_len, *to_dp, *from_dp;
int copy_len, num_wqe, i, ret = 0;
struct c4iw_wr_wait wr_wait;
+   __be32 cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE));
+
+   if (is_t4(rdev->lldi.adapter_type))
+   cmd |= cpu_to_be32(ULP_MEMIO_ORDER(1));
+   else
+   cmd |= cpu_to_be32(V_T5_ULP_MEMIO_IMM(1));
 
addr &= 0x7FF;
PDBG("%s addr 0x%x len %u\n", __func__, addr, len);
@@ -77,7 +143,7 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 
addr, u32 len,
   

[PATCH v2 net-next 13/22] RDMA/cxgb4: Turn off db coalescing when RDMA QPs are in use.

2013-03-14 Thread Vipul Pandya
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/qp.c|   20 
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   19 +++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h  |3 +++
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h|4 
 4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index c460244..da4869f 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -42,10 +42,17 @@ static int ocqp_support = 1;
 module_param(ocqp_support, int, 0644);
 MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
 
-int db_fc_threshold = 2000;
+int db_fc_threshold = 1000;
 module_param(db_fc_threshold, int, 0644);
-MODULE_PARM_DESC(db_fc_threshold, "QP count/threshold that triggers automatic "
-"db flow control mode (default = 2000)");
+MODULE_PARM_DESC(db_fc_threshold,
+"QP count/threshold that triggers"
+" automatic db flow control mode (default = 1000)");
+
+int db_coalescing_threshold;
+module_param(db_coalescing_threshold, int, 0644);
+MODULE_PARM_DESC(db_coalescing_threshold,
+"QP count/threshold that triggers"
+" disabling db coalescing (default = 0)");
 
 static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state)
 {
@@ -1448,6 +1455,8 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
rhp->db_state = NORMAL;
idr_for_each(&rhp->qpidr, enable_qp_db, NULL);
}
+   if (rhp->qpcnt <= db_coalescing_threshold)
+   cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]);
spin_unlock_irq(&rhp->lock);
atomic_dec(&qhp->refcnt);
wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
@@ -1559,11 +1568,14 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct 
ib_qp_init_attr *attrs,
spin_lock_irq(&rhp->lock);
if (rhp->db_state != NORMAL)
t4_disable_wq_db(&qhp->wq);
-   if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) {
+   rhp->qpcnt++;
+   if (rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) {
rhp->rdev.stats.db_state_transitions++;
rhp->db_state = FLOW_CONTROL;
idr_for_each(&rhp->qpidr, disable_qp_db, NULL);
}
+   if (rhp->qpcnt > db_coalescing_threshold)
+   cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]);
ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
spin_unlock_irq(&rhp->lock);
if (ret)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a59bb23..e76cf03 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3397,6 +3397,25 @@ out:
 }
 EXPORT_SYMBOL(cxgb4_sync_txq_pidx);
 
+void cxgb4_disable_db_coalescing(struct net_device *dev)
+{
+   struct adapter *adap;
+
+   adap = netdev2adap(dev);
+   t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_NOCOALESCE,
+F_NOCOALESCE);
+}
+EXPORT_SYMBOL(cxgb4_disable_db_coalescing);
+
+void cxgb4_enable_db_coalescing(struct net_device *dev)
+{
+   struct adapter *adap;
+
+   adap = netdev2adap(dev);
+   t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_NOCOALESCE, 0);
+}
+EXPORT_SYMBOL(cxgb4_enable_db_coalescing);
+
 static struct pci_driver cxgb4_driver;
 
 static void check_neigh_update(struct neighbour *neigh)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index e2bbc7f..4faf4d0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -269,4 +269,7 @@ struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
   unsigned int skb_len, unsigned int pull_len);
 int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
 int cxgb4_flush_eq_cache(struct net_device *dev);
+void cxgb4_disable_db_coalescing(struct net_device *dev);
+void cxgb4_enable_db_coalescing(struct net_device *dev);
+
 #endif  /* !__CXGB4_OFLD_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h 
b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 22cbcb3..ef146c0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -241,6 +241,10 @@
 #define SGE_DOORBELL_CONTROL 0x10a8
 #define  ENABLE_DROP(1 << 13)
 
+#define S_NOCOALESCE26
+#define V_NOCOALESCE(x) ((x) << S_NOCOALESCE)
+#define F_NOCOALESCEV_NOCOALESCE(1U)
+
 #define SGE_TIMER_VALUE_0_AND_1 0x10b8
 #define  TIMERVALUE0_MASK   0xU
 #define  TIMERVALUE0_SHIFT  16
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe lin

[PATCH v2 net-next 09/22] cxgb4: Update driver version and description

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index eceee44..c502e36 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -68,8 +68,8 @@
 #include "t4fw_api.h"
 #include "l2t.h"
 
-#define DRV_VERSION "1.3.0-ko"
-#define DRV_DESC "Chelsio T4 Network Driver"
+#define DRV_VERSION "2.0.0-ko"
+#define DRV_DESC "Chelsio T4/T5 Network Driver"
 
 /*
  * Max interrupt hold-off timer value in us.  Queues fall back to this value
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 07/22] cxgb4: Add T5 debugfs support

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h  |3 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   55 +---
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c  |  104 --
 3 files changed, 119 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index f8ff30e..45b18bd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -908,7 +908,8 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, 
unsigned int viid,
int start, int n, const u16 *rspq, unsigned int nrspq);
 int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
   unsigned int flags);
-int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
+int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
+  u64 *parity);
 int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
u64 *parity);
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 177d0c1..ca88070 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2843,8 +2843,8 @@ static ssize_t mem_read(struct file *file, char __user 
*buf, size_t count,
int ret, ofst;
__be32 data[16];
 
-   if (mem == MEM_MC)
-   ret = t4_mc_read(adap, pos, data, NULL);
+   if ((mem == MEM_MC) || (mem == MEM_MC1))
+   ret = t4_mc_read(adap, mem % MEM_MC, pos, data, NULL);
else
ret = t4_edc_read(adap, mem, pos, data, NULL);
if (ret)
@@ -2885,18 +2885,37 @@ static void add_debugfs_mem(struct adapter *adap, const 
char *name,
 static int setup_debugfs(struct adapter *adap)
 {
int i;
+   u32 size;
 
if (IS_ERR_OR_NULL(adap->debugfs_root))
return -1;
 
i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE);
-   if (i & EDRAM0_ENABLE)
-   add_debugfs_mem(adap, "edc0", MEM_EDC0, 5);
-   if (i & EDRAM1_ENABLE)
-   add_debugfs_mem(adap, "edc1", MEM_EDC1, 5);
-   if (i & EXT_MEM_ENABLE)
-   add_debugfs_mem(adap, "mc", MEM_MC,
-   EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)));
+   if (i & EDRAM0_ENABLE) {
+   size = t4_read_reg(adap, MA_EDRAM0_BAR);
+   add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM_SIZE_GET(size));
+   }
+   if (i & EDRAM1_ENABLE) {
+   size = t4_read_reg(adap, MA_EDRAM1_BAR);
+   add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size));
+   }
+   if (is_t4(adap->chip)) {
+   size = t4_read_reg(adap, MA_EXT_MEMORY_BAR);
+   if (i & EXT_MEM_ENABLE)
+   add_debugfs_mem(adap, "mc", MEM_MC,
+   EXT_MEM_SIZE_GET(size));
+   } else {
+   if (i & EXT_MEM_ENABLE) {
+   size = t4_read_reg(adap, MA_EXT_MEMORY_BAR);
+   add_debugfs_mem(adap, "mc0", MEM_MC0,
+   EXT_MEM_SIZE_GET(size));
+   }
+   if (i & EXT_MEM1_ENABLE) {
+   size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR);
+   add_debugfs_mem(adap, "mc1", MEM_MC1,
+   EXT_MEM_SIZE_GET(size));
+   }
+   }
if (adap->l2t)
debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap,
&t4_l2t_fops);
@@ -4101,17 +4120,27 @@ void t4_fatal_err(struct adapter *adap)
 
 static void setup_memwin(struct adapter *adap)
 {
-   u32 bar0;
+   u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base;
 
bar0 = pci_resource_start(adap->pdev, 0);  /* truncation intentional */
+   if (is_t4(adap->chip)) {
+   mem_win0_base = bar0 + MEMWIN0_BASE;
+   mem_win1_base = bar0 + MEMWIN1_BASE;
+   mem_win2_base = bar0 + MEMWIN2_BASE;
+   } else {
+   /* For T5, only relative offset inside the PCIe BAR is passed */
+   mem_win0_base = MEMWIN0_BASE;
+   mem_win1_base = MEMWIN1_BASE_T5;
+   mem_win2_base = MEMWIN2_BASE_T5;
+   }
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
-(bar0 + MEMWIN0_BASE) | BIR(0) |
+mem_win0_base | BIR(0) |
 WINDOW(ilog2(MEMWIN0_APERTURE) - 10));
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1),
- 

[PATCH v2 net-next 06/22] cxgb4: Enable doorbell drop recovery only for T4 adapter

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   87 ++
 1 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index ce1451c..177d0c1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3227,10 +3227,18 @@ EXPORT_SYMBOL(cxgb4_port_chan);
 unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo)
 {
struct adapter *adap = netdev2adap(dev);
-   u32 v;
+   u32 v1, v2, lp_count, hp_count;
 
-   v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
-   return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v);
+   v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
+   v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
+   if (is_t4(adap->chip)) {
+   lp_count = G_LP_COUNT(v1);
+   hp_count = G_HP_COUNT(v1);
+   } else {
+   lp_count = G_LP_COUNT_T5(v1);
+   hp_count = G_HP_COUNT_T5(v2);
+   }
+   return lpfifo ? lp_count : hp_count;
 }
 EXPORT_SYMBOL(cxgb4_dbfifo_count);
 
@@ -3368,14 +3376,23 @@ static struct notifier_block cxgb4_netevent_nb = {
 
 static void drain_db_fifo(struct adapter *adap, int usecs)
 {
-   u32 v;
+   u32 v1, v2, lp_count, hp_count;
 
do {
+   v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
+   v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
+   if (is_t4(adap->chip)) {
+   lp_count = G_LP_COUNT(v1);
+   hp_count = G_HP_COUNT(v1);
+   } else {
+   lp_count = G_LP_COUNT_T5(v1);
+   hp_count = G_HP_COUNT_T5(v2);
+   }
+
+   if (lp_count == 0 && hp_count == 0)
+   break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(usecs_to_jiffies(usecs));
-   v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
-   if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
-   break;
} while (1);
 }
 
@@ -3484,24 +3501,62 @@ static void process_db_drop(struct work_struct *work)
 
adap = container_of(work, struct adapter, db_drop_task);
 
+   if (is_t4(adap->chip)) {
+   disable_dbs(adap);
+   notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
+   drain_db_fifo(adap, 1);
+   recover_all_queues(adap);
+   enable_dbs(adap);
+   } else {
+   u32 dropped_db = t4_read_reg(adap, 0x010ac);
+   u16 qid = (dropped_db >> 15) & 0x1;
+   u16 pidx_inc = dropped_db & 0x1fff;
+   unsigned int s_qpp;
+   unsigned short udb_density;
+   unsigned long qpshift;
+   int page;
+   u32 udb;
+
+   dev_warn(adap->pdev_dev,
+"Dropped DB 0x%x qid %d bar2 %d coalesce %d pidx %d\n",
+dropped_db, qid,
+(dropped_db >> 14) & 1,
+(dropped_db >> 13) & 1,
+pidx_inc);
+
+   drain_db_fifo(adap, 1);
+
+   s_qpp = QUEUESPERPAGEPF1 * adap->fn;
+   udb_density = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adap,
+   SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp);
+   qpshift = PAGE_SHIFT - ilog2(udb_density);
+   udb = qid << qpshift;
+   udb &= PAGE_MASK;
+   page = udb / PAGE_SIZE;
+   udb += (qid - (page * udb_density)) * 128;
+
+   writel(PIDX(pidx_inc),  adap->bar2 + udb + 8);
+
+   /* Re-enable BAR2 WC */
+   t4_set_reg_field(adap, 0x10b0, 1<<15, 1<<15);
+   }
+
t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0);
-   disable_dbs(adap);
-   notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
-   drain_db_fifo(adap, 1);
-   recover_all_queues(adap);
-   enable_dbs(adap);
 }
 
 void t4_db_full(struct adapter *adap)
 {
-   t4_set_reg_field(adap, SGE_INT_ENABLE3,
-DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
-   queue_work(workq, &adap->db_full_task);
+   if (is_t4(adap->chip)) {
+   t4_set_reg_field(adap, SGE_INT_ENABLE3,
+DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
+   queue_work(workq, &adap->db_full_task);
+   }
 }
 
 void t4_db_dropped(struct adapter *adap)
 {
-   queue_work(workq, &adap->db_drop_task);
+   if (is_t4(adap->chip))
+   queue_work(workq, &adap->db_drop_task);
 }
 
 static void uld_attach(struct adapter *adap, unsigned int uld)
-- 
1.7.1

--
To unsubscribe from this list: send t

[PATCH v2 net-next 02/22] cxgb4: Add macros, structures and inline functions for T5

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h|   50 -
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h   |   45 ++
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h |2 +-
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 6db997c..a91dea6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -54,6 +54,10 @@
 #define FW_VERSION_MINOR 1
 #define FW_VERSION_MICRO 0
 
+#define FW_VERSION_MAJOR_T5 0
+#define FW_VERSION_MINOR_T5 0
+#define FW_VERSION_MICRO_T5 0
+
 #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
 
 enum {
@@ -66,7 +70,9 @@ enum {
 enum {
MEM_EDC0,
MEM_EDC1,
-   MEM_MC
+   MEM_MC,
+   MEM_MC0 = MEM_MC,
+   MEM_MC1
 };
 
 enum {
@@ -74,8 +80,10 @@ enum {
MEMWIN0_BASE = 0x1b800,
MEMWIN1_APERTURE = 32768,
MEMWIN1_BASE = 0x28000,
+   MEMWIN1_BASE_T5  = 0x52000,
MEMWIN2_APERTURE = 65536,
MEMWIN2_BASE = 0x3,
+   MEMWIN2_BASE_T5  = 0x54000,
 };
 
 enum dev_master {
@@ -504,6 +512,35 @@ struct sge {
 
 struct l2t_data;
 
+#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
+#define CHELSIO_CHIP_VERSION(code) ((code) >> 4)
+#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
+
+#define CHELSIO_T4 0x4
+#define CHELSIO_T5 0x5
+
+enum chip_type {
+   T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0),
+   T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
+   T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
+   T4_FIRST_REV= T4_A1,
+   T4_LAST_REV = T4_A3,
+
+   T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
+   T5_FIRST_REV= T5_A1,
+   T5_LAST_REV = T5_A1,
+};
+
+#ifdef CONFIG_PCI_IOV
+
+/* T4 - 4 PFs support SRIOV
+ * T5 - 8 PFs support SRIOV
+ */
+#define NUM_OF_PF_WITH_SRIOV_T4 4
+#define NUM_OF_PF_WITH_SRIOV_T5 8
+
+#endif
+
 struct adapter {
void __iomem *regs;
struct pci_dev *pdev;
@@ -511,6 +548,7 @@ struct adapter {
unsigned int mbox;
unsigned int fn;
unsigned int flags;
+   enum chip_type chip;
 
int msg_enable;
 
@@ -673,6 +711,16 @@ enum {
VLAN_REWRITE
 };
 
+static inline int is_t5(enum chip_type chip)
+{
+   return (chip >= T5_FIRST_REV && chip <= T5_LAST_REV);
+}
+
+static inline int is_t4(enum chip_type chip)
+{
+   return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV);
+}
+
 static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
 {
return readl(adap->regs + reg_addr);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h 
b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index 261d177..0c9f14f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -74,6 +74,7 @@ enum {
CPL_PASS_ESTABLISH= 0x41,
CPL_RX_DATA_DDP   = 0x42,
CPL_PASS_ACCEPT_REQ   = 0x44,
+   CPL_TRACE_PKT_T5  = 0x48,
 
CPL_RDMA_READ_REQ = 0x60,
 
@@ -287,6 +288,23 @@ struct cpl_act_open_req {
__be32 opt2;
 };
 
+#define S_FILTER_TUPLE  24
+#define M_FILTER_TUPLE  0xFF
+#define V_FILTER_TUPLE(x) ((x) << S_FILTER_TUPLE)
+#define G_FILTER_TUPLE(x) (((x) >> S_FILTER_TUPLE) & M_FILTER_TUPLE)
+struct cpl_t5_act_open_req {
+   WR_HDR;
+   union opcode_tid ot;
+   __be16 local_port;
+   __be16 peer_port;
+   __be32 local_ip;
+   __be32 peer_ip;
+   __be64 opt0;
+   __be32 rsvd;
+   __be32 opt2;
+   __be64 params;
+};
+
 struct cpl_act_open_req6 {
WR_HDR;
union opcode_tid ot;
@@ -566,6 +584,11 @@ struct cpl_rx_pkt {
 #define V_RX_ETHHDR_LEN(x) ((x) << S_RX_ETHHDR_LEN)
 #define G_RX_ETHHDR_LEN(x) (((x) >> S_RX_ETHHDR_LEN) & M_RX_ETHHDR_LEN)
 
+#define S_RX_T5_ETHHDR_LEN0
+#define M_RX_T5_ETHHDR_LEN0x3F
+#define V_RX_T5_ETHHDR_LEN(x) ((x) << S_RX_T5_ETHHDR_LEN)
+#define G_RX_T5_ETHHDR_LEN(x) (((x) >> S_RX_T5_ETHHDR_LEN) & 
M_RX_T5_ETHHDR_LEN)
+
 #define S_RX_MACIDX8
 #define M_RX_MACIDX0x1FF
 #define V_RX_MACIDX(x) ((x) << S_RX_MACIDX)
@@ -612,6 +635,28 @@ struct cpl_trace_pkt {
__be64 tstamp;
 };
 
+struct cpl_t5_trace_pkt {
+   __u8 opcode;
+   __u8 intf;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+   __u8 runt:4;
+   __u8 filter_hit:4;
+   __u8:6;
+   __u8 err:1;
+   __u8 trunc:1;
+#else
+   __u8 filter_hit:4;
+   __u8 runt:4;
+   __u8 trunc:1;
+   __u8 err:1;
+   __u8:6;
+#endif
+   __be16 rsvd;
+   __be16 len;
+   __be64 tstamp;
+   __be64 rsvd1;
+};
+
 struct cpl_l2t_write_req {
WR_HDR;
union opcode_tid ot;
diff --git a/drivers/net/etherne

[PATCH v2 net-next 16/22] RDMA/cxgb4: Map pbl buffers for dma if using DSGL.

2013-03-14 Thread Vipul Pandya
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/mem.c |   29 +++--
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/mem.c 
b/drivers/infiniband/hw/cxgb4/mem.c
index 33db9ee..4cb8eb2 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -51,7 +51,7 @@ module_param(inline_threshold, int, 0644);
 MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
 
 static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
-  u32 len, void *data, int wait)
+  u32 len, dma_addr_t data, int wait)
 {
struct sk_buff *skb;
struct ulp_mem_io *req;
@@ -88,7 +88,7 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev 
*rdev, u32 addr,
sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_DSGL) |
ULPTX_NSGE(1));
sgl->len0 = cpu_to_be32(len);
-   sgl->addr0 = cpu_to_be64(virt_to_phys(data));
+   sgl->addr0 = cpu_to_be64(data);
 
ret = c4iw_ofld_send(rdev, skb);
if (ret)
@@ -178,6 +178,13 @@ int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, 
u32 len, void *data)
u32 remain = len;
u32 dmalen;
int ret = 0;
+   dma_addr_t daddr;
+   dma_addr_t save;
+
+   daddr = dma_map_single(&rdev->lldi.pdev->dev, data, len, DMA_TO_DEVICE);
+   if (dma_mapping_error(&rdev->lldi.pdev->dev, daddr))
+   return -1;
+   save = daddr;
 
while (remain > inline_threshold) {
if (remain < T4_ULPTX_MAX_DMA) {
@@ -188,16 +195,18 @@ int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, 
u32 len, void *data)
} else
dmalen = T4_ULPTX_MAX_DMA;
remain -= dmalen;
-   ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, data,
+   ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, daddr,
 !remain);
if (ret)
goto out;
addr += dmalen >> 5;
data += dmalen;
+   daddr += dmalen;
}
if (remain)
ret = _c4iw_write_mem_inline(rdev, addr, remain, data);
 out:
+   dma_unmap_single(&rdev->lldi.pdev->dev, save, len, DMA_TO_DEVICE);
return ret;
 }
 
@@ -209,9 +218,17 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 
addr, u32 len,
 void *data)
 {
if (is_t5(rdev->lldi.adapter_type) && use_dsgl) {
-   if (len > inline_threshold)
-   return _c4iw_write_mem_dma(rdev, addr, len, data);
-   else
+   if (len > inline_threshold) {
+   if (_c4iw_write_mem_dma(rdev, addr, len, data)) {
+   printk_ratelimited(KERN_WARNING
+  "%s: dma map"
+  " failure (non fatal)\n",
+  pci_name(rdev->lldi.pdev));
+   return _c4iw_write_mem_inline(rdev, addr, len,
+ data);
+   } else
+   return 0;
+   } else
return _c4iw_write_mem_inline(rdev, addr, len, data);
} else
return _c4iw_write_mem_inline(rdev, addr, len, data);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 14/22] RDMA/cxgb4: Add module_params to enable DB FC & Coalescing on T5

2013-03-14 Thread Vipul Pandya
Both DB Flow-Control and DB Coalescing are disabled by default on T5

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/device.c   |   25 +++--
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |1 +
 drivers/infiniband/hw/cxgb4/qp.c   |   10 ++
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/device.c 
b/drivers/infiniband/hw/cxgb4/device.c
index 3487c08..ae65601 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -45,6 +45,16 @@ MODULE_DESCRIPTION("Chelsio T4/T5 RDMA Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 
+static int allow_db_fc_on_t5;
+module_param(allow_db_fc_on_t5, int, 0644);
+MODULE_PARM_DESC(allow_db_fc_on_t5,
+"Allow DB Flow Control on T5 (default = 0)");
+
+static int allow_db_coalescing_on_t5;
+module_param(allow_db_coalescing_on_t5, int, 0644);
+MODULE_PARM_DESC(allow_db_coalescing_on_t5,
+"Allow DB Coalescing on T5 (default = 0)");
+
 struct uld_ctx {
struct list_head entry;
struct cxgb4_lld_info lldi;
@@ -630,8 +640,19 @@ static struct c4iw_dev *c4iw_alloc(const struct 
cxgb4_lld_info *infop)
if (!ocqp_supported(infop))
pr_info("%s: On-Chip Queues not supported on this device.\n",
pci_name(infop->pdev));
-   if (!is_t4(infop->adapter_type))
-   db_fc_threshold = 10;
+
+   if (!is_t4(infop->adapter_type)) {
+   if (!allow_db_fc_on_t5) {
+   db_fc_threshold = 10;
+   pr_info("DB Flow Control Disabled.\n");
+   }
+
+   if (!allow_db_coalescing_on_t5) {
+   db_coalescing_threshold = -1;
+   pr_info("DB Coalescing Disabled.\n");
+   }
+   }
+
devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
if (!devp) {
printk(KERN_ERR MOD "Cannot allocate ib device\n");
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h 
b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 34c7e62..4dbe96a 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -939,6 +939,7 @@ extern struct cxgb4_client t4c_client;
 extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
 extern int c4iw_max_read_depth;
 extern int db_fc_threshold;
+extern int db_coalescing_threshold;
 
 
 #endif
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index da4869f..28592d4 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -1455,8 +1455,9 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
rhp->db_state = NORMAL;
idr_for_each(&rhp->qpidr, enable_qp_db, NULL);
}
-   if (rhp->qpcnt <= db_coalescing_threshold)
-   cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]);
+   if (db_coalescing_threshold >= 0)
+   if (rhp->qpcnt <= db_coalescing_threshold)
+   cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]);
spin_unlock_irq(&rhp->lock);
atomic_dec(&qhp->refcnt);
wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
@@ -1574,8 +1575,9 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct 
ib_qp_init_attr *attrs,
rhp->db_state = FLOW_CONTROL;
idr_for_each(&rhp->qpidr, disable_qp_db, NULL);
}
-   if (rhp->qpcnt > db_coalescing_threshold)
-   cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]);
+   if (db_coalescing_threshold >= 0)
+   if (rhp->qpcnt > db_coalescing_threshold)
+   cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]);
ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
spin_unlock_irq(&rhp->lock);
if (ret)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 12/22] RDMA/cxgb4: Add Support for Chelsio T5 adapter

2013-03-14 Thread Vipul Pandya
Adds support for Chelsio T5 adapter.
Enables T5's Write Combining feature.

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/infiniband/hw/cxgb4/cm.c   |   64 +++
 drivers/infiniband/hw/cxgb4/device.c   |   13 --
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |9 
 drivers/infiniband/hw/cxgb4/provider.c |   15 +--
 drivers/infiniband/hw/cxgb4/qp.c   |2 +-
 drivers/infiniband/hw/cxgb4/t4.h   |9 
 6 files changed, 77 insertions(+), 35 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 565bfb1..272bf78 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -511,12 +511,16 @@ static unsigned int select_ntuple(struct c4iw_dev *dev, 
struct dst_entry *dst,
 static int send_connect(struct c4iw_ep *ep)
 {
struct cpl_act_open_req *req;
+   struct cpl_t5_act_open_req *t5_req;
struct sk_buff *skb;
u64 opt0;
u32 opt2;
unsigned int mtu_idx;
int wscale;
-   int wrlen = roundup(sizeof *req, 16);
+   int size = is_t4(ep->com.dev->rdev.lldi.adapter_type) ?
+   sizeof(struct cpl_act_open_req) :
+   sizeof(struct cpl_t5_act_open_req);
+   int wrlen = roundup(size, 16);
 
PDBG("%s ep %p atid %u\n", __func__, ep, ep->atid);
 
@@ -552,17 +556,36 @@ static int send_connect(struct c4iw_ep *ep)
opt2 |= WND_SCALE_EN(1);
t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure);
 
-   req = (struct cpl_act_open_req *) skb_put(skb, wrlen);
-   INIT_TP_WR(req, 0);
-   OPCODE_TID(req) = cpu_to_be32(
-   MK_OPCODE_TID(CPL_ACT_OPEN_REQ, ((ep->rss_qid<<14)|ep->atid)));
-   req->local_port = ep->com.local_addr.sin_port;
-   req->peer_port = ep->com.remote_addr.sin_port;
-   req->local_ip = ep->com.local_addr.sin_addr.s_addr;
-   req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;
-   req->opt0 = cpu_to_be64(opt0);
-   req->params = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, ep->l2t));
-   req->opt2 = cpu_to_be32(opt2);
+   if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) {
+   req = (struct cpl_act_open_req *) skb_put(skb, wrlen);
+   INIT_TP_WR(req, 0);
+   OPCODE_TID(req) = cpu_to_be32(
+   MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
+   ((ep->rss_qid << 14) | ep->atid)));
+   req->local_port = ep->com.local_addr.sin_port;
+   req->peer_port = ep->com.remote_addr.sin_port;
+   req->local_ip = ep->com.local_addr.sin_addr.s_addr;
+   req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;
+   req->opt0 = cpu_to_be64(opt0);
+   req->params = cpu_to_be32(select_ntuple(ep->com.dev,
+   ep->dst, ep->l2t));
+   req->opt2 = cpu_to_be32(opt2);
+   } else {
+   t5_req = (struct cpl_t5_act_open_req *) skb_put(skb, wrlen);
+   INIT_TP_WR(t5_req, 0);
+   OPCODE_TID(t5_req) = cpu_to_be32(
+   MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
+   ((ep->rss_qid << 14) | ep->atid)));
+   t5_req->local_port = ep->com.local_addr.sin_port;
+   t5_req->peer_port = ep->com.remote_addr.sin_port;
+   t5_req->local_ip = ep->com.local_addr.sin_addr.s_addr;
+   t5_req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;
+   t5_req->opt0 = cpu_to_be64(opt0);
+   t5_req->params = cpu_to_be64(V_FILTER_TUPLE(
+   select_ntuple(ep->com.dev, ep->dst, ep->l2t)));
+   t5_req->opt2 = cpu_to_be32(opt2);
+   }
+
set_bit(ACT_OPEN_REQ, &ep->com.history);
return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
 }
@@ -2869,12 +2892,14 @@ static int deferred_fw6_msg(struct c4iw_dev *dev, 
struct sk_buff *skb)
 static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos)
 {
u32 l2info;
-   u16 vlantag, len, hdr_len;
+   u16 vlantag, len, hdr_len, eth_hdr_len;
u8 intf;
struct cpl_rx_pkt *cpl = cplhdr(skb);
struct cpl_pass_accept_req *req;
struct tcp_options_received tmp_opt;
+   struct c4iw_dev *dev;
 
+   dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
/* Store values from cpl_rx_pkt in temporary location. */
vlantag = (__force u16) cpl->vlan;
len = (__force u16) cpl->len;
@@ -2898,14 +2923,16 @@ static void build_cpl_pass_accept_req(struct sk_buff 
*skb, int stid , u8 tos)
 V_SYN_MAC_IDX(G_RX_MACIDX(
 (__force int) htonl(l2info))) |
 F_SYN_XACT_MATCH);
+   eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ?
+  

[PATCH v2 net-next 11/22] cxgb4vf: Add support for Chelsio T5 adapter

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4vf/adapter.h |1 +
 .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|   35 ++--
 drivers/net/ethernet/chelsio/cxgb4vf/sge.c |8 +++-
 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |   24 +
 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c |   14 ++--
 5 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h 
b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 68eaa9c..be5c7ef 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -344,6 +344,7 @@ struct adapter {
unsigned long registered_device_map;
unsigned long open_device_map;
unsigned long flags;
+   enum chip_type chip;
struct adapter_params params;
 
/* queue and interrupt resources */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 56b46ab..7fcac20 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -54,8 +54,8 @@
 /*
  * Generic information about the driver.
  */
-#define DRV_VERSION "1.0.0"
-#define DRV_DESC "Chelsio T4 Virtual Function (VF) Network Driver"
+#define DRV_VERSION "2.0.0-ko"
+#define DRV_DESC "Chelsio T4/T5 Virtual Function (VF) Network Driver"
 
 /*
  * Module Parameters.
@@ -1050,7 +1050,7 @@ static inline unsigned int mk_adap_vers(const struct 
adapter *adapter)
/*
 * Chip version 4, revision 0x3f (cxgb4vf).
 */
-   return 4 | (0x3f << 10);
+   return CHELSIO_CHIP_VERSION(adapter->chip) | (0x3f << 10);
 }
 
 /*
@@ -2099,6 +2099,15 @@ static int adap_init0(struct adapter *adapter)
return err;
}
 
+   switch (adapter->pdev->device >> 12) {
+   case CHELSIO_T4:
+   adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0);
+   break;
+   case CHELSIO_T5:
+   adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, 0);
+   break;
+   }
+
/*
 * Grab basic operational parameters.  These will predominantly have
 * been set up by the Physical Function Driver or will be hard coded
@@ -2888,6 +2897,26 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = {
CH_DEVICE(0x480a, 0),   /* T404-bt */
CH_DEVICE(0x480d, 0),   /* T480-cr */
CH_DEVICE(0x480e, 0),   /* T440-lp-cr */
+   CH_DEVICE(0x5800, 0),   /* T580-dbg */
+   CH_DEVICE(0x5801, 0),   /* T520-cr */
+   CH_DEVICE(0x5802, 0),   /* T522-cr */
+   CH_DEVICE(0x5803, 0),   /* T540-cr */
+   CH_DEVICE(0x5804, 0),   /* T520-bch */
+   CH_DEVICE(0x5805, 0),   /* T540-bch */
+   CH_DEVICE(0x5806, 0),   /* T540-ch */
+   CH_DEVICE(0x5807, 0),   /* T520-so */
+   CH_DEVICE(0x5808, 0),   /* T520-cx */
+   CH_DEVICE(0x5809, 0),   /* T520-bt */
+   CH_DEVICE(0x580a, 0),   /* T504-bt */
+   CH_DEVICE(0x580b, 0),   /* T520-sr */
+   CH_DEVICE(0x580c, 0),   /* T504-bt */
+   CH_DEVICE(0x580d, 0),   /* T580-cr */
+   CH_DEVICE(0x580e, 0),   /* T540-lp-cr */
+   CH_DEVICE(0x580f, 0),   /* Amsterdam */
+   CH_DEVICE(0x5810, 0),   /* T580-lp-cr */
+   CH_DEVICE(0x5811, 0),   /* T520-lp-cr */
+   CH_DEVICE(0x5812, 0),   /* T560-cr */
+   CH_DEVICE(0x5813, 0),   /* T580-cr */
{ 0, }
 };
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index 9488032..61dfb2a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -528,17 +528,21 @@ static void unmap_rx_buf(struct adapter *adapter, struct 
sge_fl *fl)
  */
 static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl)
 {
+   u32 val;
+
/*
 * The SGE keeps track of its Producer and Consumer Indices in terms
 * of Egress Queue Units so we can only tell it about integral numbers
 * of multiples of Free List Entries per Egress Queue Units ...
 */
if (fl->pend_cred >= FL_PER_EQ_UNIT) {
+   val = PIDX(fl->pend_cred / FL_PER_EQ_UNIT);
+   if (!is_t4(adapter->chip))
+   val |= DBTYPE(1);
wmb();
t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
 DBPRIO(1) |
-QID(fl->cntxt_id) |
-PIDX(fl->pend_cred / FL_PER_EQ_UNIT));
+QID(fl->cntxt_id) | val);
fl->pend_cred %= FL_PER_EQ_UNIT;
}
 }
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h 
b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
index

[PATCH v2 net-next 10/22] cxgb4: Disable SR-IOV support for PF4-7 for T5

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

All T5 adapters will only support VFs on PF0-3 despite the ability of the
hardware to support them on PF4-7.  This keeps our T4 and T5 adapters more
similar which simplifies host driver software.

Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h  |8 
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   21 ++---
 2 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 45b18bd..681804b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -534,11 +534,11 @@ enum chip_type {
 
 #ifdef CONFIG_PCI_IOV
 
-/* T4 - 4 PFs support SRIOV
- * T5 - 8 PFs support SRIOV
+/* T4 supports SRIOV on PF0-3 and T5 on PF0-7.  However, the Serial
+ * Configuration initialization for T5 only has SR-IOV functionality enabled
+ * on PF0-3 in order to simplify everything.
  */
-#define NUM_OF_PF_WITH_SRIOV_T4 4
-#define NUM_OF_PF_WITH_SRIOV_T5 8
+#define NUM_OF_PF_WITH_SRIOV 4
 
 #endif
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index c502e36..a59bb23 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -360,14 +360,13 @@ static bool vf_acls;
 module_param(vf_acls, bool, 0644);
 MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");
 
-/* Since T5 has more num of PFs, using NUM_OF_PF_WITH_SRIOV_T5
- * macro as num_vf array size
+/* Configure the number of PCI-E Virtual Function which are to be instantiated
+ * on SR-IOV Capable Physical Functions.
  */
-static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV_T5];
+static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV];
 
 module_param_array(num_vf, uint, NULL, 0644);
-MODULE_PARM_DESC(num_vf,
-"number of VFs for each of PFs 0-3 for T4 and PFs 0-7 for T5");
+MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
 #endif
 
 /*
@@ -4633,10 +4632,8 @@ static int adap_init0_no_config(struct adapter *adapter, 
int reset)
 */
{
int pf, vf;
-   int max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 :
-   NUM_OF_PF_WITH_SRIOV_T5;
 
-   for (pf = 0; pf < max_no_pf; pf++) {
+   for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) {
if (num_vf[pf] <= 0)
continue;
 
@@ -5483,9 +5480,6 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
struct port_info *pi;
bool highdma = false;
struct adapter *adapter = NULL;
-#ifdef CONFIG_PCI_IOV
-   int max_no_pf;
-#endif
 
printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
 
@@ -5704,10 +5698,7 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
 sriov:
 #ifdef CONFIG_PCI_IOV
-   max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 :
-   NUM_OF_PF_WITH_SRIOV_T5;
-
-   if (func < max_no_pf && num_vf[func] > 0)
+   if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
if (pci_enable_sriov(pdev, num_vf[func]) == 0)
dev_info(&pdev->dev,
 "instantiated %u virtual functions\n",
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 08/22] cxgb4: Add T5 PCI ids

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   38 +++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index ca88070..eceee44 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -229,6 +229,44 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0x440a, 4),
CH_DEVICE(0x440d, 4),
CH_DEVICE(0x440e, 4),
+   CH_DEVICE(0x5001, 5),
+   CH_DEVICE(0x5002, 5),
+   CH_DEVICE(0x5003, 5),
+   CH_DEVICE(0x5004, 5),
+   CH_DEVICE(0x5005, 5),
+   CH_DEVICE(0x5006, 5),
+   CH_DEVICE(0x5007, 5),
+   CH_DEVICE(0x5008, 5),
+   CH_DEVICE(0x5009, 5),
+   CH_DEVICE(0x500A, 5),
+   CH_DEVICE(0x500B, 5),
+   CH_DEVICE(0x500C, 5),
+   CH_DEVICE(0x500D, 5),
+   CH_DEVICE(0x500E, 5),
+   CH_DEVICE(0x500F, 5),
+   CH_DEVICE(0x5010, 5),
+   CH_DEVICE(0x5011, 5),
+   CH_DEVICE(0x5012, 5),
+   CH_DEVICE(0x5013, 5),
+   CH_DEVICE(0x5401, 5),
+   CH_DEVICE(0x5402, 5),
+   CH_DEVICE(0x5403, 5),
+   CH_DEVICE(0x5404, 5),
+   CH_DEVICE(0x5405, 5),
+   CH_DEVICE(0x5406, 5),
+   CH_DEVICE(0x5407, 5),
+   CH_DEVICE(0x5408, 5),
+   CH_DEVICE(0x5409, 5),
+   CH_DEVICE(0x540A, 5),
+   CH_DEVICE(0x540B, 5),
+   CH_DEVICE(0x540C, 5),
+   CH_DEVICE(0x540D, 5),
+   CH_DEVICE(0x540E, 5),
+   CH_DEVICE(0x540F, 5),
+   CH_DEVICE(0x5410, 5),
+   CH_DEVICE(0x5411, 5),
+   CH_DEVICE(0x5412, 5),
+   CH_DEVICE(0x5413, 5),
{ 0, }
 };
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 net-next 04/22] cxgb4: Dump T5 registers

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |  452 ++-
 1 files changed, 448 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index dd7bcc2..3d6d23a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1340,10 +1340,15 @@ static int get_sset_count(struct net_device *dev, int 
sset)
 }
 
 #define T4_REGMAP_SIZE (160 * 1024)
+#define T5_REGMAP_SIZE (332 * 1024)
 
 static int get_regs_len(struct net_device *dev)
 {
-   return T4_REGMAP_SIZE;
+   struct adapter *adap = netdev2adap(dev);
+   if (is_t4(adap->chip))
+   return T4_REGMAP_SIZE;
+   else
+   return T5_REGMAP_SIZE;
 }
 
 static int get_eeprom_len(struct net_device *dev)
@@ -1448,7 +1453,7 @@ static void reg_block_dump(struct adapter *ap, void *buf, 
unsigned int start,
 static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
 void *buf)
 {
-   static const unsigned int reg_ranges[] = {
+   static const unsigned int t4_reg_ranges[] = {
0x1008, 0x1108,
0x1180, 0x11b4,
0x11fc, 0x123c,
@@ -1668,13 +1673,452 @@ static void get_regs(struct net_device *dev, struct 
ethtool_regs *regs,
0x27e00, 0x27e04
};
 
+   static const unsigned int t5_reg_ranges[] = {
+   0x1008, 0x1148,
+   0x1180, 0x11b4,
+   0x11fc, 0x123c,
+   0x1280, 0x173c,
+   0x1800, 0x18fc,
+   0x3000, 0x3028,
+   0x3060, 0x30d8,
+   0x30e0, 0x30fc,
+   0x3140, 0x357c,
+   0x35a8, 0x35cc,
+   0x35ec, 0x35ec,
+   0x3600, 0x5624,
+   0x56cc, 0x575c,
+   0x580c, 0x5814,
+   0x5890, 0x58bc,
+   0x5940, 0x59dc,
+   0x59fc, 0x5a18,
+   0x5a60, 0x5a9c,
+   0x5b9c, 0x5bfc,
+   0x6000, 0x6040,
+   0x6058, 0x614c,
+   0x7700, 0x7798,
+   0x77c0, 0x78fc,
+   0x7b00, 0x7c54,
+   0x7d00, 0x7efc,
+   0x8dc0, 0x8de0,
+   0x8df8, 0x8e84,
+   0x8ea0, 0x8f84,
+   0x8fc0, 0x90f8,
+   0x9400, 0x9470,
+   0x9600, 0x96f4,
+   0x9800, 0x9808,
+   0x9820, 0x983c,
+   0x9850, 0x9864,
+   0x9c00, 0x9c6c,
+   0x9c80, 0x9cec,
+   0x9d00, 0x9d6c,
+   0x9d80, 0x9dec,
+   0x9e00, 0x9e6c,
+   0x9e80, 0x9eec,
+   0x9f00, 0x9f6c,
+   0x9f80, 0xa020,
+   0xd004, 0xd03c,
+   0xdfc0, 0xdfe0,
+   0xe000, 0x11088,
+   0x1109c, 0x1117c,
+   0x11190, 0x11204,
+   0x19040, 0x1906c,
+   0x19078, 0x19080,
+   0x1908c, 0x19124,
+   0x19150, 0x191b0,
+   0x191d0, 0x191e8,
+   0x19238, 0x19290,
+   0x193f8, 0x19474,
+   0x19490, 0x194cc,
+   0x194f0, 0x194f8,
+   0x19c00, 0x19c60,
+   0x19c94, 0x19e10,
+   0x19e50, 0x19f34,
+   0x19f40, 0x19f50,
+   0x19f90, 0x19fe4,
+   0x1a000, 0x1a06c,
+   0x1a0b0, 0x1a120,
+   0x1a128, 0x1a138,
+   0x1a190, 0x1a1c4,
+   0x1a1fc, 0x1a1fc,
+   0x1e008, 0x1e00c,
+   0x1e040, 0x1e04c,
+   0x1e284, 0x1e290,
+   0x1e2c0, 0x1e2c0,
+   0x1e2e0, 0x1e2e0,
+   0x1e300, 0x1e384,
+   0x1e3c0, 0x1e3c8,
+   0x1e408, 0x1e40c,
+   0x1e440, 0x1e44c,
+   0x1e684, 0x1e690,
+   0x1e6c0, 0x1e6c0,
+   0x1e6e0, 0x1e6e0,
+   0x1e700, 0x1e784,
+   0x1e7c0, 0x1e7c8,
+   0x1e808, 0x1e80c,
+   0x1e840, 0x1e84c,
+   0x1ea84, 0x1ea90,
+   0x1eac0, 0x1eac0,
+   0x1eae0, 0x1eae0,
+   0x1eb00, 0x1eb84,
+   0x1ebc0, 0x1ebc8,
+   0x1ec08, 0x1ec0c,
+   0x1ec40, 0x1ec4c,
+   0x1ee84, 0x1ee90,
+   0x1eec0, 0x1eec0,
+   0x1eee0, 0x1eee0,
+   0x1ef00, 0x1ef84,
+   0x1efc0, 0x1efc8,
+   0x1f008, 0x1f00c,
+   0x1f040, 0x1f04c,
+   0x1f284, 0x1f290,
+   0x1f2c0, 0x1f2c0,
+   0x1f2e0, 0x1f2e0,
+   0x1f300, 0x1f384,
+   0x1f3c0, 0x1f3c8,
+   0x1f408, 0x1f40c,

[PATCH v2 net-next 03/22] cxgb4: Initialize T5

2013-03-14 Thread Vipul Pandya
From: Santosh Rastapur 

Signed-off-by: Santosh Rastapur 
Signed-off-by: Vipul Pandya 
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   85 ++---
 drivers/net/ethernet/chelsio/cxgb4/sge.c|   37 --
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c  |  152 ---
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.h  |1 -
 4 files changed, 227 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index e707e31..dd7bcc2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -233,7 +233,9 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
 };
 
 #define FW_FNAME "cxgb4/t4fw.bin"
+#define FW5_FNAME "cxgb4/t5fw.bin"
 #define FW_CFNAME "cxgb4/t4-config.txt"
+#define FW5_CFNAME "cxgb4/t5-config.txt"
 
 MODULE_DESCRIPTION(DRV_DESC);
 MODULE_AUTHOR("Chelsio Communications");
@@ -241,6 +243,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
 MODULE_FIRMWARE(FW_FNAME);
+MODULE_FIRMWARE(FW5_FNAME);
 
 /*
  * Normally we're willing to become the firmware's Master PF but will be happy
@@ -319,10 +322,14 @@ static bool vf_acls;
 module_param(vf_acls, bool, 0644);
 MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");
 
-static unsigned int num_vf[4];
+/* Since T5 has more num of PFs, using NUM_OF_PF_WITH_SRIOV_T5
+ * macro as num_vf array size
+ */
+static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV_T5];
 
 module_param_array(num_vf, uint, NULL, 0644);
-MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
+MODULE_PARM_DESC(num_vf,
+"number of VFs for each of PFs 0-3 for T4 and PFs 0-7 for T5");
 #endif
 
 /*
@@ -1002,21 +1009,36 @@ freeout:t4_free_sge_resources(adap);
 static int upgrade_fw(struct adapter *adap)
 {
int ret;
-   u32 vers;
+   u32 vers, exp_major;
const struct fw_hdr *hdr;
const struct firmware *fw;
struct device *dev = adap->pdev_dev;
+   char *fw_file_name;
 
-   ret = request_firmware(&fw, FW_FNAME, dev);
+   switch (CHELSIO_CHIP_VERSION(adap->chip)) {
+   case CHELSIO_T4:
+   fw_file_name = FW_FNAME;
+   exp_major = FW_VERSION_MAJOR;
+   break;
+   case CHELSIO_T5:
+   fw_file_name = FW5_FNAME;
+   exp_major = FW_VERSION_MAJOR_T5;
+   break;
+   default:
+   dev_err(dev, "Unsupported chip type, %x\n", adap->chip);
+   return -EINVAL;
+   }
+
+   ret = request_firmware(&fw, fw_file_name, dev);
if (ret < 0) {
-   dev_err(dev, "unable to load firmware image " FW_FNAME
-   ", error %d\n", ret);
+   dev_err(dev, "unable to load firmware image %s, error %d\n",
+   fw_file_name, ret);
return ret;
}
 
hdr = (const struct fw_hdr *)fw->data;
vers = ntohl(hdr->fw_ver);
-   if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) {
+   if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) {
ret = -EINVAL;  /* wrong major version, won't do */
goto out;
}
@@ -1024,18 +1046,15 @@ static int upgrade_fw(struct adapter *adap)
/*
 * If the flash FW is unusable or we found something newer, load it.
 */
-   if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR ||
+   if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major ||
vers > adap->params.fw_vers) {
dev_info(dev, "upgrading firmware ...\n");
ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size,
/*force=*/false);
if (!ret)
-   dev_info(dev, "firmware successfully upgraded to "
-FW_FNAME " (%d.%d.%d.%d)\n",
-FW_HDR_FW_VER_MAJOR_GET(vers),
-FW_HDR_FW_VER_MINOR_GET(vers),
-FW_HDR_FW_VER_MICRO_GET(vers),
-FW_HDR_FW_VER_BUILD_GET(vers));
+   dev_info(dev,
+"firmware upgraded to version %pI4 from %s\n",
+&hdr->fw_ver, fw_file_name);
else
dev_err(dev, "firmware upgrade failed! err=%d\n", -ret);
} else {
@@ -1413,7 +1432,8 @@ static void get_stats(struct net_device *dev, struct 
ethtool_stats *stats,
  */
 static inline unsigned int mk_adap_vers(const struct adapter *ap)
 {
-   return 4 | (ap->params.rev << 10) | (1 << 16);
+   return CHELSIO_CHIP_VERSION(ap->chip) |
+   (CHELSIO_CHIP_RELEASE(ap->chip) << 10) 

[PATCH v2 net-next 00/22] Add support for Chelsio T5 adapter

2013-03-14 Thread Vipul Pandya
Hi All,

This patch series adds support for Chelsio's T5 adapter. It also adds support
for new features of T5. It adds these in cxgb4, cxgb4vf, RDMA/cxgb4 and
csiostor drivers.

Chelsio's T5 asic moves the architecture into 40GbE speeds. T5 is a 10/40GbE
controller with full offload support of a complete Unified Wire solution
comprising NIC, Virtualization, TOE, iWARP RDMA and FCoE.

T5 supports all the offload, virtualization and switching capabilities of the
existing T4 and adds some new features. The patch series does basic
intialization for T5 in each driver. The patch series implements a low
latency Write Combining work request path in cxgb4 and RDMA/cxgb4 driver for
T5. It supports new T5 feature DSGL in RDMA/cxgb4 driver which enables direct
DMA by HW to memory region PBL arrays and fast register PBL arrays from host
memory. It adds support for dumping T5 registers, T5's debugfs support and
enables doorbell drop recovery only for T4 in cxgb4 driver.

To facilitate addition of support in csiostor for future adapters, a new
framework for adapter specific operations has been defined. Consequently, T4
and T5 specific operations are now separated into different files. One of the
csiostor patches also includes common bug fixes.

We are submitting changes in all the drivers for T5 in one series since there
are common changes in cxgb4 driver which are required by all the ULDs and
csiostor. This way we can avoid build failures, build dependencies and ensure
smooth integration.

We request to merge this patch series via David Miller's net-next tree. We are
copying respective maintainers of all the drivers for reviewing the changes.
Kindly let us know in case of any review comments.

We have successfully carried out networking, virtualization, iWARP and storage
related stress tests on this patch series.

Thanks,
Vipul Pandya

v2: Replaced #ifdef with portable interface wmb in ring_tx_db

Arvind Bhushan (4):
  csiostor: Segregate T4 adapter operations.
  csiostor: Add T5 adapter operations.
  csiostor: Header file modifications for chip support and bug fixes.
  csiostor: Cleanup chip specific operations.

Santosh Rastapur (11):
  cxgb4: Add register definations for T5
  cxgb4: Add macros, structures and inline functions for T5
  cxgb4: Initialize T5
  cxgb4: Dump T5 registers
  cxgb4: Add T5 write combining support
  cxgb4: Enable doorbell drop recovery only for T4 adapter
  cxgb4: Add T5 debugfs support
  cxgb4: Add T5 PCI ids
  cxgb4: Update driver version and description
  cxgb4: Disable SR-IOV support for PF4-7 for T5
  cxgb4vf: Add support for Chelsio T5 adapter

Vipul Pandya (7):
  RDMA/cxgb4: Add Support for Chelsio T5 adapter
  RDMA/cxgb4: Turn off db coalescing when RDMA QPs are in use.
  RDMA/cxgb4: Add module_params to enable DB FC & Coalescing on T5
  RDMA/cxgb4: Use DSGLs for fastreg and adapter memory writes for T5.
  RDMA/cxgb4: Map pbl buffers for dma if using DSGL.
  RDMA/cxgb4: Bump tcam_full stat and WR reply timeout
  RDMA/cxgb4: Fix onchip queue support for T5

 drivers/infiniband/hw/cxgb4/cm.c   |   66 ++-
 drivers/infiniband/hw/cxgb4/device.c   |   34 +-
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   14 +-
 drivers/infiniband/hw/cxgb4/mem.c  |  155 -
 drivers/infiniband/hw/cxgb4/provider.c |   15 +-
 drivers/infiniband/hw/cxgb4/qp.c   |  113 ++-
 drivers/infiniband/hw/cxgb4/t4.h   |   11 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |   55 ++-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c|  778 ++--
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h |3 +
 drivers/net/ethernet/chelsio/cxgb4/sge.c   |   89 ++-
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c |  256 ++--
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.h |1 -
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h|   53 ++
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h   |   98 +++
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h  |2 +-
 drivers/net/ethernet/chelsio/cxgb4vf/adapter.h |1 +
 .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|   35 +-
 drivers/net/ethernet/chelsio/cxgb4vf/sge.c |8 +-
 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h |   24 +
 drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c |   14 +-
 drivers/scsi/csiostor/Makefile |3 +-
 drivers/scsi/csiostor/csio_hw.c|  559 +++---
 drivers/scsi/csiostor/csio_hw.h|   47 +-
 drivers/scsi/csiostor/csio_hw_chip.h   |  175 +
 drivers/scsi/csiostor/csio_hw_t4.c |  403 ++
 drivers/scsi/csiostor/csio_hw_t5.c |  397 ++
 drivers/scsi/csiostor/csio_init.c  |   48 +-
 drivers/scsi/csiostor/csio_init.h  |   29 +-
 drivers/scsi/csiostor/csio_lnode.h |2 +-
 drivers/scsi/csiostor/csio_rnode.c 

Re: [patch] [SCSI] mpt3sas: move dereference under check

2013-03-14 Thread Dan Carpenter
On Thu, Mar 14, 2013 at 06:52:35PM +0530, Reddy, Sreekanth wrote:
> Hi Dan Carpenter,
> 
> While analyzing this patch, I have added some debugging prints to
> print the address referenced by the IOC->sense_dma_pool before and
> after pci_pool_free() API and I have observed that the address
> referenced by this pointer is same before and after calling
> pci_pool_free() API.  Please let me know if you have any case
> where you have seen ioc->sense_dma_pool is dereferenced after
> calling pci_pool_free API.
> 
> And we are checking this ioc->sense_dma_pool pointer to NULL value
> for safe side even it is not assigned to NULL value anywhere in
> the driver code.

Thanks for looking at this.

I hope you don't mind, but I've added linux-scsi back to the CC.

This is a static checker which is complaining that the code is not
checking for NULL consistently.  If "ioc->sense_dma_pool" is NULL
then we will crash inside pci_pool_free().  The NULL dereference is
on the line where we do:

mm/dmapool.c
   391  void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
   392  {
   393  struct dma_page *page;
   394  unsigned long flags;
   395  unsigned int offset;
   396  
   397  spin_lock_irqsave(&pool->lock, flags);
  ^^^
This dereference will cause a crash because we call pci_pool_free()
without testing for NULL.

   398  page = pool_find_page(pool, dma);

In other words:

drivers/scsi/mpt3sas/mpt3sas_base.c
  2481  if (ioc->sense) {
  2482  pci_pool_free(ioc->sense_dma_pool, ioc->sense, 
ioc->sense_dma);
^
We crash on this line before we reach the NULL test on the next
line.

  2483  if (ioc->sense_dma_pool)
  2484  pci_pool_destroy(ioc->sense_dma_pool);

I've looked at the code, and you're right that if (ioc->sense) {
is non-NULL that means ->sense_dma_pool is non-NULL.  ioc->sense is
allocated from the DMA pool.

I would like to just remove the test and silence the warning
message.

regards,
dan carpenter

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 10/11] iser-target: Add logic for core

2013-03-14 Thread Or Gerlitz

On 08/03/2013 03:45, Nicholas A. Bellinger wrote:

+void
+iser_cq_tx_tasklet(unsigned long data)
+{
+   struct isert_conn *isert_conn = (struct isert_conn *)data;
+   struct ib_cq *tx_cq = isert_conn->conn_tx_cq;
+   struct iser_tx_desc *tx_desc;
+   struct ib_wc wc;
+
+   while (ib_poll_cq(tx_cq, 1, &wc) == 1) {
+   tx_desc = (struct iser_tx_desc *)(unsigned long)wc.wr_id;
+
+   if (wc.status == IB_WC_SUCCESS) {
+   isert_send_completion(tx_desc, isert_conn);
+   } else {
+   pr_debug("TX wc.status != IB_WC_SUCCESS 
>>\n");
+   isert_dump_ib_wc(&wc);
+   atomic_dec(&isert_conn->post_send_buf_count);
+   isert_cq_comp_err(tx_desc, isert_conn);
+   }
+   }
+
+   ib_req_notify_cq(tx_cq, IB_CQ_NEXT_COMP);
+}
+
+void
+isert_cq_tx_callback(struct ib_cq *cq, void *context)
+{
+   struct isert_conn *isert_conn = context;
+
+   tasklet_schedule(&isert_conn->conn_tx_tasklet);
+}
+
+void
+iser_cq_rx_tasklet(unsigned long data)
+{
+   struct isert_conn *isert_conn = (struct isert_conn *)data;
+   struct ib_cq *rx_cq = isert_conn->conn_rx_cq;
+   struct iser_rx_desc *rx_desc;
+   struct ib_wc wc;
+   unsigned long xfer_len;
+
+   while (ib_poll_cq(rx_cq, 1, &wc) == 1) {
+   rx_desc = (struct iser_rx_desc *)(unsigned long)wc.wr_id;
+
+   if (wc.status == IB_WC_SUCCESS) {
+   xfer_len = (unsigned long)wc.byte_len;
+   isert_rx_completion(rx_desc, isert_conn, xfer_len);
+   } else {
+   pr_debug("RX wc.status != IB_WC_SUCCESS 
>>\n");
+   if (wc.status != IB_WC_WR_FLUSH_ERR)
+   isert_dump_ib_wc(&wc);
+
+   isert_conn->post_recv_buf_count--;
+   isert_cq_comp_err(NULL, isert_conn);
+   }
+   }
+
+   ib_req_notify_cq(rx_cq, IB_CQ_NEXT_COMP);
+}


We currently have here the following sequence of calls


isert_cq_rx_callback --> tasklet_schedule ...  --> ...
ib_poll_cq -->  isert_rx_completion --> isert_rx_queue_desc --> 
isert_rx_queue_desc --> queue_work (context switch)


isert_cq_tx_callback --> tasklet_schedule ...  --> ...
ib_poll_cq -->  isert_send_completion --> isert_completion_rdma_read 
-->  queue_work (context switch)


which means we have one context switch from the CQ callback to tasklet 
and then a PER IO context switch
from the tasklet to a kernel thread context which you might need for IO 
submission into the backing store.


This can be optimized by having one context switch from the isert cq 
callbacks to a kernel thread, with the work
item being "do polling" and then from the cq polling code do the 
submission into the backing store without

any further context switches.

Or.




+
+void
+isert_cq_rx_callback(struct ib_cq *cq, void *context)
+{
+   struct isert_conn *isert_conn = context;
+
+   tasklet_schedule(&isert_conn->conn_rx_tasklet);
+}


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 09/11] iser-target: Add logic for verbs

2013-03-14 Thread Or Gerlitz

On 08/03/2013 03:45, Nicholas A. Bellinger wrote:

isert_conn->conn_rx_cq = ib_create_cq(ib_dev, isert_cq_rx_callback,
+   isert_cq_event_callback,
+   (void *)isert_conn,
+   ISER_MAX_RX_CQ_LEN, 0);

[...]

+
+   isert_conn->conn_tx_cq = ib_create_cq(ib_dev, isert_cq_tx_callback,
+   isert_cq_event_callback,
+   (void *)isert_conn,
+   ISER_MAX_TX_CQ_LEN, 0);


Two comments here:

1. This code always attaches the CQ to vector #0 of the IB device. 
Typically vectors are associated with IRQs and IRQs are
"affiniated" with cores, so processing of completions for all 
connections will be carried out on single core at a given time.


What can be done here is to use different vectors for different CQs. The 
possible vector values are from 0 to ib_dev->num_comp_vectors - 1


2. A dedicated CQ pair is used per connection which might not scale well.

What can be done here, is to use a global context per IB device which 
holds a pool of CQs (created on different vectors, per the previous item),
and for each new connection, attach its QP to a CQ pair from this pool, 
e.g as done in drivers/infiniband/ulp/iser/iser_verbs.c :: 
iser_create_device_ib_res()
note that FWIW this context can hold also a global PD and DMA_MR objects 
to be used by all the connections opened on the device. The context can 
be opened on demand (1st connection that hits this IB device) and closed 
on non-demand (last connection).



Or.



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2 05/12] pm80xx: MSI-X implementation for using 64 interrupts

2013-03-14 Thread Hannes Reinecke

Sorry for the late reply.

On 03/14/2013 12:04 PM, Anand wrote:

 From 62b6f575d1978a965339c69158bd10d0529815fb Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:20:19 +0530
Subject: [PATCH V2 05/12] pm80xx: MSI-X implementation for using 64 interrupts

Implementation of interrupt handlers and tasklets to support
upto 64 interrupt for the device.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
  drivers/scsi/pm8001/pm8001_init.c |  456 +++--
  drivers/scsi/pm8001/pm8001_sas.h  |1 +
  2 files changed, 432 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index e8a983f..95b6966 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -163,24 +163,33 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
  }

  #ifdef PM8001_USE_TASKLET
+
+/**
+ * tasklet for 64 msi-x interrupt handler
+ * @opaque: the passed general host adapter struct
+ * Note: pm8001_tasklet is common for pm8001 & pm80xx
+ */
  static void pm8001_tasklet(unsigned long opaque)
  {
struct pm8001_hba_info *pm8001_ha;
+   u32 vec;
pm8001_ha = (struct pm8001_hba_info *)opaque;
if (unlikely(!pm8001_ha))
BUG_ON(1);
-   PM8001_CHIP_DISP->isr(pm8001_ha, 0);
+   vec = pm8001_ha->int_vector;
+   PM8001_CHIP_DISP->isr(pm8001_ha, vec);
  }
  #endif

+/**
+ * pm8001_interrupt_handler_x -main interrupt handler invokde for all 
interrupt.
+ * It obtains the vector number and calls the equivalent bottom half or 
services
+ * directly.
+ * @vec: vector number; will be 0 for none msi-x operation
+ * @opaque: the passed general host adapter struct
+ */

- /**
-  * pm8001_interrupt - when HBA originate a interrupt,we should invoke this
-  * dispatcher to handle each case.
-  * @irq: irq number.
-  * @opaque: the passed general host adapter struct
-  */
-static irqreturn_t pm8001_interrupt(int irq, void *opaque)
+static inline irqreturn_t pm8001_interrupt_handler_x(int vec, void *opaque)
  {
struct pm8001_hba_info *pm8001_ha;
irqreturn_t ret = IRQ_HANDLED;
@@ -190,6 +199,7 @@ static irqreturn_t pm8001_interrupt(int irq, void *opaque)
return IRQ_NONE;
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
return IRQ_NONE;
+   pm8001_ha->int_vector = vec;
  #ifdef PM8001_USE_TASKLET
tasklet_schedule(&pm8001_ha->tasklet);
  #else
@@ -198,6 +208,365 @@ static irqreturn_t pm8001_interrupt(int irq, void *opaque)
return ret;
  }

+/* 64 interrupt handlers for 64 msi-x vectors */
+static irqreturn_t pm8001_interrupt_handler0(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(0, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler1(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(1, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler2(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(2, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler3(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(3, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler4(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(4, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler5(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(5, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler6(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(6, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler7(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(7, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler8(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(8, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler9(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(9, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler10(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(10, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler11(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(11, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler12(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(12, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler13(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(13, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler14(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(14, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler15(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(15, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler16(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(16, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler17(int irq, void *dev_id)
+{
+

Re: [RFC 09/11] iser-target: Add logic for verbs

2013-03-14 Thread Or Gerlitz

On 08/03/2013 03:45, Nicholas A. Bellinger wrote:

+++ b/drivers/infiniband/ulp/isert/isert_verbs.c
+#define ISERT_ADDR_ROUTE_TIMEOUT 1000


remove this define, its irrelevant and you don't use that anywhere


+static void
+isert_qp_event_callback(struct ib_event *e, void *context)
+{
+   pr_err("isert_qp_event_callback event: %d\n", e->event);
+}


To be on the safe side, when the event is IB_EVENT_COMM_EST (which means 
that the login request was received by the HCA before the connection was 
fully established), call rdma_notify (id, IB_EVENT_COMM_EST) with the id 
being the one pointed from qp->qp_context->isert_conn




+
+static int
+isert_query_device(struct ib_device *ib_dev, struct ib_device_attr *devattr)
+{
+   int ret;
+
+   ret = ib_query_device(ib_dev, devattr);
+   if (ret) {
+   pr_err("ib_query_device() failed: %d\n", ret);
+   return ret;
+   }
+   pr_debug("devattr->max_mr_size: 0x%016Lx\n", devattr->max_mr_size);


running user space "ibv_devinfo -v" will give the same effect... no need 
to dump this here, maybe

except for max_sge that you need.


+   pr_debug("devattr->page_size_cap: 0x%016Lx\n", devattr->page_size_cap);
+   pr_debug("devattr->max_qp: %d\n", devattr->max_qp);
+   pr_debug("devattr->max_qp_wr: %d\n", devattr->max_qp_wr);
+   pr_debug("devattr->device_cap_flags: 0x%08x\n", 
devattr->device_cap_flags);
+   pr_debug("devattr->max_sge: %d\n", devattr->max_sge);
+   pr_debug("devattr->max_sge_rd: %d\n", devattr->max_sge_rd);
+   pr_debug("devattr->max_cq: %d\n", devattr->max_cq);
+   pr_debug("devattr->max_cqe: %d\n", devattr->max_cqe);
+   pr_debug("devattr->max_mr: %d\n", devattr->max_mr);
+   pr_debug("devattr->max_pd: %d\n", devattr->max_pd);
+   pr_debug("devattr->max_rdd: %d\n", devattr->max_rdd);
+   pr_debug("devattr->max_mw: %d\n", devattr->max_mw);
+   pr_debug("devattr->max_srq: %d\n", devattr->max_srq);
+   pr_debug("devattr->max_srq_wr: %d\n", devattr->max_srq_wr);
+   pr_debug("devattr->max_srq_sge: %d\n", devattr->max_srq_sge);
+
+   return 0;
+}

[...]

+
+
+int
+isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
+{
+   int ret = 0;
+
+   pr_debug("isert_cma_handler: event %d status %d conn %p id %p\n",
+   event->event, event->status, cma_id->context, cma_id);
+
+   switch (event->event) {
+   case RDMA_CM_EVENT_CONNECT_REQUEST:
+   pr_debug("RDMA_CM_EVENT_CONNECT_REQUEST: >>>\n");
+   ret = isert_connect_request(cma_id, event);
+   break;
+   case RDMA_CM_EVENT_ESTABLISHED:
+   pr_debug("RDMA_CM_EVENT_ESTABLISHED >>\n");
+   isert_connected_handler(cma_id);
+   break;
+   case RDMA_CM_EVENT_DISCONNECTED:
+   pr_debug("RDMA_CM_EVENT_DISCONNECTED: >>\n");
+   isert_disconnected_handler(cma_id);
+   break;
+   case RDMA_CM_EVENT_DEVICE_REMOVAL:
+   case RDMA_CM_EVENT_ADDR_CHANGE:
+   break;
+   case RDMA_CM_EVENT_ADDR_ERROR:
+   case RDMA_CM_EVENT_ROUTE_ERROR:
+   case RDMA_CM_EVENT_CONNECT_ERROR:
+   default:
+   pr_err("Unknown RDMA CMA event: %d\n", event->event);
+   break;
+   }
+


ADDR_ERROR and ROUTE_ERROR you can remove from here, since you don't 
call rdma_resolve_addr nor rdma_resolve_route, they

will not be delivered to you.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RESEND] [PATCH 05/13] pm80xx: MSI-X implementation for using 64 interrupts

2013-03-14 Thread Anand Kumar Santhanam
Hi Hannes,

I have addressed your comment and merged individual tasklet to one and have 
resubmitted the patchset.

Regards
Anand

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de] 
Sent: Monday, March 04, 2013 3:46 PM
To: Anand Kumar Santhanam
Cc: linux-scsi@vger.kernel.org; Harry Yang; jack_w...@usish.com; Vishwanath 
Maram; Sangeetha Gnanasekaran
Subject: Re: [RESEND] [PATCH 05/13] pm80xx: MSI-X implementation for using 64 
interrupts

On 03/02/2013 05:48 PM, Anand wrote:
>  From c5db2e0b6cf65fbef66fb2f4e345bf6856e242a4 Mon Sep 17 00:00:00 
> 2001
> From: Sakthivel K 
> Date: Wed, 27 Feb 2013 20:32:56 +0530
> Subject: [PATCH 05/13] pm80xx: MSI-X implementation for using 64 
> interrupts
>
> Implementation of 64 interrupt handlers and tasklets to support upto 
> 64 interrupt for the device.
>
> Signed-off-by: Sakthivel K 
> Signed-off-by: Anand Kumar S 
> Ack-by: Jack Wang 
> ---
>   drivers/scsi/pm8001/pm8001_init.c | 1233 
> -
>   drivers/scsi/pm8001/pm8001_sas.h  |3 +-
>   2 files changed, 1205 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_init.c 
> b/drivers/scsi/pm8001/pm8001_init.c
> index e8a983f..f0c5075 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -163,7 +163,13 @@ static void pm8001_free(struct pm8001_hba_info 
> *pm8001_ha)
>   }
>
>   #ifdef PM8001_USE_TASKLET
> -static void pm8001_tasklet(unsigned long opaque)
> +
> +/**
> + * tasklets for 64 msi-x interrupt handlers
> + * @opaque: the passed general host adapter struct
> + * Note: pm8001_tasklet0 is common for pm8001 & pm80xx  */ static 
> +void pm8001_tasklet0(unsigned long opaque)
>   {
>   struct pm8001_hba_info *pm8001_ha;
>   pm8001_ha = (struct pm8001_hba_info *)opaque; @@ -171,16 +177,521 
> @@ static void pm8001_tasklet(unsigned long opaque)
>   BUG_ON(1);
>   PM8001_CHIP_DISP->isr(pm8001_ha, 0);
>   }
> +static void pm8001_tasklet1(unsigned long opaque) {
> + struct pm8001_hba_info *pm8001_ha;
> + pm8001_ha = (struct pm8001_hba_info *)opaque;
> + if (unlikely(!pm8001_ha))
> + BUG_ON(1);
> + PM8001_CHIP_DISP->isr(pm8001_ha, 1); } static void 
> +pm8001_tasklet2(unsigned long opaque) {
> + struct pm8001_hba_info *pm8001_ha;
> + pm8001_ha = (struct pm8001_hba_info *)opaque;
> + if (unlikely(!pm8001_ha))
> + BUG_ON(1);
> + PM8001_CHIP_DISP->isr(pm8001_ha, 2); }
[ ... ]

This is stupid.
Please merge all the individual tasklets etc.

Having 64 identical functions makes the code unreadable and unmaintainable.

Cheers,
Hannes
-- 
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 10/11] iser-target: Add logic for core

2013-03-14 Thread Or Gerlitz

On 08/03/2013 03:45, Nicholas A. Bellinger wrote:

+void
+isert_dump_ib_wc(struct ib_wc *wc)
+{
+   pr_debug("wc->wr_id: %llu\n", wc->wr_id);
+   pr_debug("wc->status: 0x%08x\n", wc->status);


This helper is called for a CQ completion with error, but when this 
happens all the WC fields except for the wr_id and the status aren't 
defined, so there's no point in dumping them (can be terribly misleading)



+   pr_debug("wc->opcode: 0x%08x\n", wc->opcode);
+   pr_debug("wc->vendor_err: 0x%08x\n", wc->vendor_err);
+   pr_debug("wc->byte_len: %u\n", wc->byte_len);
+   pr_debug("wc->qp: %p\n", wc->qp);
+   pr_debug("wc->src_qp: %u\n", wc->src_qp);
+   pr_debug("wc->wc_flags: 0x%08x\n", wc->wc_flags);
+   pr_debug("wc->pkey_index: %hu\n", wc->pkey_index);
+   pr_debug("wc->slid: %hu\n", wc->slid);
+   pr_debug("wc->sl: 0x%02x\n", wc->sl);
+   pr_debug("wc->dlid_path_bits: 0x%02x\n", wc->dlid_path_bits);
+   pr_debug("wc->port_num: 0x%02x\n", wc->port_num);
+}
+
+void
+iser_cq_tx_tasklet(unsigned long data)
+{
+   struct isert_conn *isert_conn = (struct isert_conn *)data;
+   struct ib_cq *tx_cq = isert_conn->conn_tx_cq;
+   struct iser_tx_desc *tx_desc;
+   struct ib_wc wc;
+
+   while (ib_poll_cq(tx_cq, 1, &wc) == 1) {
+   tx_desc = (struct iser_tx_desc *)(unsigned long)wc.wr_id;
+
+   if (wc.status == IB_WC_SUCCESS) {
+   isert_send_completion(tx_desc, isert_conn);
+   } else {
+   pr_debug("TX wc.status != IB_WC_SUCCESS 
>>\n");
+   isert_dump_ib_wc(&wc);
+   atomic_dec(&isert_conn->post_send_buf_count);
+   isert_cq_comp_err(tx_desc, isert_conn);
+   }
+   }
+
+   ib_req_notify_cq(tx_cq, IB_CQ_NEXT_COMP);
+}
+
+void
+isert_cq_tx_callback(struct ib_cq *cq, void *context)
+{
+   struct isert_conn *isert_conn = context;
+
+   tasklet_schedule(&isert_conn->conn_tx_tasklet);
+}
+
+void
+iser_cq_rx_tasklet(unsigned long data)
+{
+   struct isert_conn *isert_conn = (struct isert_conn *)data;
+   struct ib_cq *rx_cq = isert_conn->conn_rx_cq;
+   struct iser_rx_desc *rx_desc;
+   struct ib_wc wc;
+   unsigned long xfer_len;
+
+   while (ib_poll_cq(rx_cq, 1, &wc) == 1) {
+   rx_desc = (struct iser_rx_desc *)(unsigned long)wc.wr_id;
+
+   if (wc.status == IB_WC_SUCCESS) {
+   xfer_len = (unsigned long)wc.byte_len;
+   isert_rx_completion(rx_desc, isert_conn, xfer_len);
+   } else {
+   pr_debug("RX wc.status != IB_WC_SUCCESS 
>>\n");
+   if (wc.status != IB_WC_WR_FLUSH_ERR)
+   isert_dump_ib_wc(&wc);
+
+   isert_conn->post_recv_buf_count--;
+   isert_cq_comp_err(NULL, isert_conn);
+   }
+   }
+
+   ib_req_notify_cq(rx_cq, IB_CQ_NEXT_COMP);
+}


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 12/12] pm80xx: thermal, sas controller config and error handling update

2013-03-14 Thread Anand
>From 375653061c0db3189e9e5678b11291b7b0195ac3 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:44:36 +0530
Subject: [PATCH V2 12/12] pm80xx: thermal, sas controller config and error 
handling update

Modified thermal configuration to happen after interrupt registration
Added SAS controller configuration during initialization
Added error handling logic to handle I_T_Nexus errors and variants

Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_hwi.c  |2 +-
 drivers/scsi/pm8001/pm8001_init.c |2 +
 drivers/scsi/pm8001/pm8001_sas.c  |   66 
 drivers/scsi/pm8001/pm8001_sas.h  |2 +
 drivers/scsi/pm8001/pm80xx_hwi.c  |  150 +
 drivers/scsi/pm8001/pm80xx_hwi.h  |   44 +++-
 6 files changed, 249 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index a90c002..d18f421 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1670,7 +1670,7 @@ void pm8001_work_fn(struct work_struct *work)
}   break;
case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
dev = pm8001_dev->sas_device;
-   pm8001_I_T_nexus_reset(dev);
+   pm8001_I_T_nexus_event_handler(dev);
break;
case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
dev = pm8001_dev->sas_device;
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index adda111..27d519d 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1165,6 +1165,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
if (pm8001_ha->chip_id != chip_8001) {
for (i = 1; i < pm8001_ha->number_of_intr; i++)
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
+   /* setup thermal configuration. */
+   pm80xx_set_thermal_config(pm8001_ha);
}
 
pm8001_init_sas_add(pm8001_ha);
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index c720917..9af9585 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1018,6 +1018,72 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
return rc;
 }
 
+/*
+* This function handle the IT_NEXUS_XXX event or completion
+* status code for SSP/SATA/SMP I/O request.
+*/
+int pm8001_I_T_nexus_event_handler(struct domain_device *dev)
+{
+   int rc = TMF_RESP_FUNC_FAILED;
+   struct pm8001_device *pm8001_dev;
+   struct pm8001_hba_info *pm8001_ha;
+   struct sas_phy *phy;
+   u32 device_id = 0;
+
+   if (!dev || !dev->lldd_dev)
+   return -1;
+
+   pm8001_dev = dev->lldd_dev;
+   device_id = pm8001_dev->device_id;
+   pm8001_ha = pm8001_find_ha_by_dev(dev);
+
+   PM8001_EH_DBG(pm8001_ha,
+   pm8001_printk("I_T_Nexus handler invoked !!"));
+
+   phy = sas_get_local_phy(dev);
+
+   if (dev_is_sata(dev)) {
+   DECLARE_COMPLETION_ONSTACK(completion_setstate);
+   if (scsi_is_sas_phy_local(phy)) {
+   rc = 0;
+   goto out;
+   }
+   /* send internal ssp/sata/smp abort command to FW */
+   rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+   dev, 1, 0);
+   msleep(100);
+
+   /* deregister the target device */
+   pm8001_dev_gone_notify(dev);
+   msleep(200);
+
+   /*send phy reset to hard reset target */
+   rc = sas_phy_reset(phy, 1);
+   msleep(2000);
+   pm8001_dev->setds_completion = &completion_setstate;
+
+   wait_for_completion(&completion_setstate);
+   } else {
+   /* send internal ssp/sata/smp abort command to FW */
+   rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+   dev, 1, 0);
+   msleep(100);
+
+   /* deregister the target device */
+   pm8001_dev_gone_notify(dev);
+   msleep(200);
+
+   /*send phy reset to hard reset target */
+   rc = sas_phy_reset(phy, 1);
+   msleep(2000);
+   }
+   PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n",
+   pm8001_dev->device_id, rc));
+out:
+   sas_put_local_phy(phy);
+
+   return rc;
+}
 /* mandatory SAM-3, the task reset the specified LUN*/
 int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
 {
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 2fa73fc..29a6a7b 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -562,6 +562,7 @@ int pm8001_dev_found(struct domain_device *dev);
 void pm

[PATCH V2 11/12] pm80xx: NCQ error handling changes

2013-03-14 Thread Anand
>From 6c5a97ffa25ca47e2403b11e8325c51ac044e501 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:43:20 +0530
Subject: [PATCH V2 11/12] pm80xx: NCQ error handling changes

Handled NCQ errors in the low level driver as the FW
is not providing the faulty tag for NCQ errors for libsas
to recover.

Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_hwi.c |  270 --
 drivers/scsi/pm8001/pm8001_sas.c |   22 +++-
 drivers/scsi/pm8001/pm8001_sas.h |   15 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c |  262 +++--
 drivers/scsi/pm8001/pm80xx_hwi.h |1 +
 5 files changed, 543 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 265dbf4..a90c002 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1707,6 +1707,123 @@ int pm8001_handle_event(struct pm8001_hba_info 
*pm8001_ha, void *data,
return ret;
 }
 
+static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
+   struct pm8001_device *pm8001_ha_dev)
+{
+   int res;
+   u32 ccb_tag;
+   struct pm8001_ccb_info *ccb;
+   struct sas_task *task = NULL;
+   struct task_abort_req task_abort;
+   struct inbound_queue_table *circularQ;
+   u32 opc = OPC_INB_SATA_ABORT;
+   int ret;
+
+   if (!pm8001_ha_dev) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null \n"));
+   return;
+   }
+
+   task = sas_alloc_slow_task(GFP_ATOMIC);
+
+   if (!task) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot "
+   "allocate task \n"));
+   return;
+   }
+
+   task->task_done = pm8001_task_done;
+
+   res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+   if (res)
+   return;
+
+   ccb = &pm8001_ha->ccb_info[ccb_tag];
+   ccb->device = pm8001_ha_dev;
+   ccb->ccb_tag = ccb_tag;
+   ccb->task = task;
+
+   circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+   memset(&task_abort, 0, sizeof(task_abort));
+   task_abort.abort_all = cpu_to_le32(1);
+   task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
+   task_abort.tag = cpu_to_le32(ccb_tag);
+
+   ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0);
+
+}
+
+static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
+   struct pm8001_device *pm8001_ha_dev)
+{
+   struct sata_start_req sata_cmd;
+   int res;
+   u32 ccb_tag;
+   struct pm8001_ccb_info *ccb;
+   struct sas_task *task = NULL;
+   struct host_to_dev_fis fis;
+   struct domain_device *dev;
+   struct inbound_queue_table *circularQ;
+   u32 opc = OPC_INB_SATA_HOST_OPSTART;
+
+   task = sas_alloc_slow_task(GFP_ATOMIC);
+
+   if (!task) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("cannot allocate task !!!\n"));
+   return;
+   }
+   task->task_done = pm8001_task_done;
+
+   res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+   if (res) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("cannot allocate tag !!!\n"));
+   return;
+   }
+
+   /* allocate domain device by ourselves as libsas
+* is not going to provide any
+   */
+   dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
+   if (!dev) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Domain device cannot be allocated \n"));
+   sas_free_task(task);
+   return;
+   } else {
+   task->dev = dev;
+   task->dev->lldd_dev = pm8001_ha_dev;
+   }
+
+   ccb = &pm8001_ha->ccb_info[ccb_tag];
+   ccb->device = pm8001_ha_dev;
+   ccb->ccb_tag = ccb_tag;
+   ccb->task = task;
+   pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
+   pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
+
+   memset(&sata_cmd, 0, sizeof(sata_cmd));
+   circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+   /* construct read log FIS */
+   memset(&fis, 0, sizeof(struct host_to_dev_fis));
+   fis.fis_type = 0x27;
+   fis.flags = 0x80;
+   fis.command = ATA_CMD_READ_LOG_EXT;
+   fis.lbal = 0x10;
+   fis.sector_count = 0x1;
+
+   sata_cmd.tag = cpu_to_le32(ccb_tag);
+   sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
+   sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9));
+   memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
+
+   res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0);
+
+}
+
 /**
  * mpi_ssp_completion- process the event that FW response to the SSP request.
  * @pm8001_ha: our hba card information
@@ -2170,16 +2287,44 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, 
void *piomb)
   

[PATCH V2 09/12] pm80xx: Changed module name and debug messages update

2013-03-14 Thread Anand
>From 763c1337ae0ec3acea557fa9a4117dd9e2f2ef32 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:41:38 +0530
Subject: [PATCH V2 09/12] pm80xx: Changed module name and debug messages update

Changed name in driver to pm80xx. Updated debug messages.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_hwi.c  |   11 ++-
 drivers/scsi/pm8001/pm8001_init.c |   14 ++
 drivers/scsi/pm8001/pm8001_sas.h  |6 +++---
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c124fc6..265dbf4 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -2506,9 +2506,9 @@ static void mpi_sata_event(struct pm8001_hba_info 
*pm8001_ha , void *piomb)
if (unlikely(!t || !t->lldd_task || !t->dev))
return;
ts = &t->task_status;
-   PM8001_IO_DBG(pm8001_ha,
-   pm8001_printk("port_id = %x,device_id = %x\n",
-   port_id, dev_id));
+   PM8001_IO_DBG(pm8001_ha, pm8001_printk(
+   "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n",
+   port_id, dev_id, tag, event));
switch (event) {
case IO_OVERFLOW:
PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
@@ -4409,8 +4409,9 @@ int pm8001_chip_abort_task(struct pm8001_hba_info 
*pm8001_ha,
 {
u32 opc, device_id;
int rc = TMF_RESP_FUNC_FAILED;
-   PM8001_EH_DBG(pm8001_ha, pm8001_printk("cmd_tag = %x, abort task tag"
-   " = %x", cmd_tag, task_tag));
+   PM8001_EH_DBG(pm8001_ha,
+   pm8001_printk("cmd_tag = %x, abort task tag = 0x%x",
+   cmd_tag, task_tag));
if (pm8001_dev->dev_type == SAS_END_DEV)
opc = OPC_INB_SSP_ABORT;
else if (pm8001_dev->dev_type == SATA_DEV)
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 46df0d2..9480a12 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1068,7 +1068,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
const struct pm8001_chip_info *chip;
 
dev_printk(KERN_INFO, &pdev->dev,
-   "pm8001: driver version %s\n", DRV_VERSION);
+   "pm80xx: driver version %s\n", DRV_VERSION);
rc = pci_enable_device(pdev);
if (rc)
goto err_out_enable;
@@ -1116,15 +1116,21 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
list_add_tail(&pm8001_ha->list, &hba_list);
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
-   if (rc)
+   if (rc) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+   "chip_init failed [ret: %d]\n", rc));
goto err_out_ha_free;
+   }
 
rc = scsi_add_host(shost, &pdev->dev);
if (rc)
goto err_out_ha_free;
rc = pm8001_request_irq(pm8001_ha);
-   if (rc)
+   if (rc) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+   "pm8001_request_irq failed [ret: %d]\n", rc));
goto err_out_shost;
+   }
 
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
if (pm8001_ha->chip_id != chip_8001) {
@@ -1364,7 +1370,7 @@ static int __init pm8001_init(void)
 {
int rc = -ENOMEM;
 
-   pm8001_wq = alloc_workqueue("pm8001", 0, 0);
+   pm8001_wq = alloc_workqueue("pm80xx", 0, 0);
if (!pm8001_wq)
goto err;
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 833fab3..008c2ea 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -57,7 +57,7 @@
 #include 
 #include "pm8001_defs.h"
 
-#define DRV_NAME   "pm8001"
+#define DRV_NAME   "pm80xx"
 #define DRV_VERSION"0.1.36"
 #define PM8001_FAIL_LOGGING0x01 /* Error message logging */
 #define PM8001_INIT_LOGGING0x02 /* driver init logging */
@@ -66,8 +66,8 @@
 #define PM8001_EH_LOGGING  0x10 /* libsas EH function logging*/
 #define PM8001_IOCTL_LOGGING   0x20 /* IOCTL message logging */
 #define PM8001_MSG_LOGGING 0x40 /* misc message logging */
-#define pm8001_printk(format, arg...)  printk(KERN_INFO "%s %d:" format,\
-   __func__, __LINE__, ## arg)
+#define pm8001_printk(format, arg...)  printk(KERN_INFO "pm80xx %s %d:" \
+   format, __func__, __LINE__, ## arg)
 #define PM8001_CHECK_LOGGING(HBA, LEVEL, CMD)  \
 do {   \
if (unlikely(HBA->logging_level & LEVEL))   \
-- 
1.7.1

>From 763c1337ae0ec3acea557fa9a4117dd9e2f2ef32 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:41:38 +0530
Subject: [PATCH V2 09/12] pm80xx: Changed module name and

[PATCH V2 10/12] pm80xx: WWN Modification for PM8081/88/89 controllers

2013-03-14 Thread Anand
>From 39041621d54839dcd6878005a48f5ee3e1ec90b9 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:42:13 +0530
Subject: [PATCH V2 10/12] pm80xx: WWN Modification for PM8081/88/89 controllers

Individual WWN read operations based on controller.
PM8081 - Read WWN from Flash VPD.
PM8088/89 - Read WWN from EEPROM.
PM8001 - Read WWN from NVM.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_init.c |   43 +++--
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 9480a12..adda111 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -936,21 +936,50 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host 
*shost,
  */
 static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
 {
-   u8 i;
+   u8 i, j;
 #ifdef PM8001_READ_VPD
+   /* For new SPC controllers WWN is stored in flash vpd
+   *  For SPC/SPCve controllers WWN is stored in EEPROM
+   *  For Older SPC WWN is stored in NVMD
+   */
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
pm8001_ha->nvmd_completion = &completion;
-   payload.minor_function = 0;
-   payload.length = 128;
-   payload.func_specific = kzalloc(128, GFP_KERNEL);
+
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (deviceid == 0x8081) {
+   payload.minor_function = 4;
+   payload.length = 4096;
+   } else {
+   payload.minor_function = 0;
+   payload.length = 128;
+   }
+   } else {
+   payload.minor_function = 1;
+   payload.length = 4096;
+   }
+   payload.offset = 0;
+   payload.func_specific = kzalloc(payload.length, GFP_KERNEL);
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
wait_for_completion(&completion);
+
+   for (i = 0, j = 0; i <= 7; i++, j++) {
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (deviceid == 0x8081)
+   pm8001_ha->sas_addr[j] =
+   payload.func_specific[0x704 + i];
+   } else
+   pm8001_ha->sas_addr[j] =
+   payload.func_specific[0x804 + i];
+   }
+
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
-   memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr,
-   SAS_ADDR_SIZE);
+   memcpy(&pm8001_ha->phy[i].dev_sas_addr,
+   pm8001_ha->sas_addr, SAS_ADDR_SIZE);
PM8001_INIT_DBG(pm8001_ha,
-   pm8001_printk("phy %d sas_addr = %016llx \n", i,
+   pm8001_printk("phy %d sas_addr = %016llx\n", i,
pm8001_ha->phy[i].dev_sas_addr));
}
 #else
-- 
1.7.1

>From 39041621d54839dcd6878005a48f5ee3e1ec90b9 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:42:13 +0530
Subject: [PATCH V2 10/12] pm80xx: WWN Modification for PM8081/88/89 controllers

Individual WWN read operations based on controller.
PM8081 - Read WWN from Flash VPD.
PM8088/89 - Read WWN from EEPROM.
PM8001 - Read WWN from NVM.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_init.c |   43 +++--
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 9480a12..adda111 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -936,21 +936,50 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host 
*shost,
  */
 static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
 {
-   u8 i;
+   u8 i, j;
 #ifdef PM8001_READ_VPD
+   /* For new SPC controllers WWN is stored in flash vpd
+   *  For SPC/SPCve controllers WWN is stored in EEPROM
+   *  For Older SPC WWN is stored in NVMD
+   */
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
pm8001_ha->nvmd_completion = &completion;
-   payload.minor_function = 0;
-   payload.length = 128;
-   payload.func_specific = kzalloc(128, GFP_KERNEL);
+
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (deviceid == 0x8081) {
+   payload.minor_function = 4;
+   payload.length = 4096;
+   } else {
+   payload.minor_function = 0;
+   payload.lengt

[PATCH V2 08/12] pm80xx: Firmware flash memory free fix, with addition of new memory region for it

2013-03-14 Thread Anand
>From 5bb77b58d81591963c8bd6754276c1a78d80c4a4 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:38:50 +0530
Subject: [PATCH V2 08/12] pm80xx: Firmware flash memory free fix, with addition 
of new memory region for it

Performing pci_free_consistent in tasklet had result in a core dump. So
allocated a new memory region for it. Fix for passing proper address
and operation in firmware flash update.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_ctl.c  |5 +++--
 drivers/scsi/pm8001/pm8001_defs.h |3 ++-
 drivers/scsi/pm8001/pm8001_hwi.c  |   30 ++
 drivers/scsi/pm8001/pm8001_init.c |3 +++
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index ae2b124..d99f41c 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -400,10 +400,11 @@ static int pm8001_set_nvmd(struct pm8001_hba_info 
*pm8001_ha)
goto out;
}
payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
-   memcpy((u8 *)payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
+   memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
pm8001_ha->fw_image->size);
payload->length = pm8001_ha->fw_image->size;
payload->id = 0;
+   payload->minor_function = 0x1;
pm8001_ha->nvmd_completion = &completion;
ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
wait_for_completion(&completion);
@@ -450,7 +451,7 @@ static int pm8001_update_flash(struct pm8001_hba_info 
*pm8001_ha)
payload->length = 1024*16;
payload->id = 0;
fwControl =
- (struct fw_control_info *)payload->func_specific;
+ (struct fw_control_info *)&payload->func_specific;
fwControl->len = IOCTL_BUF_SIZE;   /* IN */
fwControl->size = partitionSize + HEADER_LEN;/* IN */
fwControl->retcode = 0;/* OUT */
diff --git a/drivers/scsi/pm8001/pm8001_defs.h 
b/drivers/scsi/pm8001/pm8001_defs.h
index 26a2ee6..479c5a7 100644
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -86,7 +86,7 @@ enum port_type {
 #definePM8001_MAX_DEVICES   2048   /* max supported device */
 #definePM8001_MAX_MSIX_VEC  64 /* max msi-x int for spcv/ve */
 
-#define USI_MAX_MEMCNT_BASE4
+#define USI_MAX_MEMCNT_BASE5
 #define IB (USI_MAX_MEMCNT_BASE + 1)
 #define CI (IB + PM8001_MAX_SPCV_INB_NUM)
 #define OB (CI + PM8001_MAX_SPCV_INB_NUM)
@@ -99,6 +99,7 @@ enum memory_region_num {
NVMD,   /* NVM device */
DEV_MEM,/* memory for devices */
CCB_MEM,/* memory for command control block */
+   FW_FLASH/* memory for fw flash update */
 };
 #definePM8001_EVENT_LOG_SIZE(128 * 1024)
 
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 3adf499..c124fc6 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3481,10 +3481,6 @@ int pm8001_mpi_fw_flash_update_resp(struct 
pm8001_hba_info *pm8001_ha,
break;
}
ccb->fw_control_context->fw_control->retcode = status;
-   pci_free_consistent(pm8001_ha->pdev,
-   fw_control_context.len,
-   fw_control_context.virtAddr,
-   fw_control_context.phys_addr);
complete(pm8001_ha->nvmd_completion);
ccb->task = NULL;
ccb->ccb_tag = 0x;
@@ -4474,7 +4470,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info 
*pm8001_ha,
fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
if (!fw_control_context)
return -ENOMEM;
-   fw_control_context->usrAddr = (u8 *)&ioctl_payload->func_specific[0];
+   fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;
fw_control_context->len = ioctl_payload->length;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memset(&nvmd_req, 0, sizeof(nvmd_req));
@@ -4556,7 +4552,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info 
*pm8001_ha,
return -ENOMEM;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
-   ioctl_payload->func_specific,
+   &ioctl_payload->func_specific,
ioctl_payload->length);
memset(&nvmd_req, 0, sizeof(nvmd_req));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
@@ -4658,29 +4654,14 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info 
*pm8001_ha,
int rc;
u32 tag;
struct pm8001_ccb_info *ccb;
-   voi

[PATCH V2 07/12] pm80xx: SPC new firmware changes for device id 0x8081 alone

2013-03-14 Thread Anand
>From 2083ae66cd04ca9d1ace29bc8f6a159215ece5b6 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:37:51 +0530
Subject: [PATCH V2 07/12] pm80xx: SPC new firmware changes for device id 0x8081 
alone

Additional bar shift for new SPC firmware, applicable to device
id 0x8081 only.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_hwi.c |   31 ---
 drivers/scsi/pm8001/pm8001_hwi.h |2 ++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c335ae8..3adf499 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -640,6 +640,18 @@ static void init_pci_device_addresses(struct 
pm8001_hba_info *pm8001_ha)
 static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
 {
u8 i = 0;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
+   /* 8081 controllers need BAR shift to access MPI space
+   * as this is shared with BIOS data */
+   if (deviceid == 0x8081) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Shift Bar4 to 0x%x failed\n",
+   GSM_SM_BASE));
+   return -1;
+   }
+   }
/* check the firmware status */
if (-1 == check_fw_ready(pm8001_ha)) {
PM8001_FAIL_DBG(pm8001_ha,
@@ -660,9 +672,12 @@ static int pm8001_chip_init(struct pm8001_hba_info 
*pm8001_ha)
update_inbnd_queue_table(pm8001_ha, i);
for (i = 0; i < PM8001_MAX_OUTB_NUM; i++)
update_outbnd_queue_table(pm8001_ha, i);
-   mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
-   /* 7->130ms, 34->500ms, 119->1.5s */
-   mpi_set_open_retry_interval_reg(pm8001_ha, 119);
+   /* 8081 controller donot require these operations */
+   if (deviceid != 0x8081) {
+   mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
+   /* 7->130ms, 34->500ms, 119->1.5s */
+   mpi_set_open_retry_interval_reg(pm8001_ha, 119);
+   }
/* notify firmware update finished and check initialization status */
if (0 == mpi_init_check(pm8001_ha)) {
PM8001_INIT_DBG(pm8001_ha,
@@ -684,6 +699,16 @@ static int mpi_uninit_check(struct pm8001_hba_info 
*pm8001_ha)
u32 max_wait_count;
u32 value;
u32 gst_len_mpistate;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
+   if (deviceid == 0x8081) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Shift Bar4 to 0x%x failed\n",
+   GSM_SM_BASE));
+   return -1;
+   }
+   }
init_pci_device_addresses(pm8001_ha);
/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
table is stop */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index 2399aab..d7c1e20 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -131,6 +131,8 @@
 #define LINKRATE_30(0x02 << 8)
 #define LINKRATE_60(0x04 << 8)
 
+/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
+#define GSM_SM_BASE0x4F
 struct mpi_msg_hdr{
__le32  header; /* Bits [11:0]  - Message operation code */
/* Bits [15:12] - Message Category */
-- 
1.7.1

>From 2083ae66cd04ca9d1ace29bc8f6a159215ece5b6 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:37:51 +0530
Subject: [PATCH V2 07/12] pm80xx: SPC new firmware changes for device id 0x8081 
alone

Additional bar shift for new SPC firmware, applicable to device
id 0x8081 only.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_hwi.c |   31 ---
 drivers/scsi/pm8001/pm8001_hwi.h |2 ++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c335ae8..3adf499 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -640,6 +640,18 @@ static void init_pci_device_addresses(struct 
pm8001_hba_info *pm8001_ha)
 static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
 {
u8 i = 0;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
+   /* 8081 controllers need BAR shift to access MPI space
+   * as this is shared with BIOS data */
+   if (deviceid == 0x8081) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha, GSM

[PATCH V2 05/12] pm80xx: MSI-X implementation for using 64 interrupts

2013-03-14 Thread Anand
>From 62b6f575d1978a965339c69158bd10d0529815fb Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 11 Mar 2013 20:20:19 +0530
Subject: [PATCH V2 05/12] pm80xx: MSI-X implementation for using 64 interrupts

Implementation of interrupt handlers and tasklets to support
upto 64 interrupt for the device.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_init.c |  456 +++--
 drivers/scsi/pm8001/pm8001_sas.h  |1 +
 2 files changed, 432 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index e8a983f..95b6966 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -163,24 +163,33 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
 }
 
 #ifdef PM8001_USE_TASKLET
+
+/**
+ * tasklet for 64 msi-x interrupt handler
+ * @opaque: the passed general host adapter struct
+ * Note: pm8001_tasklet is common for pm8001 & pm80xx
+ */
 static void pm8001_tasklet(unsigned long opaque)
 {
struct pm8001_hba_info *pm8001_ha;
+   u32 vec;
pm8001_ha = (struct pm8001_hba_info *)opaque;
if (unlikely(!pm8001_ha))
BUG_ON(1);
-   PM8001_CHIP_DISP->isr(pm8001_ha, 0);
+   vec = pm8001_ha->int_vector;
+   PM8001_CHIP_DISP->isr(pm8001_ha, vec);
 }
 #endif
 
+/**
+ * pm8001_interrupt_handler_x -main interrupt handler invokde for all 
interrupt.
+ * It obtains the vector number and calls the equivalent bottom half or 
services
+ * directly.
+ * @vec: vector number; will be 0 for none msi-x operation
+ * @opaque: the passed general host adapter struct
+ */
 
- /**
-  * pm8001_interrupt - when HBA originate a interrupt,we should invoke this
-  * dispatcher to handle each case.
-  * @irq: irq number.
-  * @opaque: the passed general host adapter struct
-  */
-static irqreturn_t pm8001_interrupt(int irq, void *opaque)
+static inline irqreturn_t pm8001_interrupt_handler_x(int vec, void *opaque)
 {
struct pm8001_hba_info *pm8001_ha;
irqreturn_t ret = IRQ_HANDLED;
@@ -190,6 +199,7 @@ static irqreturn_t pm8001_interrupt(int irq, void *opaque)
return IRQ_NONE;
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
return IRQ_NONE;
+   pm8001_ha->int_vector = vec;
 #ifdef PM8001_USE_TASKLET
tasklet_schedule(&pm8001_ha->tasklet);
 #else
@@ -198,6 +208,365 @@ static irqreturn_t pm8001_interrupt(int irq, void *opaque)
return ret;
 }
 
+/* 64 interrupt handlers for 64 msi-x vectors */
+static irqreturn_t pm8001_interrupt_handler0(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(0, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler1(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(1, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler2(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(2, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler3(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(3, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler4(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(4, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler5(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(5, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler6(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(6, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler7(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(7, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler8(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(8, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler9(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(9, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler10(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(10, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler11(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(11, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler12(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(12, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler13(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(13, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler14(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(14, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler15(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(15, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler16(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(16, dev_id);
+}
+
+static irqreturn_t pm8001_interrupt_handler17(int irq, void *dev_id)
+{
+   return pm8001_interrupt_handler_x(17, dev_id);
+}
+
+static irqretur

[PATCH V2 03/12] pm80xx: Multiple inbound/outbound queue configuration

2013-03-14 Thread Anand
>From f0b469f372f1c1faa393123f4a3a5e93e05b8387 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Wed, 27 Feb 2013 20:25:25 +0530
Subject: [PATCH V2 03/12] pm80xx: Multiple inbound/outbound queue configuration

Memory allocation and configuration of multiple inbound and
outbound queues.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_defs.h |   14 +++--
 drivers/scsi/pm8001/pm8001_hwi.c  |   43 
 drivers/scsi/pm8001/pm8001_init.c |  101 +
 3 files changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_defs.h 
b/drivers/scsi/pm8001/pm8001_defs.h
index b25f87c..26a2ee6 100644
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -48,8 +48,7 @@ enum chip_flavors {
chip_8018,
chip_8019
 };
-#define USI_MAX_MEMCNT 9
-#define PM8001_MAX_DMA_SG  SG_ALL
+
 enum phy_speed {
PHY_SPEED_15 = 0x01,
PHY_SPEED_30 = 0x02,
@@ -87,13 +86,16 @@ enum port_type {
 #definePM8001_MAX_DEVICES   2048   /* max supported device */
 #definePM8001_MAX_MSIX_VEC  64 /* max msi-x int for spcv/ve */
 
+#define USI_MAX_MEMCNT_BASE4
+#define IB (USI_MAX_MEMCNT_BASE + 1)
+#define CI (IB + PM8001_MAX_SPCV_INB_NUM)
+#define OB (CI + PM8001_MAX_SPCV_INB_NUM)
+#define PI (OB + PM8001_MAX_SPCV_OUTB_NUM)
+#define USI_MAX_MEMCNT (PI + PM8001_MAX_SPCV_OUTB_NUM)
+#define PM8001_MAX_DMA_SG  SG_ALL
 enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
IOP,/* IO processor */
-   CI, /* consumer index */
-   PI, /* producer index */
-   IB, /* inbound queue */
-   OB, /* outbound queue */
NVMD,   /* NVM device */
DEV_MEM,/* memory for devices */
CCB_MEM,/* memory for command control block */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index d04a613..651834c 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -151,10 +151,9 @@ static void read_general_status_table(struct 
pm8001_hba_info *pm8001_ha)
  */
 static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
 {
-   int inbQ_num = 1;
int i;
void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
-   for (i = 0; i < inbQ_num; i++) {
+   for (i = 0; i < PM8001_MAX_INB_NUM; i++) {
u32 offset = i * 0x20;
pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
  get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
@@ -169,10 +168,9 @@ static void read_inbnd_queue_table(struct pm8001_hba_info 
*pm8001_ha)
  */
 static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
 {
-   int outbQ_num = 1;
int i;
void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
-   for (i = 0; i < outbQ_num; i++) {
+   for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) {
u32 offset = i * 0x24;
pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
  get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
@@ -225,19 +223,19 @@ static void init_default_table_values(struct 
pm8001_hba_info *pm8001_ha)
pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt  =
PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30);
pm8001_ha->inbnd_q_tbl[i].upper_base_addr   =
-   pm8001_ha->memoryMap.region[IB].phys_addr_hi;
+   pm8001_ha->memoryMap.region[IB + i].phys_addr_hi;
pm8001_ha->inbnd_q_tbl[i].lower_base_addr   =
-   pm8001_ha->memoryMap.region[IB].phys_addr_lo;
+   pm8001_ha->memoryMap.region[IB + i].phys_addr_lo;
pm8001_ha->inbnd_q_tbl[i].base_virt =
-   (u8 *)pm8001_ha->memoryMap.region[IB].virt_ptr;
+   (u8 *)pm8001_ha->memoryMap.region[IB + i].virt_ptr;
pm8001_ha->inbnd_q_tbl[i].total_length  =
-   pm8001_ha->memoryMap.region[IB].total_len;
+   pm8001_ha->memoryMap.region[IB + i].total_len;
pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr=
-   pm8001_ha->memoryMap.region[CI].phys_addr_hi;
+   pm8001_ha->memoryMap.region[CI + i].phys_addr_hi;
pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr=
-   pm8001_ha->memoryMap.region[CI].phys_addr_lo;
+   pm8001_ha->memoryMap.region[CI + i].phys_addr_lo;
pm8001_ha->inbnd_q_tbl[i].ci_virt   =
-   pm8001_ha->memoryMap.region[CI].virt_ptr;
+   pm8001_ha->memoryMap.region[CI + i].v

[PATCH V2 02/12] pm80xx: Added SPCv/ve specific ids, variables and modify for SPC

2013-03-14 Thread Anand
>From ef678e2188866af926f2a089719c24ec99e4e88c Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Wed, 27 Feb 2013 20:22:50 +0530
Subject: [PATCH V2 02/12] pm80xx: Added SPCv/ve specific ids, variables and 
modify for SPC

Updated pci id table with device, vendor, subdevice and subvendor ids
for 8081, 8088, 8089 SAS/SATA controllers. Added SPCv/ve related macros.
Updated macros, hba info structure and other structures for SPCv/ve.
Update of structure and variable names for SPC hardware functionalities.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_ctl.c  |   69 ++---
 drivers/scsi/pm8001/pm8001_defs.h |   19 +++-
 drivers/scsi/pm8001/pm8001_hwi.c  |  210 ++---
 drivers/scsi/pm8001/pm8001_init.c |   52 -
 drivers/scsi/pm8001/pm8001_sas.h  |   93 ++--
 5 files changed, 324 insertions(+), 119 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 45bc197..ae2b124 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1,5 +1,5 @@
 /*
- * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ * PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver
  *
  * Copyright (c) 2008-2009 USI Co., Ltd.
  * All rights reserved.
@@ -58,8 +58,13 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct 
device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-   pm8001_ha->main_cfg_tbl.interface_rev);
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev);
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev);
+   }
 }
 static
 DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
@@ -78,11 +83,19 @@ static ssize_t pm8001_ctl_fw_version_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev));
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 24),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 16),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 8),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev));
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 24),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 16),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 8),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev));
+   }
 }
 static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
 /**
@@ -99,8 +112,13 @@ static ssize_t pm8001_ctl_max_out_io_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-   pm8001_ha->main_cfg_tbl.max_out_io);
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io);
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io);
+   }
 }
 static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL);
 /**
@@ -117,8 +135,15 @@ static ssize_t pm8001_ctl_max_devices_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%04d\n",
-   (u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16));
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%04d\n",
+   (u16)(pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl >> 16)
+   );
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%04d\n",
+   (u16)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16)
+   );

[PATCH V2 01/12] pm80xx: fix for memory region free

2013-03-14 Thread Anand
>From 700bfe79294e9f9e1a5def178af52b13928902a9 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 12:10:02 +0530
Subject: [PATCH V2 01/12] pm80xx: fix for memory region free

All memory regions are allocated based on variables total_len
and alignment but free was based on element_size.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_init.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 4c9fe73..3d5e522 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -140,7 +140,8 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
for (i = 0; i < USI_MAX_MEMCNT; i++) {
if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
pci_free_consistent(pm8001_ha->pdev,
-   pm8001_ha->memoryMap.region[i].element_size,
+   (pm8001_ha->memoryMap.region[i].total_len +
+   pm8001_ha->memoryMap.region[i].alignment),
pm8001_ha->memoryMap.region[i].virt_ptr,
pm8001_ha->memoryMap.region[i].phys_addr);
}
-- 
1.7.1

>From 700bfe79294e9f9e1a5def178af52b13928902a9 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 12:10:02 +0530
Subject: [PATCH V2 01/12] pm80xx: fix for memory region free

All memory regions are allocated based on variables total_len
and alignment but free was based on element_size.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
Ack-by: Jack Wang 
---
 drivers/scsi/pm8001/pm8001_init.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 4c9fe73..3d5e522 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -140,7 +140,8 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
for (i = 0; i < USI_MAX_MEMCNT; i++) {
if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
pci_free_consistent(pm8001_ha->pdev,
-   pm8001_ha->memoryMap.region[i].element_size,
+   (pm8001_ha->memoryMap.region[i].total_len +
+   pm8001_ha->memoryMap.region[i].alignment),
pm8001_ha->memoryMap.region[i].virt_ptr,
pm8001_ha->memoryMap.region[i].phys_addr);
}
-- 
1.7.1



[PATCH V2 00/12] Support for PMC 8081/8088/8089 controllers

2013-03-14 Thread Anand
Hi,

This is second resubmission for PM8081/88/89 patchset. This handles
comments from James Bottomley and Hannes.

>From 375653061c0db3189e9e5678b11291b7b0195ac3 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Wed, 13 Mar 2013 14:09:48 +0530
Subject: [PATCH V2 00/12] Support for PMC 8081/8088/8089 controllers

Patchset V2

Resubmission of patchset addressing Hannes comment

1. Patch5 - Implemented a single tasklet to handle all MSI-x 
interrupts

Patchset V1

Resubmission of pm8001 patchset based on James Bottomley comments

1. The patch permission level corrected to 644.
2. Patches 2 3 and 4 of the original patchset have been merged to a 
   single patch (patch 2) to fix compilation error and ensure
   individual functionality.
3. Email id's changed to resolvable ids.

Sakthivel K (12):
  pm80xx: fix for memory region free
  pm80xx: Added SPCv/ve specific ids, variables and modify for SPC
  pm80xx: Multiple inbound/outbound queue configuration
  pm80xx: Updated common functions common for SPC and SPCv/ve
  pm80xx: MSI-X implementation for using 64 interrupts
  pm80xx: Added SPCv/ve specific hardware functionalities and
relavent changes in common files
  pm80xx: SPC new firmware changes for device id 0x8081 alone
  pm80xx: Firmware flash memory free fix, with addition of new memory
region for it
  pm80xx: Changed module name and debug messages update
  pm80xx: WWN Modification for PM8081/88/89 controllers
  pm80xx: NCQ error handling changes
  pm80xx: thermal, sas controller config and error handling update

 drivers/scsi/pm8001/Makefile  |7 +-
 drivers/scsi/pm8001/pm8001_ctl.c  |   74 +-
 drivers/scsi/pm8001/pm8001_defs.h |   34 +-
 drivers/scsi/pm8001/pm8001_hwi.c  |  796 +---
 drivers/scsi/pm8001/pm8001_hwi.h  |4 +-
 drivers/scsi/pm8001/pm8001_init.c |  699 ++-
 drivers/scsi/pm8001/pm8001_sas.c  |  105 +-
 drivers/scsi/pm8001/pm8001_sas.h  |  174 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c  | 4131 +
 drivers/scsi/pm8001/pm80xx_hwi.h  | 1524 ++
 10 files changed, 7163 insertions(+), 385 deletions(-)
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.c
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.h

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 00/11] Add support for iSCSI Extentions for RDMA (ISER) target

2013-03-14 Thread Or Gerlitz

On 08/03/2013 03:45, Nicholas A. Bellinger wrote:

This series is first RFC for iSCSI Extentions for RDMA (ISER) target
support with existing iscsi-target TCP based socket code for a future v3.10 
merge.

This code is available in git here:
   git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git 
iser_target-rfcv1

Ths includes a basic iscsit_transport API that allows different transports
to reside under a single iscsi-target configfs control plane, using an
pre-defined network portal attribute to enable a rdma_cm listener on top
of existing ipoib portals.


Hi Nic,

Here are quick few nits (...) which need to be sorted out for the next 
version, I've picked them from running the patches through checkpatch 
and sparse / gcc warnings checks


 target-pending]# git format-patch -o /tmp/lio-iser-rfc 
7b745c84a9f4ad62db4b67053fbceb5d706451af..

/tmp/lio-iser-rfc/0001-iscsi-target-Add-iscsit_transport-API-template.patch
/tmp/lio-iser-rfc/0002-iscsi-target-Initial-traditional-TCP-conversion-to-i.patch
/tmp/lio-iser-rfc/0003-iscsi-target-Add-iser-target-parameter-keys-setup-du.patch
/tmp/lio-iser-rfc/0004-iscsi-target-Add-per-transport-iscsi_cmd-alloc-free.patch
/tmp/lio-iser-rfc/0005-iscsi-target-Refactor-RX-PDU-logic-export-request-PD.patch
/tmp/lio-iser-rfc/0006-iscsi-target-Refactor-TX-queue-logic-export-response.patch
/tmp/lio-iser-rfc/0007-iscsi-target-Add-iser-network-portal-attribute.patch
/tmp/lio-iser-rfc/0008-iser-target-Add-base-proto-includes.patch
/tmp/lio-iser-rfc/0009-iser-target-Add-logic-for-verbs.patch
/tmp/lio-iser-rfc/0010-iser-target-Add-logic-for-core.patch
/tmp/lio-iser-rfc/0011-iser-target-Add-Makefile-Kconfig.patch

target-pending]# ./scripts/checkpatch.pl --strict /tmp/lio-iser-rfc/* | 
grep total

total: 0 errors, 8 warnings, 0 checks, 142 lines checked
total: 1 errors, 14 warnings, 6 checks, 1097 lines checked
total: 0 errors, 15 warnings, 7 checks, 299 lines checked
total: 0 errors, 0 warnings, 0 checks, 106 lines checked
total: 0 errors, 13 warnings, 4 checks, 795 lines checked
total: 1 errors, 12 warnings, 2 checks, 877 lines checked
total: 0 errors, 5 warnings, 0 checks, 83 lines checked
total: 7 errors, 12 warnings, 1 checks, 170 lines checked
total: 1 errors, 9 warnings, 14 checks, 481 lines checked
total: 1 errors, 39 warnings, 43 checks, 1732 lines checked
total: 0 errors, 0 warnings, 0 checks, 21 lines checked

drivers/infiniband/ulp/isert/isert_core.c:774:1: warning: symbol 
'isert_dump_ib_wc' was not declared. Should it be static?
drivers/infiniband/ulp/isert/isert_verbs.c:341:1: warning: symbol 
'isert_put_conn' was not declared. Should it be static?
drivers/infiniband/ulp/isert/isert_verbs.c:375:1: warning: symbol 
'isert_cma_handler' was not declared. Should it be static?
drivers/infiniband/ulp/isert/isert_verbs.c:416:1: warning: symbol 
'isert_post_recv' was not declared. Should it be static?
drivers/infiniband/ulp/isert/isert_verbs.c:451:1: warning: symbol 
'isert_post_send' was not declared. Should it be static?


drivers/infiniband/ulp/isert/isert_core.c: In function ?isert_rx_do_work?:
drivers/infiniband/ulp/isert/isert_core.c:481: warning: variable ?rc? 
set but not used



Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html