/** Transmit packet over DMA, which comes from the Tx Queue */ static int ifx_start_xmit(struct sk_buff *skb, struct net_device *dev) { IFX_switch_priv_t *priv = ifx_eth_fw_netdev_priv(dev); int len , rc = NETDEV_TX_OK; char *data; struct dma_device_info* dma_dev=g_dma_device; len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; data = skb->data; priv->skb = skb; dev->trans_start = jiffies; /*select the tx channel*/ dma_dev->current_tx_chan = ifx_select_tx_chan (skb, dev); if (dma_device_write(dma_dev, data, len, skb) != len ) { if (skb) dev_kfree_skb_any(skb); priv->stats.tx_errors++; priv->stats.tx_dropped++; /* rc = NETDEV_TX_BUSY; */ } else { priv->stats.tx_packets++; priv->stats.tx_bytes+=len; } return rc; }
int ifxmips_mii_hw_tx(char *buf, int len, struct net_device *dev) { int ret = 0; struct ifxmips_mii_priv *priv = dev->priv; struct dma_device_info *dma_dev = priv->dma_device; ret = dma_device_write(dma_dev, buf, len, priv->skb); return ret; }
static void md5_transform(u32 *hash, u32 const *in) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int i = 0; volatile register u32 tmp; unsigned long flag; #ifndef ONLY_IN_MEM volatile struct deu_hash_t *hashs = (struct hash_t *) HASH_START; volatile struct deu_dma_t *dma = (struct deu_dma_t *) DMA_CON; #else unsigned char *prin = NULL; struct deu_hash_t *hashs = NULL; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ hashs = (struct deu_hash_t *) kmalloc(sizeof(*hashs), GFP_KERNEL); memset(hashs, 0, sizeof(*hashs)); prin = (unsigned char *) hashs; #endif //printk("md5_transform running\n"); local_irq_save(flag); #ifndef CONFIG_CRYPTO_DEV_DANUBE_DMA //dma or not asm("sync"); for(i = 0; i < 16; i++) { #ifdef DEBUG_MD5 //printk("%u:%x ",i,in[i]); printk("%u:%x\n", i, cpu_to_le32(in[i])); #endif //DEBUG_MD5 hashs->MR = cpu_to_le32(in[i]); asm("sync"); }; //wait for processing while(hashs->controlr.BSY) { // this will not take long } #else //dma /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ struct dma_device_info *dma_device = ifx_deu[0].dma_device; _ifx_deu_device *pDev = ifx_deu; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ pDev->len = sizeof(in); pDev->src = in; *DANUBE_DMA_PS = 1; *DANUBE_DMA_PCTRL |= (0x3 << 10); //byte swapping while(dma->controlr.BSY) { // this will not take long } dma_device_write(dma_device, (u8 *) in, 64, NULL); udelay(10); while(dma->controlr.BSY) { // this will not take long } *DANUBE_DMA_PS = 1; *DANUBE_DMA_PCTRL &= ~(0x3 << 10); //byte swapping deactivate #endif local_irq_restore(flag); }
/*! \fn void ifx_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode) * \ingroup IFX_AES_FUNCTIONS * \brief main interface to AES hardware * \param ctx_arg crypto algo context * \param out_arg output bytestream * \param in_arg input bytestream * \param iv_arg initialization vector * \param nbytes length of bytestream * \param encdec 1 for encrypt; 0 for decrypt * \param mode operation mode such as ebc, cbc, ctr * */ void ifx_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode) #endif { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg; u32 *in_key = ctx->buf; unsigned long flag; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int key_len = ctx->key_length; #ifndef CONFIG_CRYPTO_DEV_DMA int i = 0; int byte_cnt = nbytes; #else volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; struct dma_device_info *dma_device = ifx_deu[0].dma_device; //deu_drv_priv_t *deu_priv = (deu_drv_priv_t *)dma_device->priv; int wlen = 0; u32 *outcopy = NULL; u32 *dword_mem_aligned_in = NULL; #ifdef CONFIG_CRYPTO_DEV_POLL_DMA u32 timeout = 0; u32 *out_dma = NULL; #endif #endif CRTCL_SECT_START; /* 128, 192 or 256 bit key length */ aes->controlr.K = key_len / 8 - 2; if (key_len == 128 / 8) { aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); } else if (key_len == 192 / 8) { aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5)); } else if (key_len == 256 / 8) { aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7)); } else { printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len); CRTCL_SECT_END; return;// -EINVAL; } /* let HW pre-process DEcryption key in any case (even if ENcryption is used). Key Valid (KV) bit is then only checked in decryption routine! */ aes->controlr.PNK = 1; #ifdef CONFIG_CRYPTO_DEV_DMA while (aes->controlr.BUS) { // this will not take long } AES_DMA_MISC_CONFIG(); #endif aes->controlr.E_D = !encdec; //encryption aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps if (mode > 0) { aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg); aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1)); aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2)); aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3)); }; #ifndef CONFIG_CRYPTO_DEV_DMA i = 0; while (byte_cnt >= 16) { aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 0)); aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 1)); aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 2)); aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 3)); /* start crypto */ while (aes->controlr.BUS) { // this will not take long } *((volatile u32 *) out_arg + (i * 4) + 0) = aes->OD3R; *((volatile u32 *) out_arg + (i * 4) + 1) = aes->OD2R; *((volatile u32 *) out_arg + (i * 4) + 2) = aes->OD1R; *((volatile u32 *) out_arg + (i * 4) + 3) = aes->OD0R; i++; byte_cnt -= 16; } #else // dma /* memory alignment issue */ dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, aes_buff_in, BUFFER_IN, nbytes); dma->controlr.ALGO = 1; //AES dma->controlr.BS = 0; aes->controlr.DAU = 0; dma->controlr.EN = 1; while (aes->controlr.BUS) { // wait for AES to be ready }; wlen = dma_device_write (dma_device, (u8 *)dword_mem_aligned_in, nbytes, NULL); if (wlen != nbytes) { dma->controlr.EN = 0; CRTCL_SECT_END; printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__); return; // -EINVAL; } WAIT_AES_DMA_READY(); outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, aes_buff_out, BUFFER_OUT, nbytes); #ifdef CONFIG_CRYPTO_DEV_POLL_DMA // polling DMA rx channel while ((dma_device_read (dma_device, (u8 **) &out_dma, NULL)) == 0) { timeout++; if (timeout >= 333000) { dma->controlr.EN = 0; CRTCL_SECT_END; printk (KERN_ERR "[%s %s %d]: timeout!!\n", __FILE__, __func__, __LINE__); return; // -EINVAL; } } WAIT_AES_DMA_READY(); AES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes); #else /* Prepare Rx buf length used in dma psuedo interrupt */ deu_priv->deu_rx_buf = out_arg; deu_priv->outcopy = outcopy; deu_priv->deu_rx_len = nbytes; CRTCL_SECT_END; /* Sleep and wait for Rx finished */ DEU_WAIT_EVENT(deu_priv->deu_thread_wait, DEU_EVENT, deu_priv->deu_event_flags); CRTCL_SECT_START; #endif #endif // dma //tc.chen : copy iv_arg back if (mode > 0) { *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg)); *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1)); *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2)); *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3)); } CRTCL_SECT_END; }
static int lq_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg; u32 *in_key = ctx->buf; unsigned long flag; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int key_len = ctx->key_length; volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; struct dma_device_info *dma_device = ifx_deu[0].dma_device; deu_drv_priv_t *deu_priv = (deu_drv_priv_t *)dma_device->priv; int wlen = 0; //u32 *outcopy = NULL; u32 *dword_mem_aligned_in = NULL; CRTCL_SECT_START; /* 128, 192 or 256 bit key length */ aes->controlr.K = key_len / 8 - 2; if (key_len == 128 / 8) { aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); } else if (key_len == 192 / 8) { aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5)); } else if (key_len == 256 / 8) { aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0)); aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1)); aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2)); aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3)); aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4)); aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5)); aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6)); aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7)); } else { printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len); CRTCL_SECT_END; return -EINVAL; } /* let HW pre-process DEcryption key in any case (even if ENcryption is used). Key Valid (KV) bit is then only checked in decryption routine! */ aes->controlr.PNK = 1; while (aes->controlr.BUS) { // this will not take long } AES_DMA_MISC_CONFIG(); aes->controlr.E_D = !encdec; //encryption aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps if (mode > 0) { aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg); aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1)); aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2)); aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3)); }; /* Prepare Rx buf length used in dma psuedo interrupt */ deu_priv->deu_rx_buf = (u32 *)out_arg; deu_priv->deu_rx_len = nbytes; /* memory alignment issue */ dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, aes_buff_in, BUFFER_IN, nbytes); dma->controlr.ALGO = 1; //AES dma->controlr.BS = 0; aes->controlr.DAU = 0; dma->controlr.EN = 1; while (aes->controlr.BUS) { // wait for AES to be ready }; deu_priv->outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, aes_buff_out, BUFFER_OUT, nbytes); deu_priv->event_src = AES_ASYNC_EVENT; wlen = dma_device_write (dma_device, (u8 *)dword_mem_aligned_in, nbytes, NULL); if (wlen != nbytes) { dma->controlr.EN = 0; CRTCL_SECT_END; printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__); return -EINVAL; } // WAIT_AES_DMA_READY(); CRTCL_SECT_END; if (mode > 0) { *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg)); *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1)); *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2)); *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3)); } return -EINPROGRESS; }