Example #1
0
void
TkAlarmRxThread(void *cookie)
{
    int16           MsgLen = 0;
    TkMsgBuff      *pMsgBuf ;
    uint32          pathId = PTR_TO_INT(cookie);

    pMsgBuf = (TkMsgBuff *) TkOamMemGet(pathId);

    while (1) {
        if ((MsgLen =
             sal_msg_rcv(gTagLinkCfg[pathId].almMsgQid,
                         (char *) pMsgBuf,
                         TK_MAX_RX_TX_DATA_LENGTH, WAIT_FOREVER)) < 0) {
            sal_usleep(1);
            continue;
        } else {
            if (TkDbgLevelIsSet(TkDbgMsgEnable | TkDbgAlmEnable)) {
                TkDbgPrintf(("\r\nAlmTask received a msg\n"));
                TkDbgDataDump((uint8 *) pMsgBuf, MsgLen, 16);
            }
            if (ieeeAlmProcessFn)
                ieeeAlmProcessFn(pathId, pMsgBuf->buff, MsgLen);
        }
        sal_usleep(1);
    }
    TkOamMemPut(pathId,(void *) pMsgBuf);
}
Example #2
0
/*ARGSUSED*/
static void
led_beat(void *p)
{
    uint32 period = (1000000 / 3);

    for (;;) {
        sysLedOn(); 
        sal_usleep(period);
        sysLedOff();
        sal_usleep(period);
    }
}
Example #3
0
STATIC int
phy_5690_init(int unit, soc_port_t port)
{
    uint16		ctrl;
    phy_ctrl_t         *pc;

    pc       = INT_PHY_SW_STATE(unit, port);
    LOG_INFO(BSL_LS_SOC_PHY,
             (BSL_META_U(unit,
                         "phy_5690_init: u=%d p=%d\n"),
              unit, port));

    if (soc_feature(unit, soc_feature_phy_5690_link_war)) {
	PHY_5690_AN_VALID_RESET(pc);
    }

    /*
     * The internal SERDES PHY's reset bit must be held high for at
     * least 1 usec and is not self-clearing.
     */

    SOC_IF_ERROR_RETURN
	(READ_PHY_REG(unit, pc,
		       QS_MII_CTRL_REG, &ctrl));

    ctrl |= QS_MII_CTRL_RESET;

    SOC_IF_ERROR_RETURN
	(WRITE_PHY_REG(unit, pc, QS_MII_CTRL_REG, ctrl));

    sal_usleep(1);

    ctrl = QS_MII_CTRL_SS_1000 | QS_MII_CTRL_FD;

    SOC_IF_ERROR_RETURN
	(WRITE_PHY_REG(unit, pc, QS_MII_CTRL_REG, ctrl));

    sal_usleep(10000);

    SOC_IF_ERROR_RETURN
	(READ_PHY_REG(unit, pc, QS_SGMII_CTRL_REG, &ctrl));
    ctrl &= ~QS_SGMII_TBI_LOOP;
    SOC_IF_ERROR_RETURN
        (WRITE_PHY_REG(unit, pc, QS_SGMII_CTRL_REG, ctrl));
    
    SOC_IF_ERROR_RETURN
	(WRITE_PHY_REG(unit, pc, QS_SGMII_CTRL2_REG, 
                      (PHY_COPPER_MODE(unit, port) ? 0 : QS_SGMII_FIBER_MODE)));

    return SOC_E_NONE;
}
Example #4
0
File: util.c Project: ariavie/bcm
int
soc_timeout_check(soc_timeout_t *to)
{
    if (++to->polls >= to->min_polls) {
	if (to->min_polls >= 0) {
	    /*
	     * Just exceeded min_polls; calculate expiration time by
	     * consulting O/S real time clock.
	     */

	    to->min_polls = -1;
	    to->expire = SAL_USECS_ADD(sal_time_usecs(), to->usec);
	    to->exp_delay = 1;
	} else {
	    /*
	     * Exceeded min_polls in a previous call.
	     * Consult O/S real time clock to check for expiration.
	     */

	    if (SAL_USECS_SUB(sal_time_usecs(), to->expire) >= 0) {
		return 1;
	    }

	    sal_usleep(to->exp_delay);

	    /* Exponential backoff with 10% maximum latency */

	    if ((to->exp_delay *= 2) > to->usec / 10) {
		to->exp_delay = to->usec / 10;
	    }
	}
    }

    return 0;
}
Example #5
0
File: ipoll.c Project: ariavie/bcm
/*
 * Function:
 *      soc_ipoll_thread
 * Description:
 *      Thread context for interrupt handlers in polled IRQ mode
 * Parameters:
 *      data - poll delay in usecs (passed as pointer)
 * Returns:
 *      Nothing
 */
STATIC void
soc_ipoll_thread(void *data)
{
    int dev, spl, udelay;

    udelay = PTR_TO_INT(data);

    while (_ihandlers) {

        spl = sal_splhi();

        for (dev = 0; dev < SOC_MAX_NUM_DEVICES; dev++) {
            if (_ictrl[dev].handler != NULL && !_ictrl[dev].paused) {
                if (soc_feature(dev, soc_feature_cmicm)) {
                    soc_cmicm_ipoll_handler(dev);
                } else {
                    soc_cmic_ipoll_handler(dev);
                }
            }
        }

        sal_spl(spl);

        if (udelay) {
            sal_usleep(udelay);
        } else {
            sal_thread_yield();
        }
    }
    sal_thread_exit(0);
}
Example #6
0
int
sal_sem_take(sal_sem_t b, int usec)
{
    sem_ctrl_t *s = (sem_ctrl_t *) b;
    int			err;

    if (usec == sal_sem_FOREVER && !in_interrupt()) {
	err = down_interruptible(&s->sem);
    } else {
	int		time_wait = 1;
        int             cnt = s->cnt;

	for (;;) {
	    if (down_trylock(&s->sem) == 0) {
		err = 0;
		break;
	    }

            if (s->binary) {

                /* Wait for event or timeout */

                if (time_wait > 1) {
                    err = 1;
                    break;
                }
                err = wait_event_interruptible_timeout(s->wq, cnt != s->cnt, 
                                                       USEC_TO_JIFFIES(usec));
                if (err < 0) {
                    break;
                }
                time_wait++;

            } else {

                /* Retry algorithm with exponential backoff */

                if (time_wait > usec) {
                    time_wait = usec;
                }

                sal_usleep(time_wait);
                
                usec -= time_wait;
            
                if (usec == 0) {
                    err = ETIMEDOUT;
                    break;
                }

                if ((time_wait *= 2) > 100000) {
                    time_wait = 100000;
                }
	    }
	}
    }
    return err ? -1 : 0;
}
Example #7
0
/*ARGSUSED*/
static void
led_string(void *p)
{
    uint32 period = (1000000 / 3);
    int blue_led = 0;

    for (;;) {
	sal_led_string("BCM\\");
	sal_usleep(period / 4);
	sal_led_string("BCM|");
	sal_usleep(period / 4);
	sal_led_string("BCM/");
	sal_usleep(period / 4);
	sal_led_string("BCM-");
	sal_usleep(period / 4);
        sal_led(blue_led);
        blue_led = !blue_led;
    }
}
Example #8
0
File: mbox.c Project: ariavie/bcm
STATIC
void
_bcm_mbox_rx_thread(void *arg)
{
    int rv = 0;

    int unit = PTR_TO_INT(arg);

    while (1) {
        int mbox;


        /* The uc_msg is just a signal that there is a message somewhere to get, so look through all mboxes */

        sal_usleep(10000);  


        for (mbox = 0; mbox < _BCM_MBOX_MAX_BUFFERS; ++mbox) {

            switch (mbox_info.unit_state[unit].mboxes->status[mbox]) {
            case _BCM_MBOX_MS_TUNNEL_IN:
                break;

            case _BCM_MBOX_MS_EVENT:
                break;

            case _BCM_MBOX_MS_RESP:
                {

                    mbox_info.unit_state[unit].response_data = (uint8*)mbox_info.unit_state[unit].mboxes->mbox[mbox].data;
                    mbox_info.unit_state[unit].response_len  = mbox_info.unit_state[unit].mboxes->mbox[mbox].data_len;

                    rv = sal_sem_give(mbox_info.unit_state[unit].response_ready);
                    if (BCM_FAILURE(rv)) {
                        _MBOX_ERROR_FUNC("_bcm_ptp_sem_give()");
                    }

                    
                    mbox_info.unit_state[unit].mboxes->status[mbox] = _BCM_MBOX_MS_EMPTY;
                }
                break;
            }
        }
    }
}
Example #9
0
File: pae.c Project: ariavie/bcm
int 
soc_pae_send_msg(int unit, pae_msg_type msg_type, uint32 addr, uint32 len, void * buf)
{
    uint32 r5_len,r5_msg_type,r5_addr;
    pae_response_code res_code=PAE_RES_FAILURE;
    uint32 loop_i;

    if(!SOC_IS_NORTHSTARPLUS(unit)){
        return SOC_E_UNAVAIL;
    }

    soc_pae_set_cmd_response(unit, PAE_RES_INVALID);
    r5_len=pae_host_to_r5_32(len);
    r5_msg_type=pae_host_to_r5_32(msg_type);
    r5_addr=pae_host_to_r5_32(addr);

    switch(msg_type){
        case PAE_WRITE_BUF:
            _pae_byte_copy(PAE_SHARED_BUF,buf, len);
        break;

        default:
        return SOC_E_PARAM;
    }

    PAE_HAL_WRITE_32(PAE_SHARED_ACC_LEN,r5_len);
    PAE_HAL_WRITE_32(PAE_SHARED_ACC_ADDR,r5_addr);	
    PAE_HAL_WRITE_32(PAE_SHARED_MSG_TYPE,r5_msg_type);

    for(loop_i=0;loop_i<PAE_RES_WAIT_MS;loop_i++){
        sal_usleep(1000);
        res_code=soc_pae_get_cmd_response(unit);
        if(res_code==PAE_RES_OK)
        break;
    }
    
    if(res_code==PAE_RES_OK)
        return SOC_E_NONE;
    else
        return SOC_E_FAIL;
}
Example #10
0
/*
 * Function: max664x_thread
 *
 * Purpose: Poll MAX664X devices and report stats every poll_delay seconds
 *
 * Parameters:
 *    unitp	- void * version of unit
 */
STATIC void
max664x_thread(void *unitp)
{
    int			unit, dev, ndev;
    max664x_dev_info_t	*maxinfo;
    
    unit = PTR_TO_INT(unitp);
    maxinfo = max664x_info[unit];
    
    while (maxinfo && maxinfo->sleep) {
        ndev = soc_i2c_device_count(unit);
        for (dev = 0; dev < ndev; dev++) {
            if (soc_i2c_devtype(unit, dev) == MAX664X_DEVICE_TYPE) {
                max664x_temp_show(unit, dev, FALSE);
            }
        }
        sal_usleep(maxinfo->sleep * SECOND_USEC);
    }
    LOG_CLI((BSL_META_U(unit,
                        "unit %d: thermal monitoring completed\n"), unit));
    sal_thread_exit(0);
}
Example #11
0
File: mbox.c Project: ariavie/bcm
int
_bcm_mbox_tx_completion(
    int unit,
    uint32 node_num)
{
#if defined(BCM_CMICM_SUPPORT)
    int iter;

    for (iter = 0; iter < 10000; ++iter) {
        if (mbox_info.unit_state[unit].mboxes->status[0] == _BCM_MBOX_MS_EMPTY) {
            /* sal_strcpy(holding_thread_name, "none"); */
            return BCM_E_NONE;
        }
        sal_usleep(1);
    }

    /* sal_strcpy(holding_thread_name + strlen(holding_thread_name), "-over"); */
    SOC_DEBUG_PRINT((DK_ERR | DK_VERBOSE, "Failed async Tx to ToP.  No clear\n"));
    return BCM_E_TIMEOUT;
#else  /* BCM_CMICM_SUPPORT */
    return BCM_E_UNAVAIL;
#endif /* BCM_CMICM_SUPPORT */
}
Example #12
0
/*
 * Function: _ioctl
 *
 * Purpose:
 *    Handle IOCTL commands from user mode.
 * Parameters:
 *    cmd - IOCTL cmd
 *    arg - IOCTL parameters
 * Returns:
 *    0 on success, <0 on error
 */
static int 
_ioctl(unsigned int cmd, unsigned long arg)
{
    lubde_ioctl_t io;
    uint32 pbase, size;
    const ibde_dev_t *bde_dev;
    int inst_id;
     bde_inst_resource_t *res;

    if (copy_from_user(&io, (void *)arg, sizeof(io))) {
        return -EFAULT;
    }
  
    io.rc = LUBDE_SUCCESS;
  
    switch(cmd) {
    case LUBDE_VERSION:
        io.d0 = 0;
        break;
    case LUBDE_GET_NUM_DEVICES:

        io.d0 = user_bde->num_devices(io.dev);
        break;
    case LUBDE_GET_DEVICE:
        bde_dev = user_bde->get_dev(io.dev);
        if (bde_dev) {
            io.d0 = bde_dev->device;
            io.d1 = bde_dev->rev;
            if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) {
                /* Get physical address to map */
                io.d2 = lkbde_get_dev_phys(io.dev);
                io.d3 = lkbde_get_dev_phys_hi(io.dev);
            }
        } else {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_GET_DEVICE_TYPE:
        io.d0 = _devices[io.dev].dev_type;
        break;
    case LUBDE_GET_BUS_FEATURES:
        user_bde->pci_bus_features(io.dev, (int *) &io.d0, (int *) &io.d1,
                                   (int *) &io.d2);
        break;
    case LUBDE_PCI_CONFIG_PUT32:
        if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) {
            user_bde->pci_conf_write(io.dev, io.d0, io.d1);
        } else {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_PCI_CONFIG_GET32:
        if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) {
            io.d0 = user_bde->pci_conf_read(io.dev, io.d0);
        } else {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_GET_DMA_INFO:
        inst_id = io.dev;
        if (_bde_multi_inst){
            _dma_resource_get(inst_id, &pbase, &size);
        } else {
            lkbde_get_dma_info(&pbase, &size);
        }
        io.d0 = pbase;
        io.d1 = size; 
        /* Optionally enable DMA mmap via /dev/linux-kernel-bde */
        io.d2 = USE_LINUX_BDE_MMAP;
        break;
    case LUBDE_ENABLE_INTERRUPTS:
        if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) {
            if (_devices[io.dev].isr && !_devices[io.dev].enabled) {
                user_bde->interrupt_connect(io.dev,
                                            _devices[io.dev].isr,
                                            _devices+io.dev);
                _devices[io.dev].enabled = 1;
            }
        } else {
            /* Process ethernet device interrupt */
            /* FIXME: for multiple chips */
            if (!_devices[io.dev].enabled) {
                user_bde->interrupt_connect(io.dev,
                                            (void(*)(void *))_ether_interrupt, 
                                            _devices+io.dev);
                _devices[io.dev].enabled = 1;
            }
        }
        break;
    case LUBDE_DISABLE_INTERRUPTS:
        if (_devices[io.dev].enabled) {
            user_bde->interrupt_disconnect(io.dev);
            _devices[io.dev].enabled = 0;
        }
        break;
    case LUBDE_WAIT_FOR_INTERRUPT:
        if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) {
            res = &_bde_inst_resource[_devices[io.dev].inst];
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
            wait_event_timeout(res->intr_wq, 
                               atomic_read(&res->intr) != 0, 100);

#else
            wait_event_interruptible(res->intr_wq,
                                     atomic_read(&res->intr) != 0);
#endif
            /* 
             * Even if we get multiple interrupts, we 
             * only run the interrupt handler once.
             */
            atomic_set(&res->intr, 0);
        } else {
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
            wait_event_timeout(_ether_interrupt_wq,     
                               atomic_read(&_ether_interrupt_has_taken_place) != 0, 100);
#else
            wait_event_interruptible(_ether_interrupt_wq,     
                                     atomic_read(&_ether_interrupt_has_taken_place) != 0);
#endif
            /* 
             * Even if we get multiple interrupts, we 
             * only run the interrupt handler once.
             */
            atomic_set(&_ether_interrupt_has_taken_place, 0);
        }
        break;
    case LUBDE_USLEEP:
        sal_usleep(io.d0);
        break;
    case LUBDE_UDELAY:
        sal_udelay(io.d0);
        break;
    case LUBDE_SEM_OP:
        switch (io.d0) {
        case LUBDE_SEM_OP_CREATE:
            io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2);
            break;
        case LUBDE_SEM_OP_DESTROY:
            sal_sem_destroy((sal_sem_t)io.p0);
            break;
        case LUBDE_SEM_OP_TAKE:
            io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2);
            break;
        case LUBDE_SEM_OP_GIVE:
            io.rc = sal_sem_give((sal_sem_t)io.p0);
            break;
        default:
            io.rc = LUBDE_FAIL;
            break;
        }
        break;
    case LUBDE_WRITE_IRQ_MASK:
        io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0);
        break;
    case LUBDE_SPI_READ_REG:
        if (user_bde->spi_read(io.dev, io.d0, io.dx.buf, io.d1) == -1) {
            io.rc = LUBDE_FAIL;
        } 
        break;
    case LUBDE_SPI_WRITE_REG:
        if (user_bde->spi_write(io.dev, io.d0, io.dx.buf, io.d1) == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_READ_REG_16BIT_BUS:
        io.d1 = user_bde->read(io.dev, io.d0);
        break;
    case LUBDE_WRITE_REG_16BIT_BUS:
        io.rc = user_bde->write(io.dev, io.d0, io.d1);
        break;
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
    case LUBDE_CPU_WRITE_REG:
    {
        if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    }
    case LUBDE_CPU_READ_REG:
    {
        if (lkbde_cpu_read(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    }
    case LUBDE_CPU_PCI_REGISTER:
    {
        if (lkbde_cpu_pci_register(io.dev) == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    }
#endif
    case LUBDE_DEV_RESOURCE:
        bde_dev = user_bde->get_dev(io.dev);
        if (bde_dev) {
            if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) {
                /* Get physical address to map */
                io.rc = lkbde_get_dev_resource(io.dev, io.d0,
                                               &io.d1, &io.d2, &io.d3);
            }
        } else {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_IPROC_READ_REG:
        io.d1 = user_bde->iproc_read(io.dev, io.d0);
        if (io.d1 == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_IPROC_WRITE_REG:
        if (user_bde->iproc_write(io.dev, io.d0, io.d1) == -1) {
            io.rc = LUBDE_FAIL;
        }
        break;
    case LUBDE_ATTACH_INSTANCE:
        io.rc = _instance_attach(io.d0, io.d1);
        break;
    default:
        gprintk("Error: Invalid ioctl (%08x)\n", cmd);
        io.rc = LUBDE_FAIL;
        break;
    }
  
    if (copy_to_user((void *)arg, &io, sizeof(io))) {
        return -EFAULT;
    }

    return 0;
}
Example #13
0
File: ctrans.c Project: ariavie/bcm
/*
 * Start BCM RX and initiate packet processing
 *
 * Note:
 *   BCM RX does not start packet processing until a callback
 *   routine is registered (other than the internal discard routine).
 */
STATIC int
rx_start(void)
{
    int  i;
    int  rv = BCM_E_NONE;
    int  rx_started = 0;
    /*
     * Start BCM RX
     */
    for (i = 0; i < soc_ndev; i++) {
        if (bcm_rx_active(i)) {
            rx_started++;
            continue;
        }
        rv = bcm_rx_init(i);
        if (rv == BCM_E_UNAVAIL) {
            cli_out("WARNING: BCM RX init failed, unit %d: %s\n",
                    i, bcm_errmsg(rv));
            continue;
        } else if (BCM_FAILURE(rv)) {
            cli_out("ERROR: BCM RX init failed, unit %d: %s\n",
                    i, bcm_errmsg(rv));
            return rv;
        }

        rv = bcm_rx_start(i, NULL);
        if (BCM_FAILURE(rv)) {
            cli_out("ERROR: BCM RX start failed, unit %d: %s\n",
                    i, bcm_errmsg(rv));
            return rv;
        }
        rx_started++;
    }

    /* Error if RX did not get started on any unit */
    if (rx_started == 0) {
        return BCM_E_UNAVAIL;
    }
    
    /*
     * Start BCM RX packet processing
     */
    
    /* RX packet processing has already started if NH is running */
    if (next_hop_running()) {
        return BCM_E_NONE;
    }
     
    /* Register dummy callback to trigger BCM RX packet processing */
    for (i = 0; i < soc_ndev; i++) {

        /* Skip units that did not get started */
        if (!bcm_rx_active(i)) {
            cli_out("WARNING: skipping callback registration on unit %d\n", i);
            continue;
        }

        rv = bcm_rx_register(i, "process_start",
                             rx_process_start, RX_PROCESS_START_PRIO,
                             NULL, BCM_RCO_F_ALL_COS);
        if (BCM_FAILURE(rv)) {
            cli_out("ERROR: Cannot register RX callback to initiate packet "
                    "processing, unit %d: %s\n",
                    i, bcm_errmsg(rv));
            /* Clean-up */
            for (; i > 0; i--) {
                bcm_rx_unregister(i, rx_process_start,
                                  RX_PROCESS_START_PRIO);
            }
            return rv;
        }
    }
    
    /* Give time for RX handler to process and discard queued packets */
    sal_usleep(RX_PKT_CLEAR_USEC);

    /* Routine no longer needed after RX packet processing has started */
    for (i = 0; i < soc_ndev; i++) {
        bcm_rx_unregister(i, rx_process_start, RX_PROCESS_START_PRIO);
    }

    return rv;
}
Example #14
0
File: port.c Project: ariavie/bcm
int 
_bcm_tr2_port_lanes_set(int unit, bcm_port_t port, int value)
{
    uint16      dev_id;
    uint8       rev_id;
    int i, okay, old_value, count, rv = BCM_E_NONE;
    uint32 rval, val2, to_usec, mode, flags, bitpos = 0;
    uint64 rval64;
    soc_info_t *si;
    soc_field_t xq_rst2 = INVALIDf;
    uint16 phy0, phy1, phy2, phy3;
    bcm_port_t it_port;
    iarb_tdm_table_entry_t iarb_tdm;
    arb_tdm_table_entry_t arb_tdm;
    mac_driver_t *macd;

    si = &SOC_INFO(unit);

    soc_cm_get_id(unit, &dev_id, &rev_id);

    to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
                                   (10 * MILLISECOND_USEC);

    if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) {
        return BCM_E_PORT;
    }

    if ((value != 1) && (value != 4)) {
        return BCM_E_PARAM;
    }
    BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value));

#define RECONFIGURE_PORT_TYPE_INFO(ptype) \
    si->ptype.num = 0; \
    si->ptype.min = si->ptype.max = -1; \
    PBMP_ITER(si->ptype.bitmap, it_port) { \
        si->ptype.port[si->ptype.num++] = it_port; \
        if (si->ptype.min < 0) { \
            si->ptype.min = it_port; \
        } \
        if (it_port > si->ptype.max) { \
            si->ptype.max = it_port; \
        } \
    }

    /* Step 1: Change the SOC bitmaps */
    if ((value == 1) && (old_value == 4)) {
        /* The block was originally a single high-speed port */
        SOC_CONTROL_LOCK(unit);
        if (IS_HG_PORT(unit, port)) {
            SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
            SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
            SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
        } else {
            SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
        }
        SOC_PBMP_PORT_ADD(si->ge.bitmap, port);
        si->port_speed_max[port] = 1000;
        soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE);
        for (i = port + 1; i < port + 4; i++) {
            SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i);
            SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i);
            SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i);
            SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i);
            si->port_speed_max[i] = 1000;
            soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE);
        }
        RECONFIGURE_PORT_TYPE_INFO(ether);
        RECONFIGURE_PORT_TYPE_INFO(st);
        RECONFIGURE_PORT_TYPE_INFO(hg);
        RECONFIGURE_PORT_TYPE_INFO(xe);
        RECONFIGURE_PORT_TYPE_INFO(ge);
        SOC_CONTROL_UNLOCK(unit);
        BCM_IF_ERROR_RETURN(_bcm_tr2_port_tab_set(unit, port, PORT_TYPEf, 0));
        BCM_IF_ERROR_RETURN
            (soc_reg_field32_modify(unit, EGR_PORT_64r, port, PORT_TYPEf, 0));
    } else if ((value == 4) && (old_value == 1)) {
        /* The block originally had 4 GE ports */
        SOC_CONTROL_LOCK(unit);
        SOC_PBMP_PORT_ADD(si->st.bitmap, port);
        SOC_PBMP_PORT_ADD(si->hg.bitmap, port);
        SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
        SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
	switch (dev_id) {
	case BCM56526_DEVICE_ID:
	  si->port_speed_max[port] = 13000;
	  break;
	case BCM56636_DEVICE_ID:
	case BCM56638_DEVICE_ID:
	  si->port_speed_max[port] = 12000;
	  break;
	default:
	  si->port_speed_max[port] = 10000;
	}
        soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
        for (i = port + 1; i < port + 4; i++) {
            SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i);
            SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i);
            SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i);
            SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i);
        }
        RECONFIGURE_PORT_TYPE_INFO(ether);
        RECONFIGURE_PORT_TYPE_INFO(st);
        RECONFIGURE_PORT_TYPE_INFO(hg);
        RECONFIGURE_PORT_TYPE_INFO(ge);
        SOC_CONTROL_UNLOCK(unit);
        BCM_IF_ERROR_RETURN(_bcm_tr2_port_tab_set(unit, port, PORT_TYPEf, 1));
        BCM_IF_ERROR_RETURN
            (soc_reg_field32_modify(unit, EGR_PORT_64r, port, PORT_TYPEf, 1));
    }
#undef RECONFIGURE_PORT_TYPE_INFO
    soc_dport_map_update(unit);

    /* Step 2: Perform necessary block-level reset and initialization */
    /* Egress disable */
    rval = 0;
    soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 0);
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 1, rval));
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 2, rval));
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 3, rval));

    /* Hold the XQPORT hotswap reset */
    switch (port) {
    case 30:
        bitpos = 6;
        xq_rst2 = XQ0_HOTSWAP_RST_Lf;
        break;
    case 34:
        bitpos = 7;
        xq_rst2 = XQ1_HOTSWAP_RST_Lf;
        break;
    case 38:
        bitpos = 8;
        xq_rst2 = XQ2_HOTSWAP_RST_Lf;
        break;
    case 42:
        bitpos = 9;
        xq_rst2 = XQ3_HOTSWAP_RST_Lf;
        break;
    case 46:
        bitpos = 10;
        xq_rst2 = XQ4_HOTSWAP_RST_Lf;
        break;
    case 50:
        bitpos = 11;
        xq_rst2 = XQ5_HOTSWAP_RST_Lf;
        break;
    default:
        break;
    }
    BCM_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REG_2r(unit, &val2));
    soc_reg_field_set(unit, CMIC_SOFT_RESET_REG_2r, &val2, 
                      xq_rst2, 0);
    BCM_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REG_2r(unit, val2));
    sal_usleep(to_usec);

    /* Program the ingress and MMU TDMs */
    count = -1;
    for (i = 0; i < soc_mem_index_count(unit, ARB_TDM_TABLEm); i++) {
        BCM_IF_ERROR_RETURN
            (READ_ARB_TDM_TABLEm(unit, MEM_BLOCK_ANY, i, &arb_tdm));
        BCM_IF_ERROR_RETURN
            (READ_IARB_TDM_TABLEm(unit, MEM_BLOCK_ANY, i, &iarb_tdm));
        it_port = soc_ARB_TDM_TABLEm_field32_get(unit, &arb_tdm, PORT_NUMf);
        /* First set to disabled - 63 */
        if (old_value == value) {
            continue;
        } else if (old_value == 4 && value == 1) {
            if (port != it_port) {
                continue;
            }
        } else {
            if ((it_port != port) && (it_port != port + 1) && 
                (it_port != port + 2) && (it_port != port + 3)) {
                continue;
            }
        }
        soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 63);
        soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 63);
        BCM_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 
                                                  &iarb_tdm));
        BCM_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 
                                                 &arb_tdm));
        /* Then program the desired value */
        if (old_value == 4 && value == 1) {
            count++;
            soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 
                                           port + (count % 4));
            soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 
                                            port + (count % 4));
        } else {
            soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, port);
            soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, port);
        }
        BCM_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 
                                                  &iarb_tdm));
        BCM_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 
                                                 &arb_tdm));
        if (soc_ARB_TDM_TABLEm_field32_get(unit, &arb_tdm, WRAP_ENf)) {
            break;
        }
    }

    /* Clear the ECRC register */
    for (i = port; i < port + 4; i++) {
        BCM_IF_ERROR_RETURN(WRITE_TOQ_EP_CREDITr(unit, i, 0));
    }

    /* Reset the EP */
    BCM_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval));
    rval |= (1 << (bitpos - 6));
    BCM_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval));
    sal_usleep(to_usec);
    BCM_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval));
    if (value == 4) {
        rval |= (1 << bitpos);
    } else {
        rval &= ~(1 << bitpos);
    }  
    rval &= ~(1 << (bitpos - 6));
    BCM_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval));
    sal_usleep(to_usec);

    /* Bring the XQPORT block out of reset */
    BCM_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REG_2r(unit, &val2));
    soc_reg_field_set(unit, CMIC_SOFT_RESET_REG_2r, &val2, 
                      xq_rst2, 1);
    BCM_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REG_2r(unit, val2));
    sal_usleep(to_usec);

    /* Bring the hyperlite out of reset */
    soc_xgxs_reset(unit, port);
    BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XQPORT_XGXS_NEWCTL_REGr, 
                                               port, TXD1G_FIFO_RSTBf, 0xf));

    /* Change the XQPORT block mode */
    mode = (value == 4) ? 2 : 1; /* 2 = high-speed, 1 = GE */
    SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
    soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 
                      XQPORT_MODE_BITSf, mode);
    SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval));
    if (value == 4) {
        rval = 0;
        soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1);
        soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
        SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
    }

    /* Egress Enable */
    rval = 0;
    soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1);
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));

    rval = 0;
    soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 
                      (value == 1) ? 1 : 0);
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 1, rval));
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 2, rval));
    SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 3, rval));

    /* Step 3: Port probe and initialization */
    flags = 0;
    if (value == 1) {
        phy0 = soc_property_port_get(unit, port, spn_FLEX_PORT_PHY_ADDR, 0);
        if (!phy0) {
            phy0 = _soc_triumph2_int_phy_addr[port];
            flags = _SHR_PORT_PHY_INTERNAL;
        }
        SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
        SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port, flags, phy0));
        BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
        if (!okay) {
            return BCM_E_INTERNAL;
        }
        BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE));
        phy1 = soc_property_port_get(unit, port + 1, spn_FLEX_PORT_PHY_ADDR, 0);
        if (!phy1) {
            phy1 = _soc_triumph2_int_phy_addr[port + 1];
            flags = _SHR_PORT_PHY_INTERNAL;
        }  
        SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
        SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 1, flags, phy1));
        BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 1, &okay));
        if (!okay) {
            return BCM_E_INTERNAL;
        }     
        BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 1, TRUE));
        phy2 = soc_property_port_get(unit, port + 2, spn_FLEX_PORT_PHY_ADDR, 0);
        if (!phy2) {
            phy2 = _soc_triumph2_int_phy_addr[port + 2];
            flags = _SHR_PORT_PHY_INTERNAL;
        }
        SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
        SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 2, flags, phy2));
        BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 2, &okay));
        if (!okay) {
            return BCM_E_INTERNAL;
        }
        BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 2, TRUE));
        phy3 = soc_property_port_get(unit, port + 3, spn_FLEX_PORT_PHY_ADDR, 0);
        if (!phy3) {
            phy3 = _soc_triumph2_int_phy_addr[port + 3];
            flags = _SHR_PORT_PHY_INTERNAL;
        }
        SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
        SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 3, flags, phy3));
        BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 3, &okay));
        if (!okay) {
            return BCM_E_INTERNAL;
        }
        BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 3, TRUE));
    } else {
        phy0 = soc_property_port_get(unit, port, spn_FLEX_PORT_PHY_ADDR, 0);
        if (!phy0) {
            phy0 = _soc_triumph2_int_phy_addr[port];
            flags = _SHR_PORT_PHY_INTERNAL;
        } 
        SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
        if (old_value == 1) {
            SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
            SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
            SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
        }
        SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port, flags, phy0));
        BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
        if (!okay) {
            return BCM_E_INTERNAL;
        }

        /* Need to reset the Bigmac to make registers accessible */
        SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));

        SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64));
        soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, TXRESETf, 1);
        soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, RXRESETf, 1);
        SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64));

        SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64));
        soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, TXRESETf, 0);
        soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, RXRESETf, 0);
        SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64));

        SOC_IF_ERROR_RETURN(MAC_INIT(macd, unit, port));

        BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE));
    }
    return rv;
}
Example #15
0
int
soc_port_credit_reset(int unit, soc_port_t port)
{
    int phy_port;
    egr_port_credit_reset_entry_t entry;

    switch (SOC_CHIP_GROUP(unit)) {
    case SOC_CHIP_BCM56850:
        /* Should only be called by XLMAC driver */
        phy_port = SOC_INFO(unit).port_l2p_mapping[port];
        sal_memset(&entry, 0, sizeof(entry));
        soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 1);
        SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
                                                         phy_port, &entry));
        soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 0);
        SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
                                                         phy_port, &entry));
        break;
    case SOC_CHIP_BCM56150:
    {
        uint32 rval;
        /* Should only be called by XLMAC driver */
        int bindex;
        static const soc_field_t port_field[] = {
            PORT0f, PORT1f, PORT2f, PORT3f
        };
        phy_port = SOC_INFO(unit).port_l2p_mapping[port];
        bindex = SOC_PORT_BINDEX(unit, phy_port);

        SOC_IF_ERROR_RETURN
            (soc_reg_field32_modify(unit, XLPORT_ENABLE_REGr, port,
                                    port_field[bindex], 0));

        sal_memset(&entry, 0, sizeof(entry));
        soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 1);
        SOC_IF_ERROR_RETURN
            (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, phy_port, &entry));

        SOC_IF_ERROR_RETURN
            (READ_XLPORT_TXFIFO_CTRLr(unit, port, &rval));
        soc_reg_field_set(unit, XLPORT_TXFIFO_CTRLr, &rval, MAC_CLR_COUNTf,1);
        soc_reg_field_set(unit, XLPORT_TXFIFO_CTRLr, &rval, CORE_CLR_COUNTf,1);
        SOC_IF_ERROR_RETURN
            (WRITE_XLPORT_TXFIFO_CTRLr(unit, port, rval));

        sal_usleep(1000);

        soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 0);
        SOC_IF_ERROR_RETURN
            (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, phy_port, &entry));

        soc_reg_field_set(unit, XLPORT_TXFIFO_CTRLr, &rval, MAC_CLR_COUNTf,0);
        soc_reg_field_set(unit, XLPORT_TXFIFO_CTRLr, &rval, CORE_CLR_COUNTf,0);
        SOC_IF_ERROR_RETURN
            (WRITE_XLPORT_TXFIFO_CTRLr(unit, port, rval));

        SOC_IF_ERROR_RETURN
            (soc_reg_field32_modify(unit, XLPORT_ENABLE_REGr, port,
                                    port_field[bindex], 1));
    }
        break;
    default:
        break;
    }

    return SOC_E_NONE;
}
Example #16
0
STATIC void
_bcm_report_fifo_dma_thread(void *unit_vp)
{
    int unit = PTR_TO_INT(unit_vp);
    _bcm_ft_report_ctrl_t *rctrl = _bcm_ft_report_ctrl[unit];
    _bcm_ft_report_cb_entry_t *cb_entry;
    bcm_regex_report_t data;
    int rv, entries_per_buf, interval, count, i, j, non_empty;
    int chan, entry_words, pending=0;
    void *host_buf = NULL;
    void *host_entry;
    uint32 dir, *buff_max, rval;
    uint8  overflow, timeout;
    soc_mem_t   ftmem;
    soc_control_t *soc = SOC_CONTROL(unit);
    int cmc = SOC_PCI_CMC(unit);
    bcm_regex_config_t config;

    chan = SOC_MEM_FIFO_DMA_CHANNEL_0;
    rv = bcm_esw_regex_config_get(unit, &config);
    if (BCM_FAILURE(rv)) {
        LOG_VERBOSE(BSL_LS_BCM_INTR,
                    (BSL_META_U(unit,
                                " failed to retrieve configuration, rv = %d\n"), rv));
        goto cleanup_exit;
    }
    entries_per_buf = config.report_buffer_size;

    LOG_VERBOSE(BSL_LS_BCM_INTR,
                (BSL_META_U(unit,
                            " starting _bcm_report_fifo_dma_thread\n")));

    ftmem = FT_EXPORT_FIFOm;
    entry_words = soc_mem_entry_words(unit, ftmem);
    host_buf = soc_cm_salloc(unit, entries_per_buf * entry_words * WORDS2BYTES(1),
                             "FT export fifo DMA Buffer");
    if (host_buf == NULL) {
        soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR,
                           SOC_SWITCH_EVENT_THREAD_REGEX_REPORT, __LINE__,
                           BCM_E_MEMORY);
        goto cleanup_exit;
    }

    rv = soc_mem_fifo_dma_start(unit, chan,
                                ftmem, MEM_BLOCK_ANY,
                                entries_per_buf, host_buf);
    if (BCM_FAILURE(rv)) {
        soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR,
                           SOC_SWITCH_EVENT_THREAD_REGEX_REPORT,
                           __LINE__, rv);
        LOG_VERBOSE(BSL_LS_BCM_INTR,
                    (BSL_META_U(unit,
                                " soc_mem_fifo_dma_start failed, rv = %d\n"), rv));
        goto cleanup_exit;
    }

    host_entry = host_buf;
    buff_max = (uint32 *)host_entry + (entries_per_buf * entry_words);

    while ((interval = rctrl->interval) > 0) {
        overflow = 0; timeout = 0;
        if (soc->ftreportIntrEnb) {
            soc_cmicm_intr0_enable(unit, IRQ_CMCx_FIFO_CH_DMA(chan));
            if (sal_sem_take(SOC_CONTROL(unit)->ftreportIntr, interval) < 0) {
                LOG_VERBOSE(BSL_LS_BCM_INTR,
                            (BSL_META_U(unit,
                                        " polling timeout ft_export_fifo=%d\n"), interval));
            } else {
                /* Disabling the interrupt (CHAN0) as the read process is underway */
                soc_cmicm_intr0_disable(unit, IRQ_CMCx_FIFO_CH_DMA(chan));
                LOG_VERBOSE(BSL_LS_BCM_INTR,
                            (BSL_META_U(unit,
                                        "woken up interval=%d\n"), interval));
                /* check for timeout or overflow and either process or continue */
                rval = soc_pci_read(unit,
                                    CMIC_CMCx_FIFO_CHy_RD_DMA_STAT_OFFSET(cmc, chan));
                overflow = soc_reg_field_get(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STATr,
                                             rval, HOSTMEM_TIMEOUTf);
                timeout = soc_reg_field_get(unit,
                                            CMIC_CMC0_FIFO_CH0_RD_DMA_STATr, rval, HOSTMEM_OVERFLOWf);
                overflow |= timeout ? 1 : 0;
            }
        } else {
            sal_usleep(interval);
        }

        if (rctrl->interval <= 0) {
            break;
        }

        /* reconcile the user registered callbacks. */
        for (i = 0; i < _BCM_FT_REPORT_MAX_CB; i++) {
            cb_entry = &rctrl->callback_entry[i];
            switch (cb_entry->state) {
                case _BCM_FT_REPORT_CALLBACK_STATE_REGISTERED:
                    cb_entry->state = _BCM_FT_REPORT_CALLBACK_STATE_ACTIVE;
                    break;
                case _BCM_FT_REPORT_CALLBACK_STATE_UNREGISTERED:
                    cb_entry->state = _BCM_FT_REPORT_CALLBACK_STATE_INVALID;
                    break;
                default:
                    break;
            }
        }

        non_empty = FALSE;
        do {
            rv = soc_mem_fifo_dma_get_num_entries(unit, chan, &count);
            if (SOC_SUCCESS(rv)) {
                non_empty = TRUE;
                for (i = 0; i < count; i++) {
                    rv = _bcm_ft_report_process_export_entry(unit, host_entry,
                                                             &data, &pending, &dir);
                    host_entry = (uint32 *)host_entry + entry_words;
                    /* handle roll over */
                    if ((uint32 *)host_entry >= buff_max) {
                        host_entry = host_buf;
                    }
                    for (j = 0; (j < _BCM_FT_REPORT_MAX_CB) && !pending && !rv; j++) {
                        cb_entry = &rctrl->callback_entry[j];
                        if ((cb_entry->state == _BCM_FT_REPORT_CALLBACK_STATE_ACTIVE) &&
                            ((cb_entry->reports & BCM_REGEX_REPORT_ALL) |
                             (data.flags & cb_entry->reports))) {
                            cb_entry->callback(unit, &data, cb_entry->userdata);
                        }
                    }
                }
                if (overflow) {
                    rval = 0;
                    soc_reg_field_set(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STAT_CLRr,
                                      &rval, HOSTMEM_OVERFLOWf, 1);
                    soc_reg_field_set(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STAT_CLRr,
                                      &rval, HOSTMEM_TIMEOUTf, 1);
                    soc_pci_write(unit,
                                  CMIC_CMCx_FIFO_CHy_RD_DMA_STAT_CLR_OFFSET(cmc, chan), rval);
                }
                (void)_soc_mem_sbus_fifo_dma_set_entries_read(unit, chan, i);
            } else {
                if (overflow) {
                    rval = 0;
                    soc_reg_field_set(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STAT_CLRr,
                                      &rval, HOSTMEM_OVERFLOWf, 1);
                    soc_reg_field_set(unit, CMIC_CMC0_FIFO_CH0_RD_DMA_STAT_CLRr,
                                      &rval, HOSTMEM_TIMEOUTf, 1);
                    soc_pci_write(unit,
                                  CMIC_CMCx_FIFO_CHy_RD_DMA_STAT_CLR_OFFSET(cmc, chan), rval);
                }
                LOG_VERBOSE(BSL_LS_BCM_INTR,
                            (BSL_META_U(unit,
                                        " soc_mem_fifo_dma_get_num_entries failed, rv=%d\n"), rv));
                non_empty = FALSE;
            }
        } while (non_empty);
    }

