コード例 #1
0
static unsigned int graes_trans(struct graes_priv *pDev, struct graes_block *curr_frm, unsigned int addr_in ) {
	unsigned int addr = addr_in;
	/* Prepare descriptor address. Three cases:
	 *  - GRAES core on same bus as CPU ==> no translation (Address used by CPU = address used by GRAES)
	 *  - GRAES core on remote bus, and payload address given as used by CPU ==> Translation needed
	 *  - GRAES core on remote bus, and payload address given as used by GRAES ==> no translation  [ USER does custom translation]
	 */
	if ( curr_frm->flags & (GRAES_FLAGS_TRANSLATE|GRAES_FLAGS_TRANSLATE_AND_REMEMBER) ) {
		/* Do translation */
		drvmgr_translate(pDev->dev, CPUMEM_TO_DMA, (void *)addr_in, (void **)&addr);
		if ( curr_frm->flags & GRAES_FLAGS_TRANSLATE_AND_REMEMBER ) {
			if ( addr_in != addr ) {
				/* Translation needed */
				curr_frm->flags &= ~GRAES_FLAGS_TRANSLATE_AND_REMEMBER;
				curr_frm->flags |= GRAES_FLAGS_TRANSLATE;
			} else {
				/* No Trnaslation needed */
				curr_frm->flags &= ~(GRAES_FLAGS_TRANSLATE|GRAES_FLAGS_TRANSLATE_AND_REMEMBER);
			}
		}
	} else {
		/* Custom translation or no translation needed */
		addr = (unsigned int)addr_in;
	}
	return addr;
}
コード例 #2
0
/* Calls drvmgr_translate() to translate an address range and check the result,
 * a printout is generated if the check fails. See paramters of
 * drvmgr_translate().
 * If size=0 only the starting address is not checked.
 */
int drvmgr_translate_check(
	struct drvmgr_dev *dev,
	unsigned int options,
	void *src_address,
	void **dst_address,
	unsigned int size)
{
	unsigned int max;

	max = drvmgr_translate(dev, options, src_address, dst_address);
	if (max == 0 || (max < size && (size != 0))) {
		printk(" ### dev %p (%s) failed mapping %p\n",
			dev, dev->name ? dev->name : "unnamed", src_address);
		return -1;
	}

	return 0;
}
コード例 #3
0
/* Moves as many frames in the ready queue (as there are free descriptors for)
 * to the scheduled queue. The free descriptors are then assigned one frame
 * each and enabled for transmission.
 * 
 * Return Value
 * Returns number of frames moved from ready to scheduled queue 
 */
