All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Rood <benjaminjrood@gmail.com>
To: linux-scsi@vger.kernel.org, xjtuwjp@gmail.com,
	James.Bottomley@HansenPartnership.com
Cc: Benjamin Rood <brood@attotech.com>
Subject: [PATCH 5/8] pm80xx: set PHY profiles for ATTO 12Gb SAS controllers
Date: Fri, 30 Oct 2015 10:53:28 -0400	[thread overview]
Message-ID: <1446216811-2248-6-git-send-email-brood@attotech.com> (raw)
In-Reply-To: <1446216811-2248-1-git-send-email-brood@attotech.com>

PHY profiles are not saved in NVRAM on ATTO 12Gb SAS controllers.
Therefore, in order for the controller to function in a wide range of
configurations, the PHY profiles must be statically set.  This patch
provides the necessary functionality to do so.

Signed-off-by: Benjamin Rood <brood@attotech.com>
---
 drivers/scsi/pm8001/pm8001_init.c | 130 ++++++++++++++++++++++++++++++++++++++
 drivers/scsi/pm8001/pm8001_sas.h  |   2 +
 drivers/scsi/pm8001/pm80xx_hwi.c  |  32 ++++++++++
 3 files changed, 164 insertions(+)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index fdbfab6..a0e55d4 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -732,6 +732,131 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
 	return 0;
 }
 
+struct pm8001_mpi3_phy_pg_trx_config {
+	u32 LaneLosCfg;
+	u32 LanePgaCfg1;
+	u32 LanePisoCfg1;
+	u32 LanePisoCfg2;
+	u32 LanePisoCfg3;
+	u32 LanePisoCfg4;
+	u32 LanePisoCfg5;
+	u32 LanePisoCfg6;
+	u32 LaneBctCtrl;
+};
+
+/**
+ * pm8001_get_internal_phy_settings : Retrieves the internal PHY settings
+ * @pm8001_ha : our adapter
+ * @phycfg : PHY config page to populate
+ */
+static
+void pm8001_get_internal_phy_settings(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_mpi3_phy_pg_trx_config *phycfg)
+{
+	phycfg->LaneLosCfg   = 0x00000132;
+	phycfg->LanePgaCfg1  = 0x00203949;
+	phycfg->LanePisoCfg1 = 0x000000FF;
+	phycfg->LanePisoCfg2 = 0xFF000001;
+	phycfg->LanePisoCfg3 = 0xE7011300;
+	phycfg->LanePisoCfg4 = 0x631C40C0;
+	phycfg->LanePisoCfg5 = 0xF8102036;
+	phycfg->LanePisoCfg6 = 0xF74A1000;
+	phycfg->LaneBctCtrl  = 0x00FB33F8;
+}
+
+/**
+ * pm8001_get_external_phy_settings : Retrieves the external PHY settings
+ * @pm8001_ha : our adapter
+ * @phycfg : PHY config page to populate
+ */
+static
+void pm8001_get_external_phy_settings(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_mpi3_phy_pg_trx_config *phycfg)
+{
+	phycfg->LaneLosCfg   = 0x00000132;
+	phycfg->LanePgaCfg1  = 0x00203949;
+	phycfg->LanePisoCfg1 = 0x000000FF;
+	phycfg->LanePisoCfg2 = 0xFF000001;
+	phycfg->LanePisoCfg3 = 0xE7011300;
+	phycfg->LanePisoCfg4 = 0x63349140;
+	phycfg->LanePisoCfg5 = 0xF8102036;
+	phycfg->LanePisoCfg6 = 0xF80D9300;
+	phycfg->LaneBctCtrl  = 0x00FB33F8;
+}
+
+/**
+ * pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext
+ * @pm8001_ha : our adapter
+ * @phymask : The PHY mask
+ */
+static
+void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask)
+{
+	switch (pm8001_ha->pdev->subsystem_device) {
+	case 0x0070: /* H1280 - 8 external 0 internal */
+	case 0x0072: /* H12F0 - 16 external 0 internal */
+		*phymask = 0x0000;
+		break;
+
+	case 0x0071: /* H1208 - 0 external 8 internal */
+	case 0x0073: /* H120F - 0 external 16 internal */
+		*phymask = 0xFFFF;
+		break;
+
+	case 0x0080: /* H1244 - 4 external 4 internal */
+		*phymask = 0x00F0;
+		break;
+
+	case 0x0081: /* H1248 - 4 external 8 internal */
+		*phymask = 0x0FF0;
+		break;
+
+	case 0x0082: /* H1288 - 8 external 8 internal */
+		*phymask = 0xFF00;
+		break;
+
+	default:
+		PM8001_INIT_DBG(pm8001_ha,
+			pm8001_printk("Unknown subsystem device=0x%.04x",
+				pm8001_ha->pdev->subsystem_device));
+	}
+}
+
+/**
+ * pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings
+ * @pm8001_ha : our adapter
+ */
+static
+int pm8001_set_phy_settings_ven_117c_12G(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pm8001_mpi3_phy_pg_trx_config phycfg_int;
+	struct pm8001_mpi3_phy_pg_trx_config phycfg_ext;
+	int phymask = 0;
+	int i = 0;
+
+	memset(&phycfg_int, 0, sizeof(phycfg_int));
+	memset(&phycfg_ext, 0, sizeof(phycfg_ext));
+
+	pm8001_get_internal_phy_settings(pm8001_ha, &phycfg_int);
+	pm8001_get_external_phy_settings(pm8001_ha, &phycfg_ext);
+	pm8001_get_phy_mask(pm8001_ha, &phymask);
+
+	for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+		if (phymask & (1 << i)) {/* Internal PHY */
+			pm8001_set_phy_profile_single(pm8001_ha, i,
+					sizeof(phycfg_int) / sizeof(u32),
+					(u32 *)&phycfg_int);
+
+		} else { /* External PHY */
+			pm8001_set_phy_profile_single(pm8001_ha, i,
+					sizeof(phycfg_ext) / sizeof(u32),
+					(u32 *)&phycfg_ext);
+		}
+	}
+
+	return 0;
+}
+
 /**
  * pm8001_configure_phy_settings : Configures PHY settings based on vendor ID.
  * @pm8001_ha : our hba.
@@ -740,6 +865,11 @@ static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
 {
 	switch (pm8001_ha->pdev->subsystem_vendor) {
 	case PCI_VENDOR_ID_ATTO:
+		if (pm8001_ha->pdev->device == 0x0042) /* 6Gb */
+			return 0;
+		else
+			return pm8001_set_phy_settings_ven_117c_12G(pm8001_ha);
+
 	case PCI_VENDOR_ID_ADAPTEC2:
 	case 0:
 		return 0;
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 9fa9705..6628cc3 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -710,6 +710,8 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
 int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
 void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
 	u32 length, u8 *buf);
