示例#1
0
/*
 * Decode an incoming frame coming from the switch
 */
static int
ngfrm_decode(node_p node, item_p item)
{
	const sc_p  sc = NG_NODE_PRIVATE(node);
	char       *data;
	int         alen;
	u_int	    dlci = 0;
	int	    error = 0;
	int	    ctxnum;
	struct mbuf *m;

	NGI_GET_M(item, m);
	if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) {
		error = ENOBUFS;
		goto out;
	}
	data = mtod(m, char *);
	if ((alen = sc->addrlen) == 0) {
		sc->addrlen = alen = ngfrm_addrlen(data);
	}
	switch (alen) {
	case 2:
		SHIFTIN(makeup + 0, data[0], dlci);
		SHIFTIN(makeup + 1, data[1], dlci);
		break;
	case 3:
		SHIFTIN(makeup + 0, data[0], dlci);
		SHIFTIN(makeup + 1, data[1], dlci);
		SHIFTIN(makeup + 3, data[2], dlci);	/* 3 and 2 is correct */
		break;
	case 4:
		SHIFTIN(makeup + 0, data[0], dlci);
		SHIFTIN(makeup + 1, data[1], dlci);
		SHIFTIN(makeup + 2, data[2], dlci);
		SHIFTIN(makeup + 3, data[3], dlci);
		break;
	default:
		error = EINVAL;
		goto out;
	}

	if (dlci > 1023) {
		error = EINVAL;
		goto out;
	}
	ctxnum = sc->ALT[dlci];
	if ((ctxnum & CTX_VALID) && sc->channel[ctxnum &= CTX_VALUE].hook) {
		/* Send it */
		m_adj(m, alen);
		NG_FWD_NEW_DATA(error, item, sc->channel[ctxnum].hook, m);
		return (error);
	} else {
		error = ENETDOWN;
	}
out:
	NG_FREE_ITEM(item);
	NG_FREE_M(m);
	return (error);
}
int
a10_clk_sata_activate(void)
{
	struct a10_ccm_softc *sc = a10_ccm_sc;
	uint32_t ocfg, ncfg;
	int k;

	if (sc == NULL)
		return (ENXIO);

	/*
	 * SATA needs PLL6 to be a 100MHz clock.
	 */
	ocfg = ccm_read_4(sc, CCM_PLL6_CFG);
	k = SHIFTOUT(ocfg, CCM_PLL_CFG_FACTOR_K);

	/*
	 * Output freq is 24MHz * n * k / m / 6.
	 * To get to 100MHz, k & m must be equal and n must be 25.
	 */
	ncfg = ocfg;
	ncfg &= ~(CCM_PLL_CFG_FACTOR_M | CCM_PLL_CFG_FACTOR_N);
	ncfg &= ~(CCM_PLL_CFG_BYPASS);

	ncfg |= SHIFTIN(k, CCM_PLL_CFG_FACTOR_M);
	ncfg |= SHIFTIN(25, CCM_PLL_CFG_FACTOR_N);

	ncfg |= CCM_PLL_CFG_ENABLE | CCM_PLL6_CFG_SATA_CLK_EN;
	if (ncfg != ocfg)
		ccm_write_4(sc, CCM_PLL6_CFG, ncfg);

	/*
	 * Make sure it's enabled for the AHB.
	 */
	ncfg = ccm_read_4(sc, CCM_AHB_GATING0);
	ncfg |= CCM_AHB_GATING_SATA;
	ccm_write_4(sc, CCM_AHB_GATING0, ncfg);
	DELAY(1000);

	/*
	 * Now turn it on (forcing it to use PLL6).
	 */
	ccm_write_4(sc, CCM_SATA_CLK, CCM_CLK_ENABLE);

	return (0);
}