Ejemplo n.º 1
0
int _unipro_reset_cport(unsigned int cportid)
{
    int rc;
    int retval = 0;
    uint32_t tx_reset_offset;
    uint32_t rx_reset_offset;
    uint32_t tx_queue_empty_offset;
    unsigned tx_queue_empty_bit;

    if (cportid >= cport_count) {
        return -EINVAL;
    }

    tx_queue_empty_offset = CPB_TXQUEUEEMPTY_0 + ((cportid / 32) << 2);
    tx_queue_empty_bit = (1 << (cportid % 32));

    while (!(getreg32(AIO_UNIPRO_BASE + tx_queue_empty_offset) &
                tx_queue_empty_bit)) {
    }

    tx_reset_offset = TX_SW_RESET_00 + (cportid << 2);
    rx_reset_offset = RX_SW_RESET_00 + (cportid << 2);

    putreg32(CPORT_SW_RESET_BITS, AIO_UNIPRO_BASE + tx_reset_offset);

    rc = unipro_attr_local_write(T_CONNECTIONSTATE, 0, cportid);
    if (rc) {
        lowsyslog("error resetting T_CONNECTIONSTATE (%d)\n", rc);
        retval = -EIO;
    }

    rc = unipro_attr_local_write(T_LOCALBUFFERSPACE, 0, cportid);
    if (rc) {
        lowsyslog("error resetting T_LOCALBUFFERSPACE (%d)\n", rc);
        retval = -EIO;
    }

    rc = unipro_attr_local_write(T_PEERBUFFERSPACE, 0, cportid);
    if (rc) {
        lowsyslog("error resetting T_PEERBUFFERSPACE (%d)\n", rc);
        retval = -EIO;
    }

    rc = unipro_attr_local_write(T_CREDITSTOSEND, 0, cportid);
    if (rc) {
        lowsyslog("error resetting T_CREDITSTOSEND (%d)\n", rc);
        retval = -EIO;
    }

    putreg32(CPORT_SW_RESET_BITS, AIO_UNIPRO_BASE + rx_reset_offset);
    putreg32(0, AIO_UNIPRO_BASE + tx_reset_offset);
    putreg32(0, AIO_UNIPRO_BASE + rx_reset_offset);

    return retval;
}
Ejemplo n.º 2
0
static int es3_tsb_unipro_set_init_status(uint32_t val)
{
    int retval;
    uint32_t status;

    /*
     * See SW-1228
     *  -> https://projectara.atlassian.net/browse/SW-1228?focusedCommentId=28889&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-28889
     */
    if (val & INIT_STATUS_ERROR_CODE_MASK) {
        lowsyslog("%s() cannot override the init status error code (init status: %u).\n",
                  __func__, val);
        return -EINVAL;
    }

    retval = unipro_attr_local_read(TSB_DME_ES3_INIT_STATUS, &status,
                                    UNIPRO_SELINDEX_NULL);
    if (retval) {
        lowsyslog("init-status read failed: retval = %d\n", retval);
        return retval;
    }

    /* preserve error code: see SW-1228 */
    val |= status & INIT_STATUS_ERROR_CODE_MASK;

    retval = unipro_attr_local_write(TSB_DME_ES3_INIT_STATUS, val,
                                     UNIPRO_SELINDEX_NULL);
    if (retval) {
        lowsyslog("init-status write failed: retval = %d\n", retval);
        return retval;
    }

    return 0;
}
Ejemplo n.º 3
0
static enum svc_state svc_wf_unipro__link_up(struct svc *svc, struct svc_work *work) {
    vdbg("\n");

    /* Unipro link is up. Starting "unipro_init" stuff now */
    unipro_init_with_event_handler(unipro_evt_handler);
    unipro_p2p_detect_linkloss(true);
    tsb_unipro_set_init_status(INIT_STATUS_OPERATING);
    unipro_attr_local_write(TSB_DME_ES3_SYSTEM_STATUS_14, CONFIG_VERSION, 0);
    return SVC_WAIT_FOR_MOD;
}
Ejemplo n.º 4
0
void gb_control_register(int cport, int bundle)
{
    gb_register_driver(cport, bundle, &control_driver);
    unipro_attr_local_write(T_CPORTFLAGS,
            CPORT_FLAGS_CSV_N |
            CPORT_FLAGS_CSD_N |
            CPORT_FLAGS_E2EFC, cport);
    unipro_enable_fct_tx_flow(cport);
    gb_listen(cport);
}
Ejemplo n.º 5
0
/**
 * Since the switch has no 32-bit MBOX_ACK_ATTR attribute, we need to repurpose
 * a 16-bit attribute, which means that received mbox values must fit inside a
 * uint16_t.
 */
static int tsb_unipro_mbox_ack(uint16_t val) {
    int rc;
    uint32_t mbox_ack_attr = tsb_get_rev_id() == tsb_rev_es2 ?
                             ES2_MBOX_ACK_ATTR : ES3_MBOX_ACK_ATTR;

    rc = unipro_attr_local_write(mbox_ack_attr, val, 0);
    if (rc) {
        lldbg("MBOX_ACK_ATTR complement write of 0x%x failed: %d\n", val, rc);
        return rc;
    }

    return 0;
}
Ejemplo n.º 6
0
static int es2_tsb_unipro_set_init_status(uint32_t val)
{
    int rc;

    rc = unipro_attr_local_write(T_TSTSRCINCREMENT, ES2_INIT_STATUS(val),
                                 UNIPRO_SELINDEX_NULL);
    if (rc) {
        lldbg("init-status write failed: rc=%d\n", rc);
        return rc;
    }

    return 0;
}
Ejemplo n.º 7
0
static int unipro_enable_mailbox_irq(void)
{
    int retval;
    uint32_t val;

    retval = unipro_attr_local_read(TSB_INTERRUPTENABLE, &val,
                                    UNIPRO_SELINDEX_NULL);
    if (retval) {
        return retval;
    }

    return unipro_attr_local_write(TSB_INTERRUPTENABLE,
                                   val | TSB_INTERRUPTSTATUS_MAILBOX,
                                   UNIPRO_SELINDEX_NULL);
}
Ejemplo n.º 8
0
static enum svc_state svc_wf_slave_unipro__link_up(struct svc *svc, struct svc_work *work) {
    vdbg("\n");

    unipro_p2p_detect_linkloss(true);
    tsb_unipro_set_init_status(INIT_STATUS_OPERATING);
    unipro_attr_local_write(TSB_DME_ES3_SYSTEM_STATUS_14, CONFIG_VERSION, 0);
    tsb_unipro_mbox_send(TSB_MAIL_READY_OTHER);

    if (g_svc.gearbox) {
        gearbox_link_up(g_svc.gearbox);
    }

#if CONFIG_MHB_IPC_SERVER || CONFIG_MHB_IPC_CLIENT
    ipc_register_unipro();
#endif
#if defined(CONFIG_ARCH_CHIP_TSB_I2S_TUNNEL)
    (void)i2s_unipro_tunnel_unipro_register();
#endif

    return SVC_SLAVE_WAIT_FOR_CPORTS;
}
Ejemplo n.º 9
0
static int es2_fixup_mphy(void)
{
    uint32_t debug_0720 = tsb_get_debug_reg(0x0720);
    uint32_t urc;
    const struct tsb_mphy_fixup *fu;

    /*
     * Apply the "register 2" map fixups.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_TSB_REGISTER_2, 0,
                            &urc);
    if (urc) {
        lldbg("%s: failed to switch to register 2 map: %u\n",
              __func__, urc);
        return urc;
    }
    fu = tsb_register_2_map_mphy_fixups;
    do {
        unipro_attr_local_write(fu->attrid, fu->value, fu->select_index,
                                &urc);
        if (urc) {
            lldbg("%s: failed to apply register 1 map fixup: %u\n",
                  __func__, urc);
            return urc;
        }
    } while (!tsb_mphy_fixup_is_last(fu++));

    /*
     * Switch to "normal" map.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_NORMAL, 0,
                            &urc);
    if (urc) {
        lldbg("%s: failed to switch to normal map: %u\n",
              __func__, urc);
        return urc;
    }

    /*
     * Apply the "register 1" map fixups.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_TSB_REGISTER_1, 0,
                            &urc);
    if (urc) {
        lldbg("%s: failed to switch to register 1 map: %u\n",
              __func__, urc);
        return urc;
    }
    fu = tsb_register_1_map_mphy_fixups;
    do {
        if (tsb_mphy_r1_fixup_is_magic(fu)) {
            /* The magic R1 fixups come from the mysterious and solemn
             * debug register 0x0720. */
            unipro_attr_local_write(0x8002, (debug_0720 >> 1) & 0x1f, 0, &urc);
        } else {
            unipro_attr_local_write(fu->attrid, fu->value, fu->select_index,
                                    &urc);
        }
        if (urc) {
            lldbg("%s: failed to apply register 1 map fixup: %u\n",
                  __func__, urc);
            return urc;
        }
    } while (!tsb_mphy_fixup_is_last(fu++));