cleanup_exit:
    LOG_VERBOSE(BSL_LS_BCM_INTR,
                (BSL_META_U(unit,
                            " stopping _bcm_report_fifo_dma_thread\n")));
    (void)soc_mem_fifo_dma_stop(unit, chan);

    if (host_buf != NULL) {
        soc_cm_sfree(unit, host_buf);
    }
    rctrl->pid = SAL_THREAD_ERROR;
    sal_thread_exit(0);
}
Example #17
0
STATIC int
phy_serdescombo_init_no_reset(int unit, soc_port_t port)
{
    int                fiber;
    uint16             data16, mask16;
    phy_ctrl_t        *pc;

    pc                       = INT_PHY_SW_STATE(unit, port);
    fiber                    = PHY_FIBER_MODE(unit, port);
    pc->fiber.enable         = fiber;
    pc->fiber.preferred      = fiber;
    pc->fiber.autoneg_enable = 1;
    pc->fiber.autoneg_advert = ADVERT_ALL_FIBER;
    pc->fiber.force_speed    = 1000;
    pc->fiber.force_duplex   = TRUE;
    pc->fiber.master         = SOC_PORT_MS_NONE;
    pc->fiber.mdix           = SOC_PORT_MDIX_NORMAL;

    /* Since physerdescombo driver reset function vector does not reset
     * the SerDes, reset the SerDes in initialization first. 
     * The internal SERDES PHY's reset bit is self-clearing.
     */
    SOC_IF_ERROR_RETURN
        (WRITE_SERDESCOMBO_MII_CTRLr(unit, pc, COMBO_MII_CTRL_RESET));

    sal_usleep(10000);

    mask16 = COMBO_MII_CTRL_AN_ENABLE | COMBO_MII_CTRL_AN_RESTART |
             COMBO_MII_CTRL_FD;
    if (PHY_COPPER_MODE(unit, port) && !PHY_SGMII_AUTONEG_MODE(unit, port)) {
        data16 = COMBO_MII_CTRL_FD;
    } else {
        data16 = COMBO_MII_CTRL_AN_ENABLE | COMBO_MII_CTRL_AN_RESTART |
                 COMBO_MII_CTRL_FD;
    }
    SOC_IF_ERROR_RETURN
        (MODIFY_SERDESCOMBO_MII_CTRLr(unit, pc, data16, mask16));

    SOC_IF_ERROR_RETURN
        (phy_serdescombo_adv_local_set(unit, port, pc->fiber.autoneg_advert));

    /* Configure default preemphasis, predriver, idriver values */
    SOC_IF_ERROR_RETURN
        (_phy_serdescombo_tx_control_set(unit, pc, port));

    SOC_IF_ERROR_RETURN
        (MODIFY_SERDESCOMBO_1000X_CTRL2r(unit, pc, 
                       (COMBO_1000X_FALSE_LNK_DIS | COMBO_1000X_FLT_FORCE_EN),
                       (COMBO_1000X_FALSE_LNK_DIS | COMBO_1000X_FLT_FORCE_EN)));

    data16 = 0;
    mask16 = COMBO_1000X_AUTO_DETECT | COMBO_1000X_FIBER_MODE;
    /*
     * Configure signal auto-detection between SGMII and fiber.
     * This detection only works if auto-negotiation is enabled.
     */
    if (soc_property_port_get(unit, port, 
                              spn_SERDES_AUTOMEDIUM, FALSE)) {
        data16 |= COMBO_1000X_AUTO_DETECT;
    }
    /*
     * Put the Serdes in Fiber or SGMII mode
     */
    if (fiber) {
        if (soc_property_port_get(unit, port,
                                  spn_SERDES_FIBER_PREF, TRUE)) {
            data16 |= COMBO_1000X_FIBER_MODE;
        }
    }
    SOC_IF_ERROR_RETURN
        (MODIFY_SERDESCOMBO_1000X_CTRL1r(unit, pc, data16, mask16));

    if (!fiber) {
        /* Do not wait 10ms for sync status before a valid link is 
         * established when auto-negotiation is disabled.
         */
        SOC_IF_ERROR_RETURN
            (MODIFY_SERDESCOMBO_1000X_CTRL2r(unit, pc, 0x0000, 0x0004));
    }
   
    SOC_IF_ERROR_RETURN
        (_phy_serdescombo_combo_serdes_init(unit, port));
 
    LOG_INFO(BSL_LS_SOC_PHY,
             (BSL_META_U(unit,
                         "phy_serdescombo_init: u=%d p=%d %s\n"),
              unit, port, (fiber) ? "Fiber" : "Copper"));
    return SOC_E_NONE;
}
Example #18
0
/*
 * Function:
 *    phy_522x_init
 * Purpose:
 *    Initialize phy
 * Parameters:
 *    unit - device number
 *    port - port number
 * Returns:
 *    SOC_E_XXX
 */
STATIC int
phy_522x_init(int unit, soc_port_t port)
{
    phy_ctrl_t  *pc;
    uint16       led1;
    uint16       led2;
    uint16       led_mode;
    int          phy_index;
    soc_pbmp_t pbmp_100fx;
    uint16      tmp = 0;
    uint16  mii_ctrl = 0;
    uint16  mii_stat = 0;
    uint32 loop = 0;


    pc = EXT_PHY_SW_STATE(unit, port);
   
    /* BCM5248 after a hardware reset or s/w reset does not 
       guarantee internal automatic power down (APD) timer to be 
       reset for all ports. It could result in waking up of 
       all inactive ports at the same time causing excessive noise 
       on the power supplies causing active ports to have performance
       issues. To avoid this reset all the MII registers.
       Refer - Design Guide for more detials 
     */
    if(PHY_IS_BCM5248(pc)) {
        /* Set all the MII registers to their default values */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1f, 0x0200));
       /* Delay 100 microseconds */
       sal_usleep(100); 
    }

    SOC_IF_ERROR_RETURN(phy_fe_init(unit, port));

    SOC_IF_ERROR_RETURN
        (WRITE_PHY_REG(unit, pc, 0x16, 0x0002)); 

    if ((PHY_IS_BCM53101_A0(pc)) || (PHY_IS_BCM53280_A0(pc))) {
        /* EPHY initial setting for Lotus A0 and ThunderBolt A0 */
        /* enable ephy shadow 2 regsiter */
        SOC_IF_ERROR_RETURN(PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x1f, 0xf));

        /* ephy R1 resistor trim */
        SOC_IF_ERROR_RETURN(
            PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x16, 0x5286));

        /* ephy linedriver opamp compensation capacitor to 3pF */
        SOC_IF_ERROR_RETURN(
            PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x17, 0x9050));

        /* ephy tail current for 100TX to 8mA */
        SOC_IF_ERROR_RETURN(
            PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x16, 0x5296));

        /* ephy rise-fall digital waveform to 5788(rising)  5688(falling) */
        SOC_IF_ERROR_RETURN(
            PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x17, 0x9073));

        /* enable ephy shadow 2 regsiter */
        SOC_IF_ERROR_RETURN(PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x1f, 0xb));

        /* Set current 2.13% lower to compensate for amplitude symmetry */
        SOC_IF_ERROR_RETURN(PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x17, 0x1f)); 
    }

    if (PHY_IS_BCM53280(pc) && (!PHY_IS_BCM53280_A0(pc))) {
        /* TB Bx RL WAR*/
         /* enable ephy shadow 2 regsiter */
        SOC_IF_ERROR_RETURN(PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x1f, 0xf));
        /* default value 0x9050. change bit[10:9]=2'b01 */
        SOC_IF_ERROR_RETURN(
            PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x17, 0x9250));
        /* disable ephy shadow 2 regsiter */
        SOC_IF_ERROR_RETURN(PHYFEGE_REG_WRITE(unit, pc, 0x0, 0x0, 0x1f, 0xb));
    }

    switch ((pc->phy_model << 16) | pc->phy_oui) {
    case (PHY_BCM5228_MODEL << 16) | PHY_BCM5228_OUI:
    case (PHY_BCM5238_MODEL << 16) | PHY_BCM5238_OUI:
    case (PHY_BCM5248_MODEL << 16) | PHY_BCM5248_OUI:
    case (PHY_BCM5324_MODEL << 16) | PHY_BCM5324_OUI:
    case (PHY_BCM5324_MODEL << 16) | PHY_BCM5324A1_OUI:
    case (PHY_BCM53101_MODEL << 16) | PHY_BCM53101_OUI:

        /* enable jumbo packets */
        SOC_IF_ERROR_RETURN
            (MODIFY_PHY522X_AUX_MODE2r(unit, pc, 0x0400, 0x0400));
        break;
    case (PHY_BCM53280_MODEL << 16) | PHY_BCM53280_OUI:
        if (!PHY_IS_BCM53280_A0(pc)) {
            /* Enable jumbo packets. Only supported after B0 */
            SOC_IF_ERROR_RETURN
                (MODIFY_PHY522X_AUX_MODE2r(unit, pc, 0x0400, 0x0400));
        }
        break;
    }

    if (PHY_IS_BCM5248(pc)) {
        /* Find out which port is the first port of the octal PHY */
        phy_index = soc_property_port_get(unit, port, 
                                          spn_PHY_OCTAL_PORT_FIRST, 0);

        phy_index = (port - phy_index) % 8;
        if (0 == phy_index) {
            /* Link */
            led1 = soc_property_port_get(unit, port, spn_PHY_LED1_MODE, 0); 

            /* Activity */
            led2 = soc_property_port_get(unit, port, spn_PHY_LED2_MODE, 1);

            /* Enable parallel LED mode and program LED 1 and LED2 */
            SOC_IF_ERROR_RETURN
                (READ_PHY522X_AUX_MODE4r(unit, pc, &led_mode));
            led_mode = ~(0x023f);
            led_mode |= (1 << 9) |             /* Enable parallel LED mode */
                        (led2 << 3) | (led1);  /* LED1 and LED2 mode select */ 
            SOC_IF_ERROR_RETURN
                (WRITE_PHY522X_AUX_MODE4r(unit, pc, led_mode));
        }

        if (2 == phy_index) {
            /* Disable Extended Parallel LED Mode */
            SOC_IF_ERROR_RETURN
                (READ_PHY522X_AUX_MODE4r(unit, pc, &led_mode));
            led_mode = ~(1 << 9);
            SOC_IF_ERROR_RETURN
                (WRITE_PHY522X_AUX_MODE4r(unit, pc, led_mode));
        }
    }

    /*
      * Get 100-FX ports from config.bcm.
      */
    pbmp_100fx = soc_property_get_pbmp(unit, spn_PBMP_FE_100FX, 0);
    if (SOC_PBMP_MEMBER(pbmp_100fx, port)) {
        /* Speed/Duplex selection and auto-negotiation Disable */
        SOC_IF_ERROR_RETURN             
            (WRITE_PHY522X_MII_CTRLr(unit, pc, 0x2100));

        /* Scrambler and Descrambler Disable and Far-End-Fault Enable */
        SOC_IF_ERROR_RETURN            
            (READ_PHY522X_AUX_CTRLr(unit, pc, &tmp));
        tmp |= 0x0220;
        SOC_IF_ERROR_RETURN            
            (WRITE_PHY522X_AUX_CTRLr(unit, pc, tmp));

        /* Configure Transmit and Receive for Binary Signaling */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_READ(unit, pc, 0x0000, 0x17, &tmp));
        tmp |= 0x20;
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x17, 0x20));

        /* Enable Internal EFX Signal Detect Function */
        /* Enable the shadow register */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1f, 0x008b));
        /* Enable the special Signal Detect function */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x19, 0x0200));
        /* Configure the transmit amplitude for 1V pk-pk differential */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1d, 0x0084));
        /* Exist the shadow register */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1f, 0x000b));
#if EFX_HALF_THRESHOLD_MODE
        /* Enable the shadow register */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1f, 0x008b));
        /* Set the threshold to the Half Threshold mode*/
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x11, 0x0a01));
        /* Exist the shadow register */
        SOC_IF_ERROR_RETURN
            (PHY522X_REG_WRITE(unit, pc, 0x0000, 0x1f, 0x000b));
#endif
    }

    if (PHY_IS_BCM53242(pc) || PHY_IS_BCM53262(pc)) {
        /*
         * Add the workaround of collision problem when fe ports' first link 
         * is at 10half after each power cycle.
         */
        /* an off */
        SOC_IF_ERROR_RETURN
            (READ_PHYFEGE_MII_CTRLr(unit, pc, &mii_ctrl));
        mii_ctrl &= ~(MII_CTRL_AE | MII_CTRL_RAN);
        SOC_IF_ERROR_RETURN
            (WRITE_PHYFEGE_MII_CTRLr(unit, pc, mii_ctrl));

        /* speed 100 */
        SOC_IF_ERROR_RETURN
            (READ_PHYFEGE_MII_CTRLr(unit, pc, &mii_ctrl));
        mii_ctrl |= MII_CTRL_SS_100;
        SOC_IF_ERROR_RETURN
            (WRITE_PHYFEGE_MII_CTRLr(unit, pc, mii_ctrl));

        /* loopback on */
        SOC_IF_ERROR_RETURN
            (READ_PHYFEGE_MII_CTRLr(unit, pc, &mii_ctrl));
        mii_ctrl |= MII_CTRL_LE;
        SOC_IF_ERROR_RETURN
            (WRITE_PHYFEGE_MII_CTRLr(unit, pc, mii_ctrl));

       /* check the link status */
       for (loop = 0; loop < LINK_WAIT_TIMEOUT; loop++) {
           SOC_IF_ERROR_RETURN
               (READ_PHYFEGE_MII_STATr(unit, pc, &mii_stat));
           if ((mii_stat & MII_STAT_LA) != 0) {
               break;
           }
       }

        /* loopback off */
        SOC_IF_ERROR_RETURN
            (READ_PHYFEGE_MII_CTRLr(unit, pc, &mii_ctrl));
        mii_ctrl &= ~MII_CTRL_LE;
        SOC_IF_ERROR_RETURN
            (WRITE_PHYFEGE_MII_CTRLr(unit, pc, mii_ctrl));

        /* an on */
        SOC_IF_ERROR_RETURN
            (READ_PHYFEGE_MII_CTRLr(unit, pc, &mii_ctrl));
        mii_ctrl |= MII_CTRL_AE | MII_CTRL_RAN;
        SOC_IF_ERROR_RETURN
            (WRITE_PHYFEGE_MII_CTRLr(unit, pc, mii_ctrl));
    }

    return SOC_E_NONE;
}
Example #19
0
File: mbox.c Project: ariavie/bcm
int
_bcm_mbox_tx(
    int unit,
    uint32 node_num,
    _bcm_mbox_transport_type_t transport,
    uint8 *message,
    int message_len)
{
#if defined(BCM_CMICM_SUPPORT)
    int rv = BCM_E_NONE;

    mos_msg_data_t uc_msg;

    int wait_iter = 0;

    /* soc_cm_print("cmic_tx Len:%d\n", message_len); */
    /* _bcm_dump_hex(message, message_len, 4); */

    if (mbox_info.unit_state[unit].mboxes->status[0] != _BCM_MBOX_MS_EMPTY) {
        /* char this_thread_name[100]; */
        /* sal_thread_name(sal_thread_self(), this_thread_name, 100); */
        /* ptp_printf("******* Contention, status %d (%s is sending, %s wants to send)\n", */
        /*            mbox_info.unit_state[unit].mboxes->status[0], holding_thread_name, this_thread_name); */
        SOC_DEBUG_PRINT((DK_ERR | DK_VERBOSE, "Contention\n"));
    }

    /* wait for to-TOP buffer to be free, if it is not already */
    while (mbox_info.unit_state[unit].mboxes->status[0] != _BCM_MBOX_MS_EMPTY && wait_iter < 100000) {
        ++wait_iter;
        sal_usleep(1);
    }

    if (mbox_info.unit_state[unit].mboxes->status[0] != _BCM_MBOX_MS_EMPTY) {
        soc_cm_print("TOP message buffer in use on Tx, re-pinging\n");
        rv = soc_cmic_uc_msg_send(unit, mbox_info.unit_state[unit].core_num, &uc_msg, 1000000);
        return BCM_E_FAIL;
    }
    /* sal_thread_name(sal_thread_self(), holding_thread_name, 100); */

    if (wait_iter > 0) {
        /* ptp_printf("Wait to send outgoing to ToP: %d\n", wait_iter); */
    }

    /* load the mailbox */
    sal_memcpy((uint8 *)mbox_info.unit_state[unit].mboxes->mbox[0].data, message, message_len);
    mbox_info.unit_state[unit].mboxes->mbox[0].data_len = message_len;
    mbox_info.unit_state[unit].mboxes->mbox[0].node_num = 0;  

    /* finish mbox load by setting status */
    switch (transport) {
    case _BCM_MBOX_MESSAGE:
        mbox_info.unit_state[unit].mboxes->status[0] = _BCM_MBOX_MS_CMD;
        break;
    case _BCM_MBOX_TUNNEL_TO:
        mbox_info.unit_state[unit].mboxes->status[0] = _BCM_MBOX_MS_TUNNEL_TO;
        break;
    case _BCM_MBOX_TUNNEL_OUT:
        mbox_info.unit_state[unit].mboxes->status[0] = _BCM_MBOX_MS_TUNNEL_OUT;
        break;
    default:
        SOC_DEBUG_PRINT((DK_ERR | DK_VERBOSE,
                         "%s() failed %s\n", __func__, "Unknown transport type"));
    }

    /* Send a notification to the CMICm */
    sal_memset(&uc_msg, 0, sizeof(uc_msg));
    uc_msg.s.mclass = MOS_MSG_CLASS_BS;
    uc_msg.s.subclass = MOS_MSG_SUBCLASS_MBOX_CMDRESP;
    uc_msg.s.len = message_len;
    uc_msg.s.data = 0;

    rv = soc_cmic_uc_msg_send(unit, mbox_info.unit_state[unit].core_num, &uc_msg, 1000000);
    return rv;

#else  /* BCM_CMICM_SUPPORT */
    return BCM_E_UNAVAIL;
#endif /* BCM_CMICM_SUPPORT */
}
Example #20
0
/*
 *  Function : drv_lotus_dev_prop_set
 *
 *  Purpose :
 *     Set the device property information
 *
 *  Parameters :
 *      unit        :   unit id
 *      prop_type   :   property type
 *      prop_val     :   property value of the property type
 *
 *  Return :
 *      SOC_E_UNAVAIL 
 *
 *  Note :
 *      This function is to set the device porperty information.
 *
 */
int 
drv_lotus_dev_prop_set(int unit, uint32 prop_type, uint32 prop_val)
{
    int rv = SOC_E_NONE, i;
    uint32  reg_val = 0, temp = 0;

    switch(prop_type) {
        case DRV_DEV_PROP_LOW_POWER_ENABLE:
            if (prop_val) {
                if (prop_val != (DEV_BCM53101_LOW_POWER_FREQ / 1000)) {
                    return SOC_E_PARAM;
                }
                /* Enable LOW POWER MODE */      
                
                /* 1. Check the signal detection should be clear */
                /* It will take 1.5s from link-down to signal-detect deassertion */
                for (i=0; i < DEV_BCM53101_SINGAL_DETECTION_RETRY; i++) {
                    SOC_IF_ERROR_RETURN(
                        REG_READ_PHY_STSr(unit, &reg_val));
                    soc_PHY_STSr_field_get(unit, &reg_val, PHY_ENERGY_DETf, &temp);
                    if (!temp) {
                        break;
                    }
                    /* Check link status if any pulg-in */
                    SOC_IF_ERROR_RETURN(
                        REG_READ_LNKSTSr(unit, &reg_val));
                    if (reg_val & DRV_LOTUS_MAC_LOW_POWER_SUPPORT_PBMP) {
                        /* There is a link-up come from one of front ports.  */
                        /* Return it, didn't set to low power mode */
                        return SOC_E_FAIL;
                    }
                    sal_usleep(1000);
                }
                if (i == DEV_BCM53101_SINGAL_DETECTION_RETRY) {
                    soc_cm_debug(DK_ERR,"The signal detection is not clear.\n");
                    return SOC_E_TIMEOUT;
                }

                /* Adjust the SPI freq to 1/4 slower than system clock */
#if defined(KEYSTONE)
                SPI_LOCK;
                ai_soc_spi_freq_set(NULL, (DEV_BCM53101_LOW_POWER_FREQ /4));
                SPI_UNLOCK;
#endif

                /* 2. Shut down PHY */
                SOC_IF_ERROR_RETURN(
                    REG_READ_PHY_PWR_DOWNr(unit, &reg_val));
                temp = DRV_LOTUS_MAC_LOW_POWER_SUPPORT_PBMP;
                
                /* 2.1 Enable PHY Power Down */
                soc_PHY_PWR_DOWNr_field_set(unit, &reg_val, 
                    PHY_PWR_DOWN_PHY_ENf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_PWR_DOWNr(unit, &reg_val));
                
                /* 2.2 Power Down PHY TX */
                soc_PHY_PWR_DOWNr_field_set(unit, &reg_val, 
                    PHY_PWR_DOWN_PHY_TXf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_PWR_DOWNr(unit, &reg_val));

                 /* 2.3 Power Down PHY RX */
                soc_PHY_PWR_DOWNr_field_set(unit, &reg_val, 
                    PHY_PWR_DOWN_PHY_RXf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_PWR_DOWNr(unit, &reg_val));

                /* 
                 * 3. Slow down system clock to 12.5Mhz 
                 *     and shut down MAC clocks for port 5 and port 8 
                 */
                SOC_IF_ERROR_RETURN(
                    REG_READ_LOW_POWER_CTRLr(unit, &reg_val));
                temp = 0x1;
                soc_LOW_POWER_CTRLr_field_set(unit, &reg_val, 
                    SYS_LOW_POWER_ENf, &temp);
                soc_LOW_POWER_CTRLr_field_set(unit, &reg_val, 
                    SLEEP_MACf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_LOW_POWER_CTRLr(unit, &reg_val));

                /* 4. Show down PLL */
                SOC_IF_ERROR_RETURN(
                    REG_READ_PLL_CTRLr(unit, &reg_val));
                temp = 0x1f;
                soc_PLL_CTRLr_field_set(unit, &reg_val, 
                    PLL_POWER_DOWN_CTRLf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PLL_CTRLr(unit, &reg_val));
                
            } else {
                /* Disable Low Power Mode */

                /* 1. Bring back PLL */
                SOC_IF_ERROR_RETURN(
                    REG_READ_PLL_CTRLr(unit, &reg_val));
                temp = 0x1;
                soc_PLL_CTRLr_field_set(unit, &reg_val, 
                    PLL_ARESETf, &temp);
                soc_PLL_CTRLr_field_set(unit, &reg_val, 
                    PLL_DRESETf, &temp);
                temp = 0;
                soc_PLL_CTRLr_field_set(unit, &reg_val, 
                    PLL_POWER_DOWN_CTRLf, &temp);
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PLL_CTRLr(unit, &reg_val));
                
                reg_val = 0x0;
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PLL_CTRLr(unit, &reg_val));
                
                /* 2. Bring back system and MAC clocks */
                reg_val = 0;
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_LOW_POWER_CTRLr(unit, &reg_val));

                /* 3. Bring back PHY */
                /* 3.1 Disable PHY power down */
                reg_val = 0;
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_PWR_DOWNr(unit, &reg_val));
                /* 3.2 Reset PHY , need wait for at least 400ns */
                reg_val = DRV_LOTUS_MAC_LOW_POWER_SUPPORT_PBMP;
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_CTRLr(unit, &reg_val));
                sal_usleep(1);
                /* 3.3 PHY reset finished */
                /* Need wait at least 100us */
                reg_val = 0;
                SOC_IF_ERROR_RETURN(
                    REG_WRITE_PHY_CTRLr(unit, &reg_val));
                sal_usleep(100);

                MAC_LOW_POWER_LOCK(unit);
                /* Reset the timestamp */
                SOC_CONTROL(unit)->all_link_down_detected = 0;
                MAC_LOW_POWER_UNLOCK(unit);
                
                /* Adjust the SPI freq to 20 Mhz */
#if defined(KEYSTONE)
                SPI_LOCK;
                ai_soc_spi_freq_set(NULL, DEV_BCM53101_NORMAL_SPI_FREQ);
                SPI_UNLOCK;
#endif
                
            }
            break;
        default:
            rv = SOC_E_UNAVAIL;
    }
    
    return rv;
}
Example #21
0
static void __usleep(unsigned int usec)
{
    sal_usleep(usec);
}
Example #22
0
cmd_result_t
iprocread_cmd(int unit, args_t *args)
{
    cmd_result_t rv = CMD_OK;
    parse_table_t  pt;
    char *c, *filename = NULL;
    uint32 addr = 0;
    int ce = 0;
    int len=1;
#ifndef NO_FILEIO
#ifndef NO_CTRL_C
    jmp_buf ctrl_c;
#endif
    FILE * volatile fp = NULL;
#endif

    if (ARG_CNT(args) < 1) {
        return(CMD_USAGE);
    }

    parse_table_init(unit, &pt);
    parse_table_add(&pt, "ChangeEndian", PQ_DFL|PQ_BOOL,
                    0, &ce,  NULL);
    if (parse_arg_eq(args, &pt) < 0) {
        printk("%s: Error: Unknown option: %s\n", ARG_CMD(args), ARG_CUR(args));
        parse_arg_eq_done(&pt);
        return(CMD_USAGE);
    }

    c = ARG_GET(args);
    if (!isint(c)) {
        printk("%s: Error: Address not specified\n", ARG_CMD(args));
        return(CMD_USAGE);
    }
    addr = parse_address(c);

    if (ARG_CNT(args) > 0) {
        c = ARG_GET(args);
        if (isint(c)) {
            len = parse_address(c);
            if (ARG_CNT(args) > 0) {
                filename = ARG_GET(args);
            }
        } else {
            filename = c;
        }
    }

    if (filename == NULL) {
        /* Just dump to screen */
        rv = _iproc_dump(unit, ce, NULL, addr, len);
    } else {
#ifdef NO_FILEIO
        printk("no filesystem\n");
#else
        /* Dump to file */        
  #ifndef NO_CTRL_C
        if (!setjmp(ctrl_c)) {
            sh_push_ctrl_c(&ctrl_c);
  #endif

            fp = sal_fopen(filename, "w");
            if (!fp) {
                printk("%s: Error: Unable to open file: %s\n",
                   ARG_CMD(args), filename);
                rv = CMD_FAIL;
  #ifndef NO_CTRL_C
                sh_pop_ctrl_c();
  #endif
                return(rv);
            } else {
                soc_cm_debug(DK_VERBOSE, "Dump to file %s\n", filename);
                rv = _iproc_dump(unit, ce, fp, addr, len);
                sal_fclose((FILE *)fp);
                fp = NULL;
            }

  #ifndef NO_CTRL_C
        } else if (fp) {
            sal_fclose((FILE *)fp);
            fp = NULL;
            rv = CMD_INTR;
        }

        sh_pop_ctrl_c();
  #endif
        sal_usleep(10000);
#endif /* NO_FILEIO */
    }

    return(rv);
}