diff options
author | Dave Olson <dave.olson@qlogic.com> | 2008-01-08 05:36:46 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-01-25 17:15:45 -0500 |
commit | c4bce8032ef4368063c84d665b19804878d63e7c (patch) | |
tree | 29b7e0b7a97747982237a98f634a97d2111d1d8a /drivers/infiniband/hw/ipath/ipath_iba6110.c | |
parent | 7387273307139ebf8d7f7fb3bb79d1ca48bd71d6 (diff) |
IB/ipath: Add new chip-specific functions to older chips, consistent init
This adds the new (sometimes empty) chip-specific functions to the older
chips, and makes the initialization and related functions consistent across
all 3 chips.
Signed-off-by: Dave Olson <dave.olson@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_iba6110.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6110.c | 172 |
1 files changed, 156 insertions, 16 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index ac436c630bcc..9e2ced3cdc5e 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
@@ -329,6 +329,9 @@ static const struct ipath_cregs ipath_ht_cregs = { | |||
329 | #define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL | 329 | #define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL |
330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL | 330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL |
331 | 331 | ||
332 | #define IBA6110_IBCS_LINKTRAININGSTATE_MASK 0xf | ||
333 | #define IBA6110_IBCS_LINKSTATE_SHIFT 4 | ||
334 | |||
332 | /* kr_extstatus bits */ | 335 | /* kr_extstatus bits */ |
333 | #define INFINIPATH_EXTS_FREQSEL 0x2 | 336 | #define INFINIPATH_EXTS_FREQSEL 0x2 |
334 | #define INFINIPATH_EXTS_SERDESSEL 0x4 | 337 | #define INFINIPATH_EXTS_SERDESSEL 0x4 |
@@ -705,7 +708,6 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | |||
705 | "with ID %u\n", boardrev); | 708 | "with ID %u\n", boardrev); |
706 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", | 709 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", |
707 | boardrev); | 710 | boardrev); |
708 | ret = 1; | ||
709 | break; | 711 | break; |
710 | } | 712 | } |
711 | if (n) | 713 | if (n) |
@@ -1137,11 +1139,49 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd, | |||
1137 | 1139 | ||
1138 | static void ipath_init_ht_variables(struct ipath_devdata *dd) | 1140 | static void ipath_init_ht_variables(struct ipath_devdata *dd) |
1139 | { | 1141 | { |
1142 | /* | ||
1143 | * setup the register offsets, since they are different for each | ||
1144 | * chip | ||
1145 | */ | ||
1146 | dd->ipath_kregs = &ipath_ht_kregs; | ||
1147 | dd->ipath_cregs = &ipath_ht_cregs; | ||
1148 | |||
1140 | dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; | 1149 | dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; |
1141 | dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; | 1150 | dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; |
1142 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; | 1151 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; |
1143 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; | 1152 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; |
1144 | 1153 | ||
1154 | /* | ||
1155 | * Fill in data for field-values that change in newer chips. | ||
1156 | * We dynamically specify only the mask for LINKTRAININGSTATE | ||
1157 | * and only the shift for LINKSTATE, as they are the only ones | ||
1158 | * that change. Also precalculate the 3 link states of interest | ||
1159 | * and the combined mask. | ||
1160 | */ | ||
1161 | dd->ibcs_ls_shift = IBA6110_IBCS_LINKSTATE_SHIFT; | ||
1162 | dd->ibcs_lts_mask = IBA6110_IBCS_LINKTRAININGSTATE_MASK; | ||
1163 | dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << | ||
1164 | dd->ibcs_ls_shift) | dd->ibcs_lts_mask; | ||
1165 | dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
1166 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
1167 | (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); | ||
1168 | dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
1169 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
1170 | (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); | ||
1171 | dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
1172 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
1173 | (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); | ||
1174 | |||
1175 | /* | ||
1176 | * Fill in data for ibcc field-values that change in newer chips. | ||
1177 | * We dynamically specify only the mask for LINKINITCMD | ||
1178 | * and only the shift for LINKCMD and MAXPKTLEN, as they are | ||
1179 | * the only ones that change. | ||
1180 | */ | ||
1181 | dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK; | ||
1182 | dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT; | ||
1183 | dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
1184 | |||
1145 | /* Fill in shifts for RcvCtrl. */ | 1185 | /* Fill in shifts for RcvCtrl. */ |
1146 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; | 1186 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; |
1147 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; | 1187 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; |
@@ -1204,6 +1244,8 @@ static void ipath_init_ht_variables(struct ipath_devdata *dd) | |||
1204 | 1244 | ||
1205 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | 1245 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; |
1206 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | 1246 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; |
1247 | dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; | ||
1248 | dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; | ||
1207 | 1249 | ||
1208 | /* | 1250 | /* |
1209 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. | 1251 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. |
@@ -1217,9 +1259,17 @@ static void ipath_init_ht_variables(struct ipath_devdata *dd) | |||
1217 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | 1259 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK << |
1218 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; | 1260 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; |
1219 | 1261 | ||
1220 | dd->ipath_eep_st_masks[2].errs_to_log = | 1262 | dd->ipath_eep_st_masks[2].errs_to_log = INFINIPATH_E_RESET; |
1221 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; | ||
1222 | 1263 | ||
1264 | dd->delay_mult = 2; /* SDR, 4X, can't change */ | ||
1265 | |||
1266 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; | ||
1267 | dd->ipath_link_speed_supported = IPATH_IB_SDR; | ||
1268 | dd->ipath_link_width_enabled = IB_WIDTH_4X; | ||
1269 | dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; | ||
1270 | /* these can't change for this chip, so set once */ | ||
1271 | dd->ipath_link_width_active = dd->ipath_link_width_enabled; | ||
1272 | dd->ipath_link_speed_active = dd->ipath_link_speed_enabled; | ||
1223 | } | 1273 | } |
1224 | 1274 | ||
1225 | /** | 1275 | /** |
@@ -1281,6 +1331,9 @@ static void ipath_ht_init_hwerrors(struct ipath_devdata *dd) | |||
1281 | dd->ipath_hwerrmask = val; | 1331 | dd->ipath_hwerrmask = val; |
1282 | } | 1332 | } |
1283 | 1333 | ||
1334 | |||
1335 | |||
1336 | |||
1284 | /** | 1337 | /** |
1285 | * ipath_ht_bringup_serdes - bring up the serdes | 1338 | * ipath_ht_bringup_serdes - bring up the serdes |
1286 | * @dd: the infinipath device | 1339 | * @dd: the infinipath device |
@@ -1439,6 +1492,7 @@ static void ipath_ht_put_tid(struct ipath_devdata *dd, | |||
1439 | pa |= lenvalid | INFINIPATH_RT_VALID; | 1492 | pa |= lenvalid | INFINIPATH_RT_VALID; |
1440 | } | 1493 | } |
1441 | } | 1494 | } |
1495 | |||
1442 | writeq(pa, tidptr); | 1496 | writeq(pa, tidptr); |
1443 | } | 1497 | } |
1444 | 1498 | ||
@@ -1644,6 +1698,13 @@ static void ipath_ht_free_irq(struct ipath_devdata *dd) | |||
1644 | dd->ipath_intconfig = 0; | 1698 | dd->ipath_intconfig = 0; |
1645 | } | 1699 | } |
1646 | 1700 | ||
1701 | static struct ipath_message_header * | ||
1702 | ipath_ht_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) | ||
1703 | { | ||
1704 | return (struct ipath_message_header *) | ||
1705 | &rhf_addr[sizeof(u64) / sizeof(u32)]; | ||
1706 | } | ||
1707 | |||
1647 | static void ipath_ht_config_ports(struct ipath_devdata *dd, ushort cfgports) | 1708 | static void ipath_ht_config_ports(struct ipath_devdata *dd, ushort cfgports) |
1648 | { | 1709 | { |
1649 | dd->ipath_portcnt = | 1710 | dd->ipath_portcnt = |
@@ -1757,6 +1818,90 @@ static void ipath_ht_read_counters(struct ipath_devdata *dd, | |||
1757 | cntrs->RxDlidFltrCnt = 0; | 1818 | cntrs->RxDlidFltrCnt = 0; |
1758 | } | 1819 | } |
1759 | 1820 | ||
1821 | |||
1822 | /* no interrupt fallback for these chips */ | ||
1823 | static int ipath_ht_nointr_fallback(struct ipath_devdata *dd) | ||
1824 | { | ||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | |||
1829 | /* | ||
1830 | * reset the XGXS (between serdes and IBC). Slightly less intrusive | ||
1831 | * than resetting the IBC or external link state, and useful in some | ||
1832 | * cases to cause some retraining. To do this right, we reset IBC | ||
1833 | * as well. | ||
1834 | */ | ||
1835 | static void ipath_ht_xgxs_reset(struct ipath_devdata *dd) | ||
1836 | { | ||
1837 | u64 val, prev_val; | ||
1838 | |||
1839 | prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | ||
1840 | val = prev_val | INFINIPATH_XGXS_RESET; | ||
1841 | prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ | ||
1842 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
1843 | dd->ipath_control & ~INFINIPATH_C_LINKENABLE); | ||
1844 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); | ||
1845 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); | ||
1846 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); | ||
1847 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
1848 | dd->ipath_control); | ||
1849 | } | ||
1850 | |||
1851 | |||
1852 | static int ipath_ht_get_ib_cfg(struct ipath_devdata *dd, int which) | ||
1853 | { | ||
1854 | int ret; | ||
1855 | |||
1856 | switch (which) { | ||
1857 | case IPATH_IB_CFG_LWID: | ||
1858 | ret = dd->ipath_link_width_active; | ||
1859 | break; | ||
1860 | case IPATH_IB_CFG_SPD: | ||
1861 | ret = dd->ipath_link_speed_active; | ||
1862 | break; | ||
1863 | case IPATH_IB_CFG_LWID_ENB: | ||
1864 | ret = dd->ipath_link_width_enabled; | ||
1865 | break; | ||
1866 | case IPATH_IB_CFG_SPD_ENB: | ||
1867 | ret = dd->ipath_link_speed_enabled; | ||
1868 | break; | ||
1869 | default: | ||
1870 | ret = -ENOTSUPP; | ||
1871 | break; | ||
1872 | } | ||
1873 | return ret; | ||
1874 | } | ||
1875 | |||
1876 | |||
1877 | /* we assume range checking is already done, if needed */ | ||
1878 | static int ipath_ht_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) | ||
1879 | { | ||
1880 | int ret = 0; | ||
1881 | |||
1882 | if (which == IPATH_IB_CFG_LWID_ENB) | ||
1883 | dd->ipath_link_width_enabled = val; | ||
1884 | else if (which == IPATH_IB_CFG_SPD_ENB) | ||
1885 | dd->ipath_link_speed_enabled = val; | ||
1886 | else | ||
1887 | ret = -ENOTSUPP; | ||
1888 | return ret; | ||
1889 | } | ||
1890 | |||
1891 | |||
1892 | static void ipath_ht_config_jint(struct ipath_devdata *dd, u16 a, u16 b) | ||
1893 | { | ||
1894 | } | ||
1895 | |||
1896 | |||
1897 | static int ipath_ht_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | ||
1898 | { | ||
1899 | ipath_setup_ht_setextled(dd, ipath_ib_linkstate(dd, ibcs), | ||
1900 | ipath_ib_linktrstate(dd, ibcs)); | ||
1901 | return 0; | ||
1902 | } | ||
1903 | |||
1904 | |||
1760 | /** | 1905 | /** |
1761 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers | 1906 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers |
1762 | * @dd: the infinipath device | 1907 | * @dd: the infinipath device |
@@ -1781,24 +1926,19 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd) | |||
1781 | dd->ipath_f_setextled = ipath_setup_ht_setextled; | 1926 | dd->ipath_f_setextled = ipath_setup_ht_setextled; |
1782 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; | 1927 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; |
1783 | dd->ipath_f_free_irq = ipath_ht_free_irq; | 1928 | dd->ipath_f_free_irq = ipath_ht_free_irq; |
1929 | dd->ipath_f_tidtemplate = ipath_ht_tidtemplate; | ||
1930 | dd->ipath_f_intr_fallback = ipath_ht_nointr_fallback; | ||
1931 | dd->ipath_f_get_msgheader = ipath_ht_get_msgheader; | ||
1784 | dd->ipath_f_config_ports = ipath_ht_config_ports; | 1932 | dd->ipath_f_config_ports = ipath_ht_config_ports; |
1785 | dd->ipath_f_read_counters = ipath_ht_read_counters; | 1933 | dd->ipath_f_read_counters = ipath_ht_read_counters; |
1934 | dd->ipath_f_xgxs_reset = ipath_ht_xgxs_reset; | ||
1935 | dd->ipath_f_get_ib_cfg = ipath_ht_get_ib_cfg; | ||
1936 | dd->ipath_f_set_ib_cfg = ipath_ht_set_ib_cfg; | ||
1937 | dd->ipath_f_config_jint = ipath_ht_config_jint; | ||
1938 | dd->ipath_f_ib_updown = ipath_ht_ib_updown; | ||
1786 | 1939 | ||
1787 | /* | 1940 | /* |
1788 | * initialize chip-specific variables | 1941 | * initialize chip-specific variables |
1789 | */ | 1942 | */ |
1790 | dd->ipath_f_tidtemplate = ipath_ht_tidtemplate; | ||
1791 | |||
1792 | /* | ||
1793 | * setup the register offsets, since they are different for each | ||
1794 | * chip | ||
1795 | */ | ||
1796 | dd->ipath_kregs = &ipath_ht_kregs; | ||
1797 | dd->ipath_cregs = &ipath_ht_cregs; | ||
1798 | |||
1799 | /* | ||
1800 | * do very early init that is needed before ipath_f_bus is | ||
1801 | * called | ||
1802 | */ | ||
1803 | ipath_init_ht_variables(dd); | 1943 | ipath_init_ht_variables(dd); |
1804 | } | 1944 | } |