aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001
diff options
context:
space:
mode:
authorAnand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>2013-09-18 03:32:44 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 04:58:16 -0400
commit279094079a442c19ff7e7c0fd9511d9404cb2518 (patch)
tree58a509a4ecb9160ddb5793db4200f9a6f7f5af68 /drivers/scsi/pm8001
parent06f12f22cefdc2737b54fc986d9b82ec358cdbb8 (diff)
[SCSI] pm80xx: Phy settings support for motherboard controller.
Phy profile implementation to support phy settings feature for motherboard controllers. [jejb: checkpatch fixes] Signed-off-by: Anandkumar.Santhanam@pmcs.com Reviewed-by: Jack Wang <jinpu.wang@profitbricks.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/pm8001')
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c10
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c29
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h3
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c61
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.h4
5 files changed, 104 insertions, 3 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 7e879c5d0928..9d1178bcf689 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4831,6 +4831,16 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
4831 cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo); 4831 cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
4832 break; 4832 break;
4833 } 4833 }
4834 case IOP_RDUMP: {
4835 nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | IOP_RDUMP);
4836 nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
4837 nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset);
4838 nvmd_req.resp_addr_hi =
4839 cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
4840 nvmd_req.resp_addr_lo =
4841 cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
4842 break;
4843 }
4834 default: 4844 default:
4835 break; 4845 break;
4836 } 4846 }
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 93e2d9e9d2b3..92a18c4d2ebb 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -667,6 +667,31 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
667#endif 667#endif
668} 668}
669 669
670/*
671 * pm8001_get_phy_settings_info : Read phy setting values.
672 * @pm8001_ha : our hba.
673 */
674void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
675{
676
677#ifdef PM8001_READ_VPD
678 /*OPTION ROM FLASH read for the SPC cards */
679 DECLARE_COMPLETION_ONSTACK(completion);
680 struct pm8001_ioctl_payload payload;
681
682 pm8001_ha->nvmd_completion = &completion;
683 /* SAS ADDRESS read from flash / EEPROM */
684 payload.minor_function = 6;
685 payload.offset = 0;
686 payload.length = 4096;
687 payload.func_specific = kzalloc(4096, GFP_KERNEL);
688 /* Read phy setting values from flash */
689 PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
690 wait_for_completion(&completion);
691 pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific);
692#endif
693}
694
670#ifdef PM8001_USE_MSIX 695#ifdef PM8001_USE_MSIX
671/** 696/**
672 * pm8001_setup_msix - enable MSI-X interrupt 697 * pm8001_setup_msix - enable MSI-X interrupt
@@ -847,6 +872,10 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
847 } 872 }
848 873
849 pm8001_init_sas_add(pm8001_ha); 874 pm8001_init_sas_add(pm8001_ha);
875 /* phy setting support for motherboard controller */
876 if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 &&
877 pdev->subsystem_vendor != 0)
878 pm8001_get_phy_settings_info(pm8001_ha);
850 pm8001_post_sas_ha_init(shost, chip); 879 pm8001_post_sas_ha_init(shost, chip);
851 rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); 880 rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
852 if (rc) 881 if (rc)
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 68e1147e3cec..cbde11a57a92 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -632,7 +632,8 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
632int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha); 632int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
633 633
634int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue); 634int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
635 635void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
636 u32 length, u8 *buf);
636/* ctl shared API */ 637/* ctl shared API */
637extern struct device_attribute *pm8001_host_attrs[]; 638extern struct device_attribute *pm8001_host_attrs[];
638 639
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index c8a4465b74a5..91cf4242a03d 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3183,9 +3183,27 @@ static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3183static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, 3183static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
3184 void *piomb) 3184 void *piomb)
3185{ 3185{
3186 PM8001_MSG_DBG(pm8001_ha, 3186 u8 page_code;
3187 pm8001_printk(" pm80xx_addition_functionality\n")); 3187 struct set_phy_profile_resp *pPayload =
3188 (struct set_phy_profile_resp *)(piomb + 4);
3189 u32 ppc_phyid = le32_to_cpu(pPayload->ppc_phyid);
3190 u32 status = le32_to_cpu(pPayload->status);
3188 3191
3192 page_code = (u8)((ppc_phyid & 0xFF00) >> 8);
3193 if (status) {
3194 /* status is FAILED */
3195 PM8001_FAIL_DBG(pm8001_ha,
3196 pm8001_printk("PhyProfile command failed with status "
3197 "0x%08X \n", status));
3198 return -1;
3199 } else {
3200 if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) {
3201 PM8001_FAIL_DBG(pm8001_ha,
3202 pm8001_printk("Invalid page code 0x%X\n",
3203 page_code));
3204 return -1;
3205 }
3206 }
3189 return 0; 3207 return 0;
3190} 3208}
3191 3209
@@ -4281,6 +4299,45 @@ pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
4281 return IRQ_HANDLED; 4299 return IRQ_HANDLED;
4282} 4300}
4283 4301
4302void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
4303 u32 operation, u32 phyid, u32 length, u32 *buf)
4304{
4305 u32 tag , i, j = 0;
4306 int rc;
4307 struct set_phy_profile_req payload;
4308 struct inbound_queue_table *circularQ;
4309 u32 opc = OPC_INB_SET_PHY_PROFILE;
4310
4311 memset(&payload, 0, sizeof(payload));
4312 rc = pm8001_tag_alloc(pm8001_ha, &tag);
4313 if (rc)
4314 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
4315 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4316 payload.tag = cpu_to_le32(tag);
4317 payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid & 0xFF));
4318 PM8001_INIT_DBG(pm8001_ha,
4319 pm8001_printk(" phy profile command for phy %x ,length is %d\n",
4320 payload.ppc_phyid, length));
4321 for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) {
4322 payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
4323 j++;
4324 }
4325 pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
4326}
4327
4328void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
4329 u32 length, u8 *buf)
4330{
4331 u32 page_code, i;
4332
4333 page_code = SAS_PHY_ANALOG_SETTINGS_PAGE;
4334 for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
4335 mpi_set_phy_profile_req(pm8001_ha,
4336 SAS_PHY_ANALOG_SETTINGS_PAGE, i, length, (u32 *)buf);
4337 length = length + PHY_DWORD_LENGTH;
4338 }
4339 PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
4340}
4284const struct pm8001_dispatch pm8001_80xx_dispatch = { 4341const struct pm8001_dispatch pm8001_80xx_dispatch = {
4285 .name = "pmc80xx", 4342 .name = "pmc80xx",
4286 .chip_init = pm80xx_chip_init, 4343 .chip_init = pm80xx_chip_init,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 9a9116d43566..872d5cff824f 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -170,6 +170,10 @@
170#define LINKRATE_60 (0x06 << 8) 170#define LINKRATE_60 (0x06 << 8)
171#define LINKRATE_120 (0x08 << 8) 171#define LINKRATE_120 (0x08 << 8)
172 172
173/* phy_profile */
174#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
175#define PHY_DWORD_LENGTH 0xC
176
173/* Thermal related */ 177/* Thermal related */
174#define THERMAL_ENABLE 0x1 178#define THERMAL_ENABLE 0x1
175#define THERMAL_LOG_ENABLE 0x1 179#define THERMAL_LOG_ENABLE 0x1