static int graes_schedule_ready(struct graes_priv *pDev, int ints_off)
{
	int cnt;
	unsigned int ctrl, dmactrl, oldLevel, addr;
	struct graes_ring *curr_bd;
	struct graes_block *curr_frm, *last_frm;

	if ( !pDev->ready.head ){
		return 0;
	}

	cnt=0;
	curr_frm = pDev->ready.head;
	curr_bd = pDev->ring;
	while( !curr_bd->frm ){
		int i = 0, j; unsigned int kaddr = -1, iaddr = -1, oaddr = -1, daddr, naddr;
		/* Assign frame to descriptor */
		curr_bd->frm = curr_frm;

		/* Prepare descriptor address. Three cases:
		 *  - GRAES core on same bus as CPU ==> no translation (Address used by CPU = address used by GRAES)
		 *  - GRAES core on remote bus, and payload address given as used by CPU ==> Translation needed
		 *  - GRAES core on remote bus, and payload address given as used by GRAES ==> no translation  [ USER does custom translation]
		 */
		
		ctrl = GRAES_BD_EN;
		
		daddr = addr = graes_trans(pDev, curr_frm, curr_frm->payload);
		curr_bd->bd->u.d[i++] = addr;
			
		if (curr_frm->out) {
			ctrl |= GRAES_BD_OUT;
			oaddr = addr = graes_trans(pDev, curr_frm, curr_frm->out);
			curr_bd->bd->u.d[i++] = addr;
		}
		if (curr_frm->iv) {
			ctrl |= GRAES_BD_IV;
			iaddr = addr = graes_trans(pDev, curr_frm, curr_frm->iv);
			curr_bd->bd->u.d[i++] = addr;
		}
		if (curr_frm->key) {
			ctrl |= GRAES_BD_KEY;
			kaddr = addr = graes_trans(pDev, curr_frm, curr_frm->key);
			curr_bd->bd->u.d[i++] = addr;
		}

		drvmgr_translate(pDev->dev, CPUMEM_TO_DMA, (void *)curr_bd->next->bd, (void **)&naddr);
		curr_bd->bd->u.d[i++] = naddr;

		if ( curr_bd->next == pDev->_ring ){
			
			/* Wrap around */
		}

		ctrl |= ((curr_frm->length & 0x7ff) << 21);
		
		/* Apply user options/flags */
		ctrl |= (curr_frm->flags & GRAES_FLAGS_MASK);
		
		/* Is this Frame going to be an interrupt Frame? */
		if ( (--pDev->enable_cnt_curr) <= 0 ){
			if ( pDev->config.enable_cnt == 0 ){
				pDev->enable_cnt_curr = 0x3fffffff;
			}else{
				pDev->enable_cnt_curr = pDev->config.enable_cnt;
				ctrl |= GRAES_BD_IE;
			}
		}

		/* Enable descriptor */
		curr_bd->bd->ctrl = ctrl;

#ifdef DEBUG
		printk(" add bd: 0x%08x @ 0x%08x [0x%08x",ctrl,curr_bd->bd, daddr);
		if(oaddr != -1)
			printk(",o:0x%08x",oaddr);
		if(iaddr != -1)
			printk(",i:0x%08x",iaddr);
		if(kaddr != -1)
			printk(",k:0x%08x",kaddr);
		printk("] [");
		for (j = 0; j < 6; j++) {
			printk(" 0x%08x",((unsigned int *)curr_bd->bd)[j]);
		}
		printk("]\n");
		
#endif
		
		last_frm = curr_frm;
		curr_bd = curr_bd->next;
		cnt++;
		
		/* Get Next Frame from Ready Queue */
		if ( curr_frm == pDev->ready.tail ){
			/* Handled all in ready queue. */
			curr_frm = NULL;
			break;
		}
		curr_frm = curr_frm->next;
	}
	
	/* Has frames have been scheduled? */
	if ( cnt > 0 ){
		/* Make last frame mark end of chain, probably pointless... */
		last_frm->next = NULL;

		/* Insert scheduled packets into scheduled queue */
		if ( !pDev->scheduled.head ){
			/* empty scheduled queue */
			pDev->scheduled.head = pDev->ready.head;
			pDev->scheduled.tail = last_frm;
		}else{
			pDev->scheduled.tail->next = pDev->ready.head;
			pDev->scheduled.tail = last_frm;
		}

		/* Remove scheduled packets from ready queue */
		pDev->ready.head = curr_frm;
		if ( !curr_frm ){
			pDev->ready.tail = NULL;
		}

		/* Update TX ring posistion */
		pDev->ring = curr_bd;
		if ( !ints_off ) {
			IRQ_GLOBAL_DISABLE(oldLevel);
		}

		/* Make hardware aware of the newly enabled descriptors */
		dmactrl = READ_REG(&pDev->regs->dma_ctrl);
		dmactrl |= GRAES_DMA_CTRL_EN;
		pDev->regs->dma_ctrl = dmactrl;
		
		if ( !ints_off ) {
			IRQ_GLOBAL_ENABLE(oldLevel);
		}
	}
	return cnt;
}
コード例 #4
0
ファイル: grtm.c プロジェクト: gedare/rtems
/* Moves as many frames in the ready queue (as there are free descriptors for)
 * to the scheduled queue. The free descriptors are then assigned one frame
 * each and enabled for transmission.
 * 
 * Return Value
 * Returns number of frames moved from ready to scheduled queue 
 */
static int grtm_schedule_ready(struct grtm_priv *pDev)
{
	int cnt;
	unsigned int ctrl, dmactrl;
	struct grtm_ring *curr_bd;
	struct grtm_frame *curr_frm, *last_frm;

	if ( !pDev->ready.head ){
		return 0;
	}

	cnt=0;
	curr_frm = pDev->ready.head;
	curr_bd = pDev->ring;
	while( !curr_bd->frm ){
		/* Assign frame to descriptor */
		curr_bd->frm = curr_frm;

		/* Prepare descriptor address. Three cases:
		 *  - GRTM core on same bus as CPU ==> no translation (Address used by CPU = address used by GRTM)
		 *  - GRTM core on remote bus, and payload address given as used by CPU ==> Translation needed
		 *  - GRTM core on remote bus, and payload address given as used by GRTM ==> no translation  [ USER does custom translation]
		 */
		if ( curr_frm->flags & (GRTM_FLAGS_TRANSLATE|GRTM_FLAGS_TRANSLATE_AND_REMEMBER) ) {
			/* Do translation */
			drvmgr_translate(pDev->dev, CPUMEM_TO_DMA, (void *)curr_frm->payload, (void **)&curr_bd->bd->address);
			if ( curr_frm->flags & GRTM_FLAGS_TRANSLATE_AND_REMEMBER ) {
				if ( curr_frm->payload != (unsigned int *)curr_bd->bd->address ) {
					/* Translation needed */
					curr_frm->flags &= ~GRTM_FLAGS_TRANSLATE_AND_REMEMBER;
					curr_frm->flags |= GRTM_FLAGS_TRANSLATE;
				} else {
					/* No Trnaslation needed */
					curr_frm->flags &= ~(GRTM_FLAGS_TRANSLATE|GRTM_FLAGS_TRANSLATE_AND_REMEMBER);
				}
			}
		} else {
			/* Custom translation or no translation needed */
			curr_bd->bd->address = (unsigned int)curr_frm->payload;
		}

		ctrl = GRTM_BD_EN;
		if ( curr_bd->next == pDev->_ring ){
			ctrl |= GRTM_BD_WR; /* Wrap around */
		}
		/* Apply user options/flags */
		ctrl |= (curr_frm->flags & GRTM_FLAGS_MASK);

		/* Is this Frame going to be an interrupt Frame? */
		if ( (--pDev->enable_cnt_curr) <= 0 ){
			if ( pDev->config.enable_cnt == 0 ){
				pDev->enable_cnt_curr = 0x3fffffff;
			}else{
				pDev->enable_cnt_curr = pDev->config.enable_cnt;
				ctrl |= GRTM_BD_IE;
			}
		}

		/* Enable descriptor */
		curr_bd->bd->ctrl = ctrl;

		last_frm = curr_frm;
		curr_bd = curr_bd->next;
		cnt++;
		
		/* Get Next Frame from Ready Queue */
		if ( curr_frm == pDev->ready.tail ){
			/* Handled all in ready queue. */
			curr_frm = NULL;
			break;
		}
		curr_frm = curr_frm->next;
	}
	
	/* Has frames have been scheduled? */
	if ( cnt > 0 ){
		/* Make last frame mark end of chain, probably pointless... */
		last_frm->next = NULL;

		/* Insert scheduled packets into scheduled queue */
		if ( !pDev->scheduled.head ){
			/* empty scheduled queue */
			pDev->scheduled.head = pDev->ready.head;
			pDev->scheduled.tail = last_frm;
		}else{
			pDev->scheduled.tail->next = pDev->ready.head;
			pDev->scheduled.tail = last_frm;
		}

		/* Remove scheduled packets from ready queue */
		pDev->ready.head = curr_frm;
		if ( !curr_frm ){
			pDev->ready.tail = NULL;
		}

		/* Update TX ring posistion */
		pDev->ring = curr_bd;

		/* Make hardware aware of the newly enabled descriptors */
		dmactrl = READ_REG(&pDev->regs->dma_ctrl);
		dmactrl &= ~(GRTM_DMA_CTRL_TXRST | GRTM_DMA_CTRL_RST);
		dmactrl |= GRTM_DMA_CTRL_EN;
		pDev->regs->dma_ctrl = dmactrl;
	}

	return cnt;
}