Skip to content

Commit

Permalink
[SCSI] pm80xx: Phy settings support for motherboard controller.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Anand Kumar Santhanam authored and James Bottomley committed Oct 25, 2013
1 parent 06f12f2 commit 2790940
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 3 deletions.
10 changes: 10 additions & 0 deletions drivers/scsi/pm8001/pm8001_hwi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4831,6 +4831,16 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
break;
}
case IOP_RDUMP: {
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | IOP_RDUMP);
nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
break;
}
default:
break;
}
Expand Down
29 changes: 29 additions & 0 deletions drivers/scsi/pm8001/pm8001_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,31 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
#endif
}

/*
* pm8001_get_phy_settings_info : Read phy setting values.
* @pm8001_ha : our hba.
*/
void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
{

#ifdef PM8001_READ_VPD
/*OPTION ROM FLASH read for the SPC cards */
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;

pm8001_ha->nvmd_completion = &completion;
/* SAS ADDRESS read from flash / EEPROM */
payload.minor_function = 6;
payload.offset = 0;
payload.length = 4096;
payload.func_specific = kzalloc(4096, GFP_KERNEL);
/* Read phy setting values from flash */
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
wait_for_completion(&completion);
pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific);
#endif
}

#ifdef PM8001_USE_MSIX
/**
* pm8001_setup_msix - enable MSI-X interrupt
Expand Down Expand Up @@ -847,6 +872,10 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
}

pm8001_init_sas_add(pm8001_ha);
/* phy setting support for motherboard controller */
if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 &&
pdev->subsystem_vendor != 0)
pm8001_get_phy_settings_info(pm8001_ha);
pm8001_post_sas_ha_init(shost, chip);
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
if (rc)
Expand Down
3 changes: 2 additions & 1 deletion drivers/scsi/pm8001/pm8001_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,8 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
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);
/* ctl shared API */
extern struct device_attribute *pm8001_host_attrs[];

Expand Down
61 changes: 59 additions & 2 deletions drivers/scsi/pm8001/pm80xx_hwi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3183,9 +3183,27 @@ static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk(" pm80xx_addition_functionality\n"));
u8 page_code;
struct set_phy_profile_resp *pPayload =
(struct set_phy_profile_resp *)(piomb + 4);
u32 ppc_phyid = le32_to_cpu(pPayload->ppc_phyid);
u32 status = le32_to_cpu(pPayload->status);

page_code = (u8)((ppc_phyid & 0xFF00) >> 8);
if (status) {
/* status is FAILED */
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("PhyProfile command failed with status "
"0x%08X \n", status));
return -1;
} else {
if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) {
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Invalid page code 0x%X\n",
page_code));
return -1;
}
}
return 0;
}

Expand Down Expand Up @@ -4281,6 +4299,45 @@ pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
return IRQ_HANDLED;
}

void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
u32 operation, u32 phyid, u32 length, u32 *buf)
{
u32 tag , i, j = 0;
int rc;
struct set_phy_profile_req payload;
struct inbound_queue_table *circularQ;
u32 opc = OPC_INB_SET_PHY_PROFILE;

memset(&payload, 0, sizeof(payload));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
if (rc)
PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
circularQ = &pm8001_ha->inbnd_q_tbl[0];
payload.tag = cpu_to_le32(tag);
payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid & 0xFF));
PM8001_INIT_DBG(pm8001_ha,
pm8001_printk(" phy profile command for phy %x ,length is %d\n",
payload.ppc_phyid, length));
for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) {
payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
j++;
}
pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
}

void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
u32 length, u8 *buf)
{
u32 page_code, i;

page_code = SAS_PHY_ANALOG_SETTINGS_PAGE;
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
mpi_set_phy_profile_req(pm8001_ha,
SAS_PHY_ANALOG_SETTINGS_PAGE, i, length, (u32 *)buf);
length = length + PHY_DWORD_LENGTH;
}
PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
}
const struct pm8001_dispatch pm8001_80xx_dispatch = {
.name = "pmc80xx",
.chip_init = pm80xx_chip_init,
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/pm8001/pm80xx_hwi.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@
#define LINKRATE_60 (0x06 << 8)
#define LINKRATE_120 (0x08 << 8)

/* phy_profile */
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
#define PHY_DWORD_LENGTH 0xC

/* Thermal related */
#define THERMAL_ENABLE 0x1
#define THERMAL_LOG_ENABLE 0x1
Expand Down

0 comments on commit 2790940

Please sign in to comment.