+void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
+		u32 phy, u32 length, u32 *buf);
 int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
 ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 		struct device_attribute *attr, char *buf);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 9a389f1..29c548b 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4576,6 +4576,38 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
 	}
 	PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
 }
+
+void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
+		u32 phy, u32 length, u32 *buf)
+{
+	u32 tag, opc;
+	int rc, i;
+	struct set_phy_profile_req payload;
+	struct inbound_queue_table *circularQ;
+
+	memset(&payload, 0, sizeof(payload));
+
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Invalid tag"));
+
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	opc = OPC_INB_SET_PHY_PROFILE;
+
+	payload.tag = cpu_to_le32(tag);
+	payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
+				| (phy & 0xFF));
+
+	for (i = 0; i < length; i++)
+		payload.reserved[i] = cpu_to_le32(*(buf + i));
+
+	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+	if (rc)
+		pm8001_tag_free(pm8001_ha, tag);
+
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("PHY %d settings applied", phy));
+}
 const struct pm8001_dispatch pm8001_80xx_dispatch = {
 	.name			= "pmc80xx",
 	.chip_init		= pm80xx_chip_init,
-- 
2.4.3


  parent reply	other threads:[~2015-10-30 14:53 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-30 14:53 [PATCH 0/8] pm80xx: Add ATTO 12Gb HBA support and fix various issues Benjamin Rood
2015-10-30 14:53 ` [PATCH 1/8] pm80xx: configure PHY settings based on subsystem vendor ID Benjamin Rood
2015-11-02  7:51   ` Hannes Reinecke
2015-11-02  8:00   ` Jack Wang
2015-10-30 14:53 ` [PATCH 2/8] pm80xx: add support for PMC Sierra 8070 and PMC Sierra 8072 SAS controllers Benjamin Rood
2015-11-02  7:51   ` Hannes Reinecke
2015-11-02  8:01   ` Jack Wang
2015-10-30 14:53 ` [PATCH 3/8] pm80xx: add ATTO PCI IDs to pm8001_pci_table Benjamin Rood
2015-11-02  7:52   ` Hannes Reinecke
2015-11-02  8:02   ` Jack Wang
2015-10-30 14:53 ` [PATCH 4/8] pm80xx: add support for ATTO devices during SAS address initiailization Benjamin Rood
2015-11-02  7:53   ` Hannes Reinecke
2015-11-02  8:06     ` Jack Wang
2015-11-02 20:39       ` [PATCH v2 4/9] " Benjamin Rood
2015-10-30 14:53 ` Benjamin Rood [this message]
2015-11-02  7:57   ` [PATCH 5/8] pm80xx: set PHY profiles for ATTO 12Gb SAS controllers Hannes Reinecke
2015-11-02  8:08   ` Jack Wang
2015-10-30 14:53 ` [PATCH 6/8] pm80xx: do not examine registers for iButton feature if ATTO adapter Benjamin Rood
2015-11-02  7:58   ` Hannes Reinecke
2015-11-02  8:08   ` Jack Wang
2015-10-30 14:53 ` [PATCH 7/8] pm80xx: wait a minimum of 500ms before issuing commands to SPCv Benjamin Rood
2015-11-02  8:00   ` Hannes Reinecke
2015-11-02  8:12   ` Jack Wang
2015-11-02 20:42     ` [PATCH v2 7/9] " Benjamin Rood
2015-10-30 14:53 ` [PATCH 8/8] pm80xx: avoid a panic if MSI(X) interrupts are disabled Benjamin Rood
2015-11-02  8:01   ` Hannes Reinecke
2015-11-02  8:12   ` Jack Wang
2015-11-03  4:44 ` [PATCH 0/8] pm80xx: Add ATTO 12Gb HBA support and fix various issues Martin K. Petersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1446216811-2248-6-git-send-email-brood@attotech.com \
    --to=benjaminjrood@gmail.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=brood@attotech.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=xjtuwjp@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.