diff options
author | John Garry <john.garry@huawei.com> | 2018-05-21 06:09:13 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-05-28 22:40:31 -0400 |
commit | 757db2dae2c79b1f713043fcc13542683963fa82 (patch) | |
tree | 729057109aa8fd2da7565b9daf6aa95d42b8a4a9 /drivers/scsi | |
parent | eb217359ebeae7b9ac51045d50f7a516925bc5c2 (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.c | 29 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 35 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 21 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 21 |
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 | ||
869 | static 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 | |||
869 | static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, | 896 | static 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) | |||
855 | static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no, | 855 | static 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 | ||
893 | static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) | 866 | static 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) | |||
1600 | static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no, | 1600 | static 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 | ||
1628 | static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) | 1611 | static 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) | |||
1879 | static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, | 1879 | static 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 | ||
1907 | static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) | 1890 | static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) |