Fwd: crypto accelerator driver problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

As some good news and additional information, with the following patch
I no more get
"UDP bad cheksum" error as I mentioned erlier with Iperf in udp mode.
But some times I get the following call trace in dmesg after running
Iperf in UDP mode, more than one time (and ofcourse Iperf stops
transferring data while it uses 100% of CPU cycles.



[  130.171909] mydriver-aes: mydriver Crypto-Engine enabled.
[  134.767846] NET: Registered protocol family 15
[  200.031846] iperf: page allocation failure. order:0, mode:0x20
[  200.031850] Pid: 10935, comm: iperf Tainted: P            2.6.36-zen1 #1
[  200.031852] Call Trace:
[  200.031860]  [<ffffffff8108ab39>] ? __alloc_pages_nodemask+0x6d3/0x722
[  200.031864]  [<ffffffff810b454f>] ? virt_to_head_page+0x9/0x30
[  200.031867]  [<ffffffff810afac2>] ? alloc_pages_current+0xa5/0xce
[  200.031869]  [<ffffffff810899ad>] ? __get_free_pages+0x9/0x46
[  200.031872]  [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23
[  200.031876]  [<ffffffff811a10ad>] ? blkcipher_walk_next+0x68/0x2d9
[  200.031882]  [<ffffffffa001dad4>] ? mydriver_cbc_encrypt+0x47/0x9c
[mydriver_aes2]
[  200.031886]  [<ffffffff81454789>] ? ipt_do_table+0x5d8/0x619
[  200.031888]  [<ffffffff811a0871>] ? async_encrypt+0x35/0x3a
[  200.031891]  [<ffffffff811a1e0c>] ? eseqiv_givencrypt+0x341/0x389
[  200.031894]  [<ffffffff813b8bb5>] ? __skb_to_sgvec+0x49/0x1ea
[  200.031897]  [<ffffffff813b8d1e>] ? __skb_to_sgvec+0x1b2/0x1ea
[  200.031899]  [<ffffffff811a8fc8>] ? crypto_authenc_givencrypt+0x60/0x7c
[  200.031902]  [<ffffffff814492dd>] ? esp_output+0x320/0x357
[  200.031905]  [<ffffffff814658cd>] ? xfrm_output_resume+0x38d/0x48f
[  200.031908]  [<ffffffff813e1f62>] ? nf_hook_slow+0xc8/0xd9
[  200.031911]  [<ffffffff81416f9f>] ? ip_push_pending_frames+0x2cc/0x328
[  200.031914]  [<ffffffff8143339e>] ? udp_push_pending_frames+0x2c4/0x342
[  200.031917]  [<ffffffff814350ca>] ? udp_sendmsg+0x508/0x600
[  200.031919]  [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23
[  200.031923]  [<ffffffff813b3458>] ? sock_aio_write+0xd5/0xe9
[  200.031926]  [<ffffffff8100340e>] ? apic_timer_interrupt+0xe/0x20
[  200.031928]  [<ffffffff810ba2ea>] ? do_sync_write+0xb0/0xf2
[  200.031931]  [<ffffffff8100864b>] ? sched_clock+0x5/0x8
[  200.031934]  [<ffffffff8119c550>] ? security_file_permission+0x18/0x67
[  200.031937]  [<ffffffff810bac07>] ? vfs_write+0xbc/0x101
[  200.031939]  [<ffffffff810bad08>] ? sys_write+0x45/0x6e
[  200.031941]  [<ffffffff81002a42>] ? system_call_fastpath+0x16/0x1b
[  200.031942] Mem-Info:
[  200.031944] Node 0 DMA per-cpu:
[  200.031946] CPU    0: hi:    0, btch:   1 usd:   0
[  200.031947] CPU    1: hi:    0, btch:   1 usd:   0
[  200.031949] CPU    2: hi:    0, btch:   1 usd:   0
[  200.031950] CPU    3: hi:    0, btch:   1 usd:   0
[  200.031951] Node 0 DMA32 per-cpu:
[  200.031953] CPU    0: hi:  186, btch:  31 usd:  30
[  200.032016] CPU    1: hi:  186, btch:  31 usd:  23
[  200.032018] CPU    2: hi:  186, btch:  31 usd: 182
[  200.032019] CPU    3: hi:  186, btch:  31 usd: 171
[  200.032023] active_anon:248219 inactive_anon:82742 isolated_anon:7
[  200.032024]  active_file:10553 inactive_file:11106 isolated_file:27
[  200.032025]  unevictable:0 dirty:19 writeback:1881 unstable:0
[  200.032026]  free:2536 slab_reclaimable:2970 slab_unreclaimable:6490
[  200.032026]  mapped:19597 shmem:292 pagetables:12316 bounce:0
[  200.032028] Node 0 DMA free:8012kB min:40kB low:48kB high:60kB
active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB
unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15768kB
mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB
slab_reclaimable:0kB slab_unreclaimable:16kB kernel_stack:0kB
pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB
pages_scanned:0 all_unreclaimable? yes
[  200.032036] lowmem_reserve[]: 0 2002 2002 2002
[  200.032039] Node 0 DMA32 free:2132kB min:5704kB low:7128kB
high:8556kB active_anon:992876kB inactive_anon:330968kB
active_file:42212kB inactive_file:44424kB unevictable:0kB
isolated(anon):28kB isolated(file):108kB present:2050992kB mlocked:0kB
dirty:76kB writeback:7524kB mapped:78388kB shmem:1168kB
slab_reclaimable:11880kB slab_unreclaimable:25944kB
kernel_stack:2320kB pagetables:49264kB unstable:0kB bounce:0kB
writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[  200.032050] lowmem_reserve[]: 0 0 0 0
[  200.032059] Node 0 DMA: 1*4kB 1*8kB 0*16kB 0*32kB 1*64kB 0*128kB
1*256kB 1*512kB 1*1024kB 1*2048kB 1*4096kB = 8012kB
[  200.032066] Node 0 DMA32: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 0*128kB
0*256kB 0*512kB 0*1024kB 1*2048kB 0*4096kB = 2132kB
[  200.032072] 37527 total pagecache pages
[  200.032074] 15549 pages in swap cache
[  200.032075] Swap cache stats: add 72816, delete 57267, find 8267/8477
[  200.032076] Free swap  = 3832196kB
[  200.032078] Total swap = 4096568kB
[  200.040499] 523951 pages RAM
[  200.040501] 9684 pages reserved
[  200.040502] 231120 pages shared
[  200.040503] 486710 pages non-shared
[  200.040514] BUG: unable to handle kernel NULL pointer dereference at (null)
[  200.040517] IP: [<ffffffffa001d395>] mydriver_transform+0x1a3/0x6a8
[mydriver_aes2]
[  200.040523] PGD 7c3dd067 PUD 41dc067 PMD 0
[  200.040526] Oops: 0000 [#1] PREEMPT SMP
[  200.040528] last sysfs file: /sys/devices/virtual/misc/fuse/dev
[  200.040530] CPU 0
[  200.040531] Modules linked in: ctr twofish_generic twofish_x86_64
twofish_common camellia serpent blowfish cast5 xcbc rmd160
sha512_generic sha256_generic crypto_null af_key mydriver_aes2 fuse
nvidia(P) r8169 iTCO_wdt iTCO_vendor_support
[  200.040542]
[  200.040544] Pid: 10935, comm: iperf Tainted: P
2.6.36-zen1 #1 EP45-UD3P/EP45-UD3P
[  200.040546] RIP: 0010:[<ffffffffa001d395>]  [<ffffffffa001d395>]
mydriver_transform+0x1a3/0x6a8 [mydriver_aes2]
[  200.040550] RSP: 0018:ffff880072c5b898  EFLAGS: 00010246
[  200.040551] RAX: ffff880055a3a030 RBX: 0000000000000680 RCX: 00000000000005f0
[  200.040553] RDX: 0000000000000680 RSI: 0000000000000000 RDI: ffff880055a3a030
[  200.040555] RBP: 0000000000000000 R08: 0000000000000680 R09: 0000000000000018
[  200.040556] R10: 000000007d078004 R11: 0000000000013234 R12: 0000000000000010
[  200.040558] R13: 0000000000000004 R14: 00000000eaef0000 R15: 00000000000005f0
[  200.040561] FS:  0000000041767950(0063) GS:ffff880001a00000(0000)
knlGS:0000000000000000
[  200.040562] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  200.040564] CR2: 0000000000000000 CR3: 000000007409d000 CR4: 00000000000406f0
[  200.040566] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  200.040568] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  200.040570] Process iperf (pid: 10935, threadinfo ffff880072c5a000,
task ffff880006d09000)
[  200.040571] Stack:
[  200.040572]  ffff880006d09000 0000000000000000 ffffffff817854f0
0000000000000020
[  200.040574] <0> 0000000000000000 0000efea72c5b9e8 ffff88007d4a7c58
00000001810afac2
[  200.040577] <0> 0000000000000000 ffff88004d53dc00 ffff880072c5b901
000000000000000f
[  200.040580] Call Trace:
[  200.040585]  [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23
[  200.040588]  [<ffffffffa001db0b>] ? mydriver_cbc_encrypt+0x7e/0x9c
[mydriver_aes2]
[  200.040592]  [<ffffffff811a0871>] ? async_encrypt+0x35/0x3a
[  200.040595]  [<ffffffff811a1e0c>] ? eseqiv_givencrypt+0x341/0x389
[  200.040598]  [<ffffffff813b8bb5>] ? __skb_to_sgvec+0x49/0x1ea
[  200.040600]  [<ffffffff813b8d1e>] ? __skb_to_sgvec+0x1b2/0x1ea
[  200.040603]  [<ffffffff811a8fc8>] ? crypto_authenc_givencrypt+0x60/0x7c
[  200.040607]  [<ffffffff814492dd>] ? esp_output+0x320/0x357
[  200.040610]  [<ffffffff814658cd>] ? xfrm_output_resume+0x38d/0x48f
[  200.040613]  [<ffffffff813e1f62>] ? nf_hook_slow+0xc8/0xd9
[  200.040616]  [<ffffffff81416f9f>] ? ip_push_pending_frames+0x2cc/0x328
[  200.040619]  [<ffffffff8143339e>] ? udp_push_pending_frames+0x2c4/0x342
[  200.040621]  [<ffffffff814350ca>] ? udp_sendmsg+0x508/0x600
[  200.040623]  [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23
[  200.040627]  [<ffffffff813b3458>] ? sock_aio_write+0xd5/0xe9
[  200.040630]  [<ffffffff8100340e>] ? apic_timer_interrupt+0xe/0x20
[  200.040633]  [<ffffffff810ba2ea>] ? do_sync_write+0xb0/0xf2
[  200.040636]  [<ffffffff8100864b>] ? sched_clock+0x5/0x8
[  200.040639]  [<ffffffff8119c550>] ? security_file_permission+0x18/0x67
[  200.040641]  [<ffffffff810bac07>] ? vfs_write+0xbc/0x101
[  200.040643]  [<ffffffff810bad08>] ? sys_write+0x45/0x6e
[  200.040646]  [<ffffffff81002a42>] ? system_call_fastpath+0x16/0x1b
[  200.040647] Code: 83 c0 08 80 7c 24 50 01 75 10 48 89 c7 49 63 cc
48 8b 74 24 48 f3 a4 48 89 f8 48 89 c7 48 8b 74 24 40 41 0f b7 d8 49
63 cf 89 da <f3> a4 4c 8b 2d 62 1d 00 00 48 8b 3d 53 1d 00 00 b1 01 48
8b 74
[  200.040668] RIP  [<ffffffffa001d395>]
mydriver_transform+0x1a3/0x6a8 [mydriver_aes2]
[  200.040671]  RSP <ffff880072c5b898>
[  200.040672] CR2: 0000000000000000
[  200.040733] ---[ end trace ae2865df0a025f7d ]---
[  221.687773] SysRq : Emergency Sync



BUT Iperf in TCP mode has its own problems yet ( the system freezes
with no response ).

Thank in advance,
Hamid.


--- mydriver1	2010-12-21 15:20:17.000000000 +0330
+++ mydriver2	2010-12-21 15:24:18.000000000 +0330
@@ -1,4 +1,3 @@
-
 static int
 mydriver_cbc_decrypt(struct blkcipher_desc *desc,
 		  struct scatterlist *dst, struct scatterlist *src,
@@ -14,18 +13,17 @@ mydriver_cbc_decrypt(struct blkcipher_desc
 	err = blkcipher_walk_virt(desc, &walk);
 	op->iv = walk.iv;
 	
-	while((nbytes = walk.nbytes)) {
+	
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_CBC;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes;
 		op->dir = AES_DIR_DECRYPT;
-		
 		ret = mydriver_transform(op, 0);

 		nbytes -= ret;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
-	}
+	

 	return err;
 }
@@ -45,16 +43,17 @@ mydriver_cbc_encrypt(struct blkcipher_desc
 	err = blkcipher_walk_virt(desc, &walk);
 	op->iv = walk.iv;
 	
-	while((nbytes = walk.nbytes)) {
+	
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_CBC;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes;
 		op->dir = AES_DIR_ENCRYPT;
 		ret = mydriver_transform(op, 0);
 		nbytes -= ret;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
-	}
+	

 	return err;
 }
+

---------- Forwarded message ----------
From: Hamid Nassiby <h.nassiby@xxxxxxxxx>
Date: Sun, Dec 19, 2010 at 4:28 PM
Subject: crypto accelerator driver problems
To: linux-crypto@xxxxxxxxxxxxxxx


Hi All,

In a research project, we've developed a crypto accelerator based on Xilinx
Virtex5 FPGA family whichÂis connected to PC through PCI-Express slot and is
used by IPSec to offload crypto processing fromÂCPU. The accelerator only
provides AES and DES3_EDE algorithms and I am responsible for providing driver
of the stuff. I inspired much of driver work from geode_aes.c which is
located in "drivers/crypto" subdir of kernel source directory. Both algorithms
are registered as blkcipher providing cbc wrapper "cbc(aes)" just as one that is
registered in geode_aes. Now after months of work, the accelerator is ready to
work (Correctness of hardware operation is assured by direct crypto
test and not by IPSec) and it is time of driver to provide IPSec
access to accelerator. In first
try I could get Â"ping" through the IPsec tunnel. One end of IPSec tunnel is
equipped by our accelerator and the other end is using kernel native IPSec and
built in AES and DES3_EDE algorithms. Now I am faced with 2 problems:

1. Ping will stop getting reply with packet sizes greater than 1426 Bytes
(ping dest_ip -s Â1427). I guessed that it might be MTU problem, but reducing
mtu with "ifconfig eth1 mtu xxx" or
"echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc"
Âdoes not solve the problem. Also when I ping each of tunnel ends from
another end
simultaneously with "ping other_node_ip -i 0.001", the kernel hangs
out completely.

2. Iperf problem. When I try to measure throughput of the IPSec gateway equipped
by our accelerator ( AES-MD5 ), using iperf in tcp mode, the kernel hangs such
that sometimes "Magic SysRq key" does not respond too! And so I could not trace
the problem anyway. Using iperf in udp mode works but I get "UDP bad cheksum" in
'dmesg' output of other end of tunnel (Native IPSec and built in kernel
algorithms).

Two gateways are connected by a cross cable and no router/switch is located
between them to cause mtu problems. In my test pcrypt is not used by now and
booting the kernel with nosmp (so no fear of thread contention) does not change
the situation.

So I request you to help me solve the problem. I bring some parts of driver
that is changed from geode_aes.c and might give useful information. If
it is required,
I'll post all driver text.
------------------------------ ----------------------------

static struct crypto_alg mydriver_cbc_alg = {
   Â.cra_name        =    "cbc(aes)",
   Â.cra_driver_name    Â=    "cbc-aes-mydriver",
   Â.cra_priority      =    400,
   Â.cra_flags           Â=    CRYPTO_ALG_TYPE_BLKCIPHER |

CRYPTO_ALG_NEED_FALLBACK,
   Â.cra_init            =    fallback_init_blk,
   Â.cra_exit            =    fallback_exit_blk,
   Â.cra_blocksize     Â=    AES_MIN_BLOCK_SIZE,
   Â.cra_ctxsize      Â=    sizeof(struct mydriver_aes_op),
   Â.cra_alignmask     Â=    15,
   Â.cra_type            =    &crypto_blkcipher_type,
   Â.cra_module           =    THIS_MODULE,
   Â.cra_list            =
LIST_HEAD_INIT(mydriver_cbc_alg.cra_list),
   Â.cra_u             Â=    {
       Â.blkcipher   Â=    {
           Â.min_keysize  Â=    AES_MIN_KEY_SIZE,
           Â.max_keysize  Â=    AES_MIN_KEY_SIZE,
           Â.setkey         =    mydriver_setkey_blk,
           Â.encrypt        Â=    mydriver_cbc_encrypt,
           Â.decrypt        Â=    mydriver_cbc_decrypt,
           Â.ivsize         =    AES_IV_LENGTH,
       Â}
   Â}
};
//---------------
static int
mydriver_cbc_encrypt(struct blkcipher_desc *desc,
        Âstruct scatterlist *dst, struct scatterlist *src,
        Âunsigned int nbytes)
{

   Âstruct mydriver_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
   Âstruct blkcipher_walk walk;
   Âint err, ret;

   Âif (unlikely(op->keylen != AES_KEYSIZE_128))
       Âreturn fallback_blk_enc(desc, dst, src, nbytes);

   Âblkcipher_walk_init(&walk, dst, src, nbytes);
   Âerr = blkcipher_walk_virt(desc, &walk);
   Âop->iv = walk.iv;

   Âwhile((nbytes = walk.nbytes)) {

       Âop->src = walk.src.virt.addr,
       Âop->dst = walk.dst.virt.addr;
       Âop->mode = AES_MODE_CBC;
       Âop->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
       Âop->dir = AES_DIR_ENCRYPT;
           Â//ret = mydriver_aes_crypt(op);
       Âret = mydriver_transform(op, 0);
       Ânbytes -= ret;
       Âerr = blkcipher_walk_done(desc, &walk, nbytes);
   Â}

   Âreturn err;
}
/*--------- mydriver_transform which makes a buffer containing key, iv, data
with
some additional header that is required by our accelerator, writes the buffer
to accelerator by DMA and then reads response from hardware.*/

static inline int mydriver_transform(struct mydriver_aes_op *op, int alg)
{

       Âint Âreq_len, err;
       Âu8 *req_buf = NULL, *res_buf = NULL;
       Âalg_operation operation;
       Âu32 my_req_id;
       Âif (op->len == 0)
           Âreturn 0;

       Âif ((op->dir == AES_DIR_ENCRYPT) ||(op->dir ==
DES3_DIR_ENCRYPT)){
            operation = SH_ENCRYPT;
            my_req_id = smp_processor_id();// This ID is
put into our packet and is checked by each thread when the hardware
response is ready to see if the packet is its?
       Â}
       Âelse {
           Âoperation = SH_DECRYPT;
           Âmy_req_id = smp_processor_id() + 64;
//uniqueness of ID does not solve problem described in mail :( .
       Â}



       Âerr = create_request(alg, op->mode, operation, htonl(my_req_id),
op->key, op->iv, op->src, op->len, &req_buf, &req_len);


       Âif (err){
           Âprintk(KERN_EMERG"mydriver_transform : Error
CreateReuest :
errcode = %d\n", err);
           Â//goto error;
       Â}

       Âerr = write_request(req_buf, req_len);
       Âif (err){
           Âprintk(KERN_EMERG"mydriver_transform : Error WriteReuest
:
errcode = %d\n", err);
           Â//goto error;
       Â}
       Âkfree(req_buf);
       Âreq_buf = NULL;

       Âerr = read_response(&res_buf, /*local_hdr.Length*/my_req_id);

       Âmemcpy(op->dst, (res_buf + sizeof(struct response_hdr)),
op->len);

       Âkfree(res_buf);
       Âres_buf = NULL;
       Âreturn op->len;
}
//-----------
/* create_request wich builds packet for mydriver_transform */
static inline int create_request(int alg, char mode, char enc_dec, u32
request_id,
         char *key, char *iv, char *data, int datalen,
         u8 **outbuf, int *outlen)
{
   Âint req_len, n_padding, keylen, blocklen, algid;
   Âstruct request_hdr *p_hdr;
   Âchar *ptr;

   Âif (alg == 0){ //AES Algorithm
       Âkeylen = 16;
       Âblocklen = 16;
       Âalgid = 4;
   Â} else if (alg == 1){ //DES3 Algorithm
       Âkeylen = 24;
       Âblocklen = 8;
       Âalgid = 3;
   Â}

   Âreq_len = sizeof(struct request_hdr) + keylen;
   Âif (keylen != 0 && keylen % 16 == 0)
       Âreq_len += 8; //For request packet to be 128bit aligned
   Âif (mode == SHAMS_CBC)
       Âreq_len += blocklen; // for IV len

   Ân_padding = (blocklen - (datalen % blocklen)) % blocklen; //padding
data to be multiple of 128 bits.

   Âreq_len += (n_padding + datalen);
   Â*outbuf = kmalloc(req_len, GFP_ATOMIC);
   Âp_hdr = (struct request_hdr *) *outbuf;
   Â*outlen = p_hdr->Length = req_len;

   Âp_hdr->request_id = request_id;
   Âp_hdr->AlgID_Mode_EncDec = (enc_dec << 15) | (mode << 12) | algid;
   Â// Filling key
   Âptr = *outbuf + sizeof(struct request_hdr);
   Âmemcpy(ptr, key, keylen);
   Âptr += keylen;
   Âif (keylen != 0 && keylen % 16 == 0){
       Âmemset(ptr, 0, 8);
       Âptr += 8;
   Â}
   Â// Filling IV
   Âif (mode == SHAMS_CBC){
       Âmemcpy(ptr, iv, blocklen);
       Âptr += blocklen;
   Â}
   Â// Copy data
   Âmemcpy(ptr, data, datalen);
   Âptr += datalen;
   Â// Zeroing padd bits
   Âmemset(ptr, 0, n_padding);

   Âreturn 0;

}
//--------------------------------
/* write_request that writes the provided buffer to device */

static inline int write_request(u8 *buff, unsigned int count)
{
unsigned long Âiflags;
u32 tlp_count, tlp_size;
dma_addr_t dma_addr;
struct x5pcie_dma_desc *desc_table = (struct x5pcie_dma_desc *)global_bar[0];

/** DMA operations:*/
   Âdma_addr = pci_map_single(global_dev, buff, count, PCI_DMA_TODEVICE);
   Âif (0 == dma_addr) {
       Âprintk(KERN_EMERG"XPCIe_Read: Map error.\n");
       Âreturn -1;
   Â}

// Do DMA transfer here....
   Âcount = count /4;//
   Âfor (tlp_size = 32; tlp_size > 0; tlp_size--)
       Âif ((count % tlp_size) == 0){
           Âtlp_count = count / tlp_size;
           Âbreak;
       Â}

   Âtlp_size = tlp_count | (tlp_size << 16);
   Âspin_lock_irqsave(&wlock, iflags);
   Â//down(&my_sem);
// Â Â Âif (down_interruptible(&my_sem)){
// Â Â Â Â Â Â Âprintk(KERN_EMERG "\nwrite_request: Error Acquire Semaphore!!");
// Â Â Â Â Â Â Âreturn -ERESTARTSYS;
// Â Â Â}
   Âwritel(cpu_to_le32(tlp_size),&desc_table->rdmatlpc);       // read
DMA TLP count: ÂTLPs to transfer
   Âwritel(cpu_to_le32(dma_addr),&desc_table->rdmatlpa); Â// physical bus
address of DMA able buffer
   Âwmb();
   Âwritew(cpu_to_le16(0x0001),(global_bar[0]+6));        Â// read
dma start bit[16] to ddmacr
   Âwmb();
   Âwhile(readw((global_bar[0]+6)) != 0x0101);
   Âspin_unlock_irqrestore(&wlock, iflags);
   Â//up(&my_sem);
  Â // Unmap the DMA buffer so it is safe for normal access again.
   Âpci_unmap_single(global_dev, dma_addr, count, PCI_DMA_TODEVICE);

   Â/** End of dma section*/
   Âreturn 0;

}
//--------------
/* read_response that reads the en/decrypted buffer from device */

static inline int read_response(u8 **buff, Âu16 my_req_id)
{
   Âdma_addr_t dma_addr;
   Âu16 count, tmp_req_id;
   Âunsigned long Âiflags1;//, iflags2;
   Âu32 tlp_count, tlp_size;
   Âstruct x5pcie_dma_desc *desc_table = (struct x5pcie_dma_desc
*)global_bar[0];

   Âfor(;;){

       Âspin_lock_irqsave(&alock, iflags1);
       Âtmp_req_id = readw((global_bar[0] + 82 + (fifo_entry * 4)));
       Âspin_unlock_irqrestore(&alock, iflags1);
       Âif(my_req_id == tmp_req_id) // Is the provided packet mine?
           Âbreak;

   Â}

           Âcount = readw(global_bar[0] + 80 + (fifo_entry
* 4));//What is the size of my packet?
           Âprintk(KERN_EMERG "read_response : my_req_id = %d has
count = %d\n", my_req_id, count);

           Â*buff = kmalloc(count, GFP_ATOMIC);
           Âdma_addr = pci_map_single(global_dev, *buff, count,
PCI_DMA_FROMDEVICE);
           Âif (0 == dma_addr){
               Âprintk(KERN_EMERG"XPCIe_Read: Map error.\n");
               Âreturn -1;
           Â}

           Âcount = count /4;//
           Âfor (tlp_size = 32; tlp_size > 0; tlp_size--)
               Âif ((count % tlp_size) == 0){
                   Âtlp_count = count / tlp_size;
                   Âbreak;
               Â}

           Âtlp_size = tlp_count | (tlp_size << 16);
   Â//       Âdown(&my_sem);
// Â Â Â Â Â Â Â Â Â Â Âif (down_interruptible(&my_sem)){
// Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âprintk(KERN_EMERG "\nread_response: Error
Acquire Semaphore!!");
// Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âreturn -ERESTARTSYS;
// Â Â Â Â Â Â Â Â Â Â Â}
           Âwritel(cpu_to_le32(tlp_size),&desc_table->wdmatlpc);
   Â// read DMA TLP count: ÂTLPs to transfer
           Âwritel(cpu_to_le32(dma_addr),&desc_table->wdmatlpa); Â//
physical bus address of DMA able buffer
           Âwmb();
           Âwritew(cpu_to_le16(0x0001),(global_bar[0]+4));
  // read dma start bit[16] to ddmacr
           Âwmb();
           Âwhile(readw(global_bar[0]+4) != 0x0101);

           Âfifo_entry = (fifo_entry + 1) % 9; // 9 : Number of
registers holding request_id and len of FiFo's elements .
           Â//spin_unlock_irqrestore(&rlock, iflags2);
           Â//up(&my_sem);
           Âpci_unmap_single(global_dev, dma_addr, count,
PCI_DMA_FROMDEVICE);

           Âreturn count;

}


Thanks in advance,
Hamid.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux