コード例 #1
0
ファイル: dma_lib.c プロジェクト: 325116067/semc-qsd8x50
int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan)
{
	int reg, retries;
	u32 sta;

	if (chan->chan_type == RXCHAN) {
		reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno);
		pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST);
		for (retries = 0; retries < MAX_RETRIES; retries++) {
			sta = pasemi_read_dma_reg(reg);
			if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
				pasemi_write_dma_reg(reg, 0);
				return 1;
			}
			cond_resched();
		}
	} else {
		reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno);
		pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST);
		for (retries = 0; retries < MAX_RETRIES; retries++) {
			sta = pasemi_read_dma_reg(reg);
			if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
				pasemi_write_dma_reg(reg, 0);
				return 1;
			}
			cond_resched();
		}
	}

	return 0;
}
コード例 #2
0
ファイル: dma_lib.c プロジェクト: 325116067/semc-qsd8x50
/* pasemi_dma_start_chan - Start a DMA channel
 * @chan: Channel to start
 * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write
 *
 * Enables (starts) a DMA channel with optional additional arguments.
 */
void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta)
{
	if (chan->chan_type == RXCHAN)
		pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno),
				     cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN);
	else
		pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno),
				     cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN);
}
コード例 #3
0
ファイル: pasemi.c プロジェクト: Noltari/uboot-lantiq-2010_03
static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
{
	struct pasemi_fnu_txring *ring = &sc->tx[chan];
	int chan_index = chan + sc->base_chan;
	int retries;
	u32 stat;

	/* Stop the channel */
	out_le32(sc->dma_regs +
		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),
		 PAS_DMA_TXCHAN_TCMDSTA_ST);

	for (retries = 0; retries < MAX_RETRIES; retries++) {
		stat = in_le32(sc->dma_regs +
			       PAS_DMA_TXCHAN_TCMDSTA(chan_index));
		if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
			break;
		cond_resched();
	}

	if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
		dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
			chan_index);

	/* Disable the channel */
	out_le32(sc->dma_regs +
		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),
		 0);

	if (ring->desc_info)
		kfree((void *) ring->desc_info);
	if (ring->desc)
		dma_free_coherent(&sc->dma_pdev->dev,
				  TX_RING_SIZE *
				  2 * sizeof(u64),
				  (void *) ring->desc, ring->dma);
	if (ring->irq != -1)
		free_irq(ring->irq, sc);

	del_timer(&ring->crypto_timer);
}
コード例 #4
0
ファイル: pasemi.c プロジェクト: Noltari/uboot-lantiq-2010_03
static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
{
	u32 val;
	int chan_index = chan + sc->base_chan;
	int ret;
	struct pasemi_fnu_txring *ring;

	ring = &sc->tx[chan];

	spin_lock_init(&ring->fill_lock);
	spin_lock_init(&ring->clean_lock);

	ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
				  TX_RING_SIZE, GFP_KERNEL);
	if (!ring->desc_info)
		return -ENOMEM;

	/* Allocate descriptors */
	ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
					TX_RING_SIZE *
					2 * sizeof(u64),
					&ring->dma, GFP_KERNEL);
	if (!ring->desc)
		return -ENOMEM;

	memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));

	out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);

	ring->total_pktcnt = 0;

	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
		 PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));

	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);

	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);

	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
		 PAS_DMA_TXCHAN_CFG_TY_FUNC |
		 PAS_DMA_TXCHAN_CFG_TATTR(chan) |
		 PAS_DMA_TXCHAN_CFG_WT(2));

	/* enable tx channel */
	out_le32(sc->dma_regs +
		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),
		 PAS_DMA_TXCHAN_TCMDSTA_EN);

	out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
		 PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));

	ring->next_to_fill = 0;
	ring->next_to_clean = 0;

	snprintf(ring->irq_name, sizeof(ring->irq_name),
		 "%s%d", "crypto", chan);

	ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
	ret = request_irq(ring->irq, (irq_handler_t)
			  pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
	if (ret) {
		printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
		       ring->irq, ret);
		ring->irq = -1;
		return ret;
	}

	setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);

	return 0;
}