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_iba6120.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_iba6120.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6120.c | 163 |
1 files changed, 154 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 57915fd718e2..597192e912de 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -329,6 +329,9 @@ static const struct ipath_cregs ipath_pe_cregs = { | |||
329 | #define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL | 329 | #define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL |
330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL | 330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL |
331 | 331 | ||
332 | #define IBA6120_IBCS_LINKTRAININGSTATE_MASK 0xf | ||
333 | #define IBA6120_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 |
@@ -936,12 +939,27 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, | |||
936 | else | 939 | else |
937 | ipath_dev_err(dd, "Can't find PCI Express " | 940 | ipath_dev_err(dd, "Can't find PCI Express " |
938 | "capability!\n"); | 941 | "capability!\n"); |
942 | |||
943 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; | ||
944 | dd->ipath_link_speed_supported = IPATH_IB_SDR; | ||
945 | dd->ipath_link_width_enabled = IB_WIDTH_4X; | ||
946 | dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; | ||
947 | /* these can't change for this chip, so set once */ | ||
948 | dd->ipath_link_width_active = dd->ipath_link_width_enabled; | ||
949 | dd->ipath_link_speed_active = dd->ipath_link_speed_enabled; | ||
939 | return 0; | 950 | return 0; |
940 | } | 951 | } |
941 | 952 | ||
942 | static void ipath_init_pe_variables(struct ipath_devdata *dd) | 953 | static void ipath_init_pe_variables(struct ipath_devdata *dd) |
943 | { | 954 | { |
944 | /* | 955 | /* |
956 | * setup the register offsets, since they are different for each | ||
957 | * chip | ||
958 | */ | ||
959 | dd->ipath_kregs = &ipath_pe_kregs; | ||
960 | dd->ipath_cregs = &ipath_pe_cregs; | ||
961 | |||
962 | /* | ||
945 | * bits for selecting i2c direction and values, | 963 | * bits for selecting i2c direction and values, |
946 | * used for I2C serial flash | 964 | * used for I2C serial flash |
947 | */ | 965 | */ |
@@ -950,6 +968,37 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
950 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; | 968 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; |
951 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; | 969 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; |
952 | 970 | ||
971 | /* | ||
972 | * Fill in data for field-values that change in newer chips. | ||
973 | * We dynamically specify only the mask for LINKTRAININGSTATE | ||
974 | * and only the shift for LINKSTATE, as they are the only ones | ||
975 | * that change. Also precalculate the 3 link states of interest | ||
976 | * and the combined mask. | ||
977 | */ | ||
978 | dd->ibcs_ls_shift = IBA6120_IBCS_LINKSTATE_SHIFT; | ||
979 | dd->ibcs_lts_mask = IBA6120_IBCS_LINKTRAININGSTATE_MASK; | ||
980 | dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << | ||
981 | dd->ibcs_ls_shift) | dd->ibcs_lts_mask; | ||
982 | dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
983 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
984 | (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); | ||
985 | dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
986 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
987 | (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); | ||
988 | dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
989 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
990 | (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); | ||
991 | |||
992 | /* | ||
993 | * Fill in data for ibcc field-values that change in newer chips. | ||
994 | * We dynamically specify only the mask for LINKINITCMD | ||
995 | * and only the shift for LINKCMD and MAXPKTLEN, as they are | ||
996 | * the only ones that change. | ||
997 | */ | ||
998 | dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK; | ||
999 | dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT; | ||
1000 | dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
1001 | |||
953 | /* Fill in shifts for RcvCtrl. */ | 1002 | /* Fill in shifts for RcvCtrl. */ |
954 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; | 1003 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; |
955 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; | 1004 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; |
@@ -1003,6 +1052,8 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
1003 | 1052 | ||
1004 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | 1053 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; |
1005 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | 1054 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; |
1055 | dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; | ||
1056 | dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; | ||
1006 | 1057 | ||
1007 | /* | 1058 | /* |
1008 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. | 1059 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. |
@@ -1024,6 +1075,7 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
1024 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; | 1075 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; |
1025 | 1076 | ||
1026 | 1077 | ||
1078 | dd->delay_mult = 2; /* SDR, 4X, can't change */ | ||
1027 | } | 1079 | } |
1028 | 1080 | ||
1029 | /* setup the MSI stuff again after a reset. I'd like to just call | 1081 | /* setup the MSI stuff again after a reset. I'd like to just call |
@@ -1329,6 +1381,9 @@ static int ipath_pe_early_init(struct ipath_devdata *dd) | |||
1329 | */ | 1381 | */ |
1330 | dd->ipath_rcvhdrentsize = 24; | 1382 | dd->ipath_rcvhdrentsize = 24; |
1331 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; | 1383 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; |
1384 | dd->ipath_rhf_offset = 0; | ||
1385 | dd->ipath_egrtidbase = (u64 __iomem *) | ||
1386 | ((char __iomem *) dd->ipath_kregbase + dd->ipath_rcvegrbase); | ||
1332 | 1387 | ||
1333 | /* | 1388 | /* |
1334 | * To truly support a 4KB MTU (for usermode), we need to | 1389 | * To truly support a 4KB MTU (for usermode), we need to |
@@ -1399,6 +1454,14 @@ static void ipath_pe_free_irq(struct ipath_devdata *dd) | |||
1399 | dd->ipath_irq = 0; | 1454 | dd->ipath_irq = 0; |
1400 | } | 1455 | } |
1401 | 1456 | ||
1457 | |||
1458 | static struct ipath_message_header * | ||
1459 | ipath_pe_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) | ||
1460 | { | ||
1461 | return (struct ipath_message_header *) | ||
1462 | &rhf_addr[sizeof(u64) / sizeof(u32)]; | ||
1463 | } | ||
1464 | |||
1402 | static void ipath_pe_config_ports(struct ipath_devdata *dd, ushort cfgports) | 1465 | static void ipath_pe_config_ports(struct ipath_devdata *dd, ushort cfgports) |
1403 | { | 1466 | { |
1404 | dd->ipath_portcnt = | 1467 | dd->ipath_portcnt = |
@@ -1534,6 +1597,88 @@ static int ipath_pe_txe_recover(struct ipath_devdata *dd) | |||
1534 | return 1; | 1597 | return 1; |
1535 | } | 1598 | } |
1536 | 1599 | ||
1600 | /* no interrupt fallback for these chips */ | ||
1601 | static int ipath_pe_nointr_fallback(struct ipath_devdata *dd) | ||
1602 | { | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | |||
1607 | /* | ||
1608 | * reset the XGXS (between serdes and IBC). Slightly less intrusive | ||
1609 | * than resetting the IBC or external link state, and useful in some | ||
1610 | * cases to cause some retraining. To do this right, we reset IBC | ||
1611 | * as well. | ||
1612 | */ | ||
1613 | static void ipath_pe_xgxs_reset(struct ipath_devdata *dd) | ||
1614 | { | ||
1615 | u64 val, prev_val; | ||
1616 | |||
1617 | prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | ||
1618 | val = prev_val | INFINIPATH_XGXS_RESET; | ||
1619 | prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ | ||
1620 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
1621 | dd->ipath_control & ~INFINIPATH_C_LINKENABLE); | ||
1622 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); | ||
1623 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); | ||
1624 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); | ||
1625 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
1626 | dd->ipath_control); | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | static int ipath_pe_get_ib_cfg(struct ipath_devdata *dd, int which) | ||
1631 | { | ||
1632 | int ret; | ||
1633 | |||
1634 | switch (which) { | ||
1635 | case IPATH_IB_CFG_LWID: | ||
1636 | ret = dd->ipath_link_width_active; | ||
1637 | break; | ||
1638 | case IPATH_IB_CFG_SPD: | ||
1639 | ret = dd->ipath_link_speed_active; | ||
1640 | break; | ||
1641 | case IPATH_IB_CFG_LWID_ENB: | ||
1642 | ret = dd->ipath_link_width_enabled; | ||
1643 | break; | ||
1644 | case IPATH_IB_CFG_SPD_ENB: | ||
1645 | ret = dd->ipath_link_speed_enabled; | ||
1646 | break; | ||
1647 | default: | ||
1648 | ret = -ENOTSUPP; | ||
1649 | break; | ||
1650 | } | ||
1651 | return ret; | ||
1652 | } | ||
1653 | |||
1654 | |||
1655 | /* we assume range checking is already done, if needed */ | ||
1656 | static int ipath_pe_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) | ||
1657 | { | ||
1658 | int ret = 0; | ||
1659 | |||
1660 | if (which == IPATH_IB_CFG_LWID_ENB) | ||
1661 | dd->ipath_link_width_enabled = val; | ||
1662 | else if (which == IPATH_IB_CFG_SPD_ENB) | ||
1663 | dd->ipath_link_speed_enabled = val; | ||
1664 | else | ||
1665 | ret = -ENOTSUPP; | ||
1666 | return ret; | ||
1667 | } | ||
1668 | |||
1669 | static void ipath_pe_config_jint(struct ipath_devdata *dd, u16 a, u16 b) | ||
1670 | { | ||
1671 | } | ||
1672 | |||
1673 | |||
1674 | static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | ||
1675 | { | ||
1676 | ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs), | ||
1677 | ipath_ib_linktrstate(dd, ibcs)); | ||
1678 | return 0; | ||
1679 | } | ||
1680 | |||
1681 | |||
1537 | /** | 1682 | /** |
1538 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers | 1683 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers |
1539 | * @dd: the infinipath device | 1684 | * @dd: the infinipath device |
@@ -1554,7 +1699,7 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) | |||
1554 | dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; | 1699 | dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; |
1555 | dd->ipath_f_clear_tids = ipath_pe_clear_tids; | 1700 | dd->ipath_f_clear_tids = ipath_pe_clear_tids; |
1556 | /* | 1701 | /* |
1557 | * this may get changed after we read the chip revision, | 1702 | * _f_put_tid may get changed after we read the chip revision, |
1558 | * but we start with the safe version for all revs | 1703 | * but we start with the safe version for all revs |
1559 | */ | 1704 | */ |
1560 | dd->ipath_f_put_tid = ipath_pe_put_tid; | 1705 | dd->ipath_f_put_tid = ipath_pe_put_tid; |
@@ -1562,19 +1707,19 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) | |||
1562 | dd->ipath_f_setextled = ipath_setup_pe_setextled; | 1707 | dd->ipath_f_setextled = ipath_setup_pe_setextled; |
1563 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; | 1708 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; |
1564 | dd->ipath_f_free_irq = ipath_pe_free_irq; | 1709 | dd->ipath_f_free_irq = ipath_pe_free_irq; |
1565 | |||
1566 | /* initialize chip-specific variables */ | ||
1567 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; | 1710 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; |
1711 | dd->ipath_f_intr_fallback = ipath_pe_nointr_fallback; | ||
1712 | dd->ipath_f_xgxs_reset = ipath_pe_xgxs_reset; | ||
1713 | dd->ipath_f_get_msgheader = ipath_pe_get_msgheader; | ||
1568 | dd->ipath_f_config_ports = ipath_pe_config_ports; | 1714 | dd->ipath_f_config_ports = ipath_pe_config_ports; |
1569 | dd->ipath_f_read_counters = ipath_pe_read_counters; | 1715 | dd->ipath_f_read_counters = ipath_pe_read_counters; |
1716 | dd->ipath_f_get_ib_cfg = ipath_pe_get_ib_cfg; | ||
1717 | dd->ipath_f_set_ib_cfg = ipath_pe_set_ib_cfg; | ||
1718 | dd->ipath_f_config_jint = ipath_pe_config_jint; | ||
1719 | dd->ipath_f_ib_updown = ipath_pe_ib_updown; | ||
1570 | 1720 | ||
1571 | /* | ||
1572 | * setup the register offsets, since they are different for each | ||
1573 | * chip | ||
1574 | */ | ||
1575 | dd->ipath_kregs = &ipath_pe_kregs; | ||
1576 | dd->ipath_cregs = &ipath_pe_cregs; | ||
1577 | 1721 | ||
1722 | /* initialize chip-specific variables */ | ||
1578 | ipath_init_pe_variables(dd); | 1723 | ipath_init_pe_variables(dd); |
1579 | } | 1724 | } |
1580 | 1725 | ||