summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJohn Garry <john.garry@huawei.com>2018-05-21 06:09:13 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-28 22:40:31 -0400
commit757db2dae2c79b1f713043fcc13542683963fa82 (patch)
tree729057109aa8fd2da7565b9daf6aa95d42b8a4a9 /drivers/scsi
parenteb217359ebeae7b9ac51045d50f7a516925bc5c2 (diff)
scsi: hisi_sas: Introduce hisi_sas_phy_set_linkrate()
There is much common code and functionality between the HW versions to set the PHY linkrate. As such, this patch factors out the common code into a generic function hisi_sas_phy_set_linkrate(). Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c29
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v1_hw.c35
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c21
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c21
4 files changed, 36 insertions, 70 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 6d3796553272..66388741e73c 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -866,6 +866,33 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags)
866 return hisi_sas_task_exec(task, gfp_flags, 0, NULL); 866 return hisi_sas_task_exec(task, gfp_flags, 0, NULL);
867} 867}
868 868
869static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
870 struct sas_phy_linkrates *r)
871{
872 struct sas_phy_linkrates _r;
873
874 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
875 struct asd_sas_phy *sas_phy = &phy->sas_phy;
876 enum sas_linkrate min, max;
877
878 if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
879 max = sas_phy->phy->maximum_linkrate;
880 min = r->minimum_linkrate;
881 } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
882 max = r->maximum_linkrate;
883 min = sas_phy->phy->minimum_linkrate;
884 } else
885 return;
886
887 _r.maximum_linkrate = max;
888 _r.minimum_linkrate = min;
889
890 hisi_hba->hw->phy_disable(hisi_hba, phy_no);
891 msleep(100);
892 hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
893 hisi_hba->hw->phy_start(hisi_hba, phy_no);
894}
895
869static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, 896static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
870 void *funcdata) 897 void *funcdata)
871{ 898{
@@ -889,7 +916,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
889 break; 916 break;
890 917
891 case PHY_FUNC_SET_LINK_RATE: 918 case PHY_FUNC_SET_LINK_RATE:
892 hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, funcdata); 919 hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata);
893 break; 920 break;
894 case PHY_FUNC_GET_EVENTS: 921 case PHY_FUNC_GET_EVENTS:
895 if (hisi_hba->hw->get_events) { 922 if (hisi_hba->hw->get_events) {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index abe175fddb86..8fa79d0968a6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -855,39 +855,12 @@ static enum sas_linkrate phy_get_max_linkrate_v1_hw(void)
855static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no, 855static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
856 struct sas_phy_linkrates *r) 856 struct sas_phy_linkrates *r)
857{ 857{
858 u32 prog_phy_link_rate = 858 enum sas_linkrate max = r->maximum_linkrate;
859 hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); 859 u32 prog_phy_link_rate = 0x800;
860 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
861 struct asd_sas_phy *sas_phy = &phy->sas_phy;
862 int i;
863 enum sas_linkrate min, max;
864 u32 rate_mask = 0;
865
866 if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
867 max = sas_phy->phy->maximum_linkrate;
868 min = r->minimum_linkrate;
869 } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
870 max = r->maximum_linkrate;
871 min = sas_phy->phy->minimum_linkrate;
872 } else
873 return;
874
875 sas_phy->phy->maximum_linkrate = max;
876 sas_phy->phy->minimum_linkrate = min;
877
878 max -= SAS_LINK_RATE_1_5_GBPS;
879 860
880 for (i = 0; i <= max; i++) 861 prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
881 rate_mask |= 1 << (i * 2);
882
883 prog_phy_link_rate &= ~0xff;
884 prog_phy_link_rate |= rate_mask;
885
886 disable_phy_v1_hw(hisi_hba, phy_no);
887 msleep(100);
888 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, 862 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
889 prog_phy_link_rate); 863 prog_phy_link_rate);
890 start_phy_v1_hw(hisi_hba, phy_no);
891} 864}
892 865
893static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) 866static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 911bb76a4d0a..fb0e966a44a8 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1600,29 +1600,12 @@ static enum sas_linkrate phy_get_max_linkrate_v2_hw(void)
1600static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no, 1600static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
1601 struct sas_phy_linkrates *r) 1601 struct sas_phy_linkrates *r)
1602{ 1602{
1603 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; 1603 enum sas_linkrate max = r->maximum_linkrate;
1604 struct asd_sas_phy *sas_phy = &phy->sas_phy;
1605 enum sas_linkrate min, max;
1606 u32 prog_phy_link_rate = 0x800; 1604 u32 prog_phy_link_rate = 0x800;
1607 1605
1608 if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
1609 max = sas_phy->phy->maximum_linkrate;
1610 min = r->minimum_linkrate;
1611 } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
1612 max = r->maximum_linkrate;
1613 min = sas_phy->phy->minimum_linkrate;
1614 } else
1615 return;
1616
1617 sas_phy->phy->maximum_linkrate = max;
1618 sas_phy->phy->minimum_linkrate = min;
1619 prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); 1606 prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
1620
1621 disable_phy_v2_hw(hisi_hba, phy_no);
1622 msleep(100);
1623 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, 1607 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
1624 prog_phy_link_rate); 1608 prog_phy_link_rate);
1625 start_phy_v2_hw(hisi_hba, phy_no);
1626} 1609}
1627 1610
1628static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) 1611static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index c013673ee8ac..0a80a39eccdd 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -1879,29 +1879,12 @@ static int hisi_sas_v3_init(struct hisi_hba *hisi_hba)
1879static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, 1879static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
1880 struct sas_phy_linkrates *r) 1880 struct sas_phy_linkrates *r)
1881{ 1881{
1882 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; 1882 enum sas_linkrate max = r->maximum_linkrate;
1883 struct asd_sas_phy *sas_phy = &phy->sas_phy;
1884 enum sas_linkrate min, max;
1885 u32 prog_phy_link_rate = 0x800; 1883 u32 prog_phy_link_rate = 0x800;
1886 1884
1887 if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
1888 max = sas_phy->phy->maximum_linkrate;
1889 min = r->minimum_linkrate;
1890 } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
1891 max = r->maximum_linkrate;
1892 min = sas_phy->phy->minimum_linkrate;
1893 } else
1894 return;
1895
1896 sas_phy->phy->maximum_linkrate = max;
1897 sas_phy->phy->minimum_linkrate = min;
1898 prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); 1885 prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
1899
1900 disable_phy_v3_hw(hisi_hba, phy_no);
1901 msleep(100);
1902 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, 1886 hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
1903 prog_phy_link_rate); 1887 prog_phy_link_rate);
1904 start_phy_v3_hw(hisi_hba, phy_no);
1905} 1888}
1906 1889
1907static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) 1890static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)