]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - drivers/staging/wlags49_h2/wl_pci.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[mirror_ubuntu-hirsute-kernel.git] / drivers / staging / wlags49_h2 / wl_pci.c
1 /*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
4 *
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
11 *
12 *------------------------------------------------------------------------------
13 *
14 * This file contains processing and initialization specific to PCI/miniPCI
15 * devices.
16 *
17 *------------------------------------------------------------------------------
18 *
19 * SOFTWARE LICENSE
20 *
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
25 *
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
28 *
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
31 *
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
35 * distribution.
36 *
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 *
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * Disclaimer
46 *
47 * THIS SOFTWARE IS PROVIDED \93AS IS\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58 * DAMAGE.
59 *
60 ******************************************************************************/
61
62 /*******************************************************************************
63 * include files
64 ******************************************************************************/
65 #include <wireless/wl_version.h>
66
67 #include <linux/module.h>
68 #include <linux/kernel.h>
69 #include <linux/errno.h>
70 #include <linux/pci.h>
71 #include <linux/init.h>
72 #include <linux/sched.h>
73 #include <linux/ptrace.h>
74 #include <linux/slab.h>
75 #include <linux/ctype.h>
76 #include <linux/string.h>
77 //#include <linux/timer.h>
78 #include <linux/interrupt.h>
79 #include <linux/in.h>
80 #include <linux/delay.h>
81 #include <asm/system.h>
82 #include <asm/io.h>
83 #include <asm/irq.h>
84 #include <asm/bitops.h>
85 #include <asm/uaccess.h>
86
87 #include <linux/ethtool.h>
88 #include <linux/netdevice.h>
89 #include <linux/etherdevice.h>
90 #include <linux/skbuff.h>
91 #include <linux/if_arp.h>
92 #include <linux/ioport.h>
93
94 #include <hcf/debug.h>
95
96 #include <hcf.h>
97 #include <dhf.h>
98 #include <hcfdef.h>
99
100 #include <wireless/wl_if.h>
101 #include <wireless/wl_internal.h>
102 #include <wireless/wl_util.h>
103 #include <wireless/wl_main.h>
104 #include <wireless/wl_netdev.h>
105 #include <wireless/wl_pci.h>
106
107
108 /*******************************************************************************
109 * global variables
110 ******************************************************************************/
111 #if DBG
112 extern dbg_info_t *DbgInfo;
113 #endif // DBG
114
115 /* define the PCI device Table Cardname and id tables */
116 enum hermes_pci_versions {
117 CH_Agere_Systems_Mini_PCI_V1 = 0,
118 };
119
120 static struct pci_device_id wl_pci_tbl[] __devinitdata = {
121 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
122 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
123 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
124 { } /* Terminating entry */
125 };
126
127 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
128
129 /*******************************************************************************
130 * function prototypes
131 ******************************************************************************/
132 int __devinit wl_pci_probe( struct pci_dev *pdev,
133 const struct pci_device_id *ent );
134 void __devexit wl_pci_remove(struct pci_dev *pdev);
135 int wl_pci_setup( struct pci_dev *pdev );
136 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
137
138 #ifdef ENABLE_DMA
139 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
140 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
141 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
142 DESC_STRCT **desc );
143 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
144 DESC_STRCT **desc );
145 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
146 DESC_STRCT **desc );
147 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
148 DESC_STRCT **desc );
149 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
150 DESC_STRCT **desc, int size );
151 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
152 DESC_STRCT **desc );
153 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
154 DESC_STRCT **desc );
155 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
156 DESC_STRCT **desc );
157 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
158 DESC_STRCT *desc, int size );
159 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
160 DESC_STRCT *desc );
161
162 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
163 #endif // ENABLE_DMA
164
165 /*******************************************************************************
166 * PCI module function registration
167 ******************************************************************************/
168 static struct pci_driver wl_driver =
169 {
170 name: MODULE_NAME,
171 id_table: wl_pci_tbl,
172 probe: wl_pci_probe,
173 remove: __devexit_p(wl_pci_remove),
174 suspend: NULL,
175 resume: NULL,
176 };
177
178 /*******************************************************************************
179 * wl_adapter_init_module()
180 *******************************************************************************
181 *
182 * DESCRIPTION:
183 *
184 * Called by init_module() to perform PCI-specific driver initialization.
185 *
186 * PARAMETERS:
187 *
188 * N/A
189 *
190 * RETURNS:
191 *
192 * 0
193 *
194 ******************************************************************************/
195 int wl_adapter_init_module( void )
196 {
197 int result;
198 /*------------------------------------------------------------------------*/
199
200 DBG_FUNC( "wl_adapter_init_module()" );
201 DBG_ENTER( DbgInfo );
202 DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
203
204 result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
205 //;? why not do something with the result
206
207 DBG_LEAVE( DbgInfo );
208 return 0;
209 } // wl_adapter_init_module
210 /*============================================================================*/
211
212 /*******************************************************************************
213 * wl_adapter_cleanup_module()
214 *******************************************************************************
215 *
216 * DESCRIPTION:
217 *
218 * Called by cleanup_module() to perform PCI-specific driver cleanup.
219 *
220 * PARAMETERS:
221 *
222 * N/A
223 *
224 * RETURNS:
225 *
226 * N/A
227 *
228 ******************************************************************************/
229 void wl_adapter_cleanup_module( void )
230 {
231 //;?how comes wl_adapter_cleanup_module is located in a seemingly pci specific module
232 DBG_FUNC( "wl_adapter_cleanup_module" );
233 DBG_ENTER( DbgInfo );
234
235 //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
236 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
237
238 pci_unregister_driver( &wl_driver );
239
240 DBG_LEAVE( DbgInfo );
241 return;
242 } // wl_adapter_cleanup_module
243 /*============================================================================*/
244
245 /*******************************************************************************
246 * wl_adapter_insert()
247 *******************************************************************************
248 *
249 * DESCRIPTION:
250 *
251 * Called by wl_pci_probe() to continue the process of device insertion.
252 *
253 * PARAMETERS:
254 *
255 * dev - a pointer to the device's net_device structure
256 *
257 * RETURNS:
258 *
259 * TRUE or FALSE
260 *
261 ******************************************************************************/
262 int wl_adapter_insert( struct net_device *dev )
263 {
264 int result = FALSE;
265 /*------------------------------------------------------------------------*/
266
267 DBG_FUNC( "wl_adapter_insert" );
268 DBG_ENTER( DbgInfo );
269
270 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
271
272 if( dev == NULL ) {
273 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
274 } else if( dev->priv == NULL ) {
275 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
276 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
277 result = TRUE;
278 } else {
279 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
280 }
281 DBG_LEAVE( DbgInfo );
282 return result;
283 } // wl_adapter_insert
284 /*============================================================================*/
285
286 /*******************************************************************************
287 * wl_adapter_open()
288 *******************************************************************************
289 *
290 * DESCRIPTION:
291 *
292 * Open the device.
293 *
294 * PARAMETERS:
295 *
296 * dev - a pointer to the device's net_device structure
297 *
298 * RETURNS:
299 *
300 * an HCF status code
301 *
302 ******************************************************************************/
303 int wl_adapter_open( struct net_device *dev )
304 {
305 int result = 0;
306 int hcf_status = HCF_SUCCESS;
307 /*------------------------------------------------------------------------*/
308
309 DBG_FUNC( "wl_adapter_open" );
310 DBG_ENTER( DbgInfo );
311
312 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
313
314 hcf_status = wl_open( dev );
315
316 if( hcf_status != HCF_SUCCESS ) {
317 result = -ENODEV;
318 }
319
320 DBG_LEAVE( DbgInfo );
321 return result;
322 } // wl_adapter_open
323 /*============================================================================*/
324
325 /*******************************************************************************
326 * wl_adapter_close()
327 *******************************************************************************
328 *
329 * DESCRIPTION:
330 *
331 * Close the device
332 *
333 * PARAMETERS:
334 *
335 * dev - a pointer to the device's net_device structure
336 *
337 * RETURNS:
338 *
339 * 0
340 *
341 ******************************************************************************/
342 int wl_adapter_close( struct net_device *dev )
343 {
344 DBG_FUNC( "wl_adapter_close" );
345 DBG_ENTER( DbgInfo );
346
347 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
348 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
349
350 wl_close( dev );
351
352 DBG_LEAVE( DbgInfo );
353 return 0;
354 } // wl_adapter_close
355 /*============================================================================*/
356
357 /*******************************************************************************
358 * wl_adapter_is_open()
359 *******************************************************************************
360 *
361 * DESCRIPTION:
362 *
363 * Check whether this device is open. Returns
364 *
365 * PARAMETERS:
366 *
367 * dev - a pointer to the device's net_device structure
368 *
369 * RETURNS:
370 *
371 * nonzero if device is open.
372 *
373 ******************************************************************************/
374 int wl_adapter_is_open( struct net_device *dev )
375 {
376 /* This function is used in PCMCIA to check the status of the 'open' field
377 in the dev_link_t structure associated with a network device. There
378 doesn't seem to be an analog to this for PCI, and checking the status
379 contained in the net_device structure doesn't have the same effect.
380 For now, return TRUE, but find out if this is necessary for PCI. */
381
382 return TRUE;
383 } // wl_adapter_is_open
384 /*============================================================================*/
385
386 /*******************************************************************************
387 * wl_pci_probe()
388 *******************************************************************************
389 *
390 * DESCRIPTION:
391 *
392 * Registered in the pci_driver structure, this function is called when the
393 * PCI subsystem finds a new PCI device which matches the infomation contained
394 * in the pci_device_id table.
395 *
396 * PARAMETERS:
397 *
398 * pdev - a pointer to the device's pci_dev structure
399 * ent - this device's entry in the pci_device_id table
400 *
401 * RETURNS:
402 *
403 * 0 on success
404 * errno value otherwise
405 *
406 ******************************************************************************/
407 int __devinit wl_pci_probe( struct pci_dev *pdev,
408 const struct pci_device_id *ent )
409 {
410 int result;
411 /*------------------------------------------------------------------------*/
412
413 DBG_FUNC( "wl_pci_probe" );
414 DBG_ENTER( DbgInfo );
415 DBG_PRINT( "%s\n", VERSION_INFO );
416
417 result = wl_pci_setup( pdev );
418
419 DBG_LEAVE( DbgInfo );
420
421 return result;
422 } // wl_pci_probe
423 /*============================================================================*/
424
425 /*******************************************************************************
426 * wl_pci_remove()
427 *******************************************************************************
428 *
429 * DESCRIPTION:
430 *
431 * Registered in the pci_driver structure, this function is called when the
432 * PCI subsystem detects that a PCI device which matches the infomation
433 * contained in the pci_device_id table has been removed.
434 *
435 * PARAMETERS:
436 *
437 * pdev - a pointer to the device's pci_dev structure
438 *
439 * RETURNS:
440 *
441 * N/A
442 *
443 ******************************************************************************/
444 void __devexit wl_pci_remove(struct pci_dev *pdev)
445 {
446 struct net_device *dev = NULL;
447 /*------------------------------------------------------------------------*/
448
449 DBG_FUNC( "wl_pci_remove" );
450 DBG_ENTER( DbgInfo );
451
452 /* Make sure the pci_dev pointer passed in is valid */
453 if( pdev == NULL ) {
454 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
455 return;
456 }
457
458 dev = (struct net_device *)pci_get_drvdata( pdev );
459 if( dev == NULL ) {
460 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
461 return;
462 }
463
464 /* Perform device cleanup */
465 wl_remove( dev );
466 free_irq( dev->irq, dev );
467
468 #ifdef ENABLE_DMA
469 wl_pci_dma_free( pdev, (struct wl_private *)dev->priv );
470 #endif
471
472 wl_device_dealloc( dev );
473
474 DBG_LEAVE( DbgInfo );
475 return;
476 } // wl_pci_remove
477 /*============================================================================*/
478
479 /*******************************************************************************
480 * wl_pci_setup()
481 *******************************************************************************
482 *
483 * DESCRIPTION:
484 *
485 * Called by wl_pci_probe() to begin a device's initialization process.
486 *
487 * PARAMETERS:
488 *
489 * pdev - a pointer to the device's pci_dev structure
490 *
491 * RETURNS:
492 *
493 * 0 on success
494 * errno value otherwise
495 *
496 ******************************************************************************/
497 int wl_pci_setup( struct pci_dev *pdev )
498 {
499 int result = 0;
500 struct net_device *dev = NULL;
501 struct wl_private *lp = NULL;
502 /*------------------------------------------------------------------------*/
503
504 DBG_FUNC( "wl_pci_setup" );
505 DBG_ENTER( DbgInfo );
506
507 /* Make sure the pci_dev pointer passed in is valid */
508 if( pdev == NULL ) {
509 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
510 return -ENODEV;
511 }
512
513 result = pci_enable_device( pdev );
514 if( result != 0 ) {
515 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
516 DBG_LEAVE( DbgInfo );
517 return result;
518 }
519
520 /* We found our device! Let's register it with the system */
521 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
522 dev = wl_device_alloc( );
523 if( dev == NULL ) {
524 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
525 DBG_LEAVE( DbgInfo );
526 return -ENOMEM;
527 }
528
529 /* Make sure that space was allocated for our private adapter struct */
530 if( dev->priv == NULL ) {
531 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
532 DBG_LEAVE( DbgInfo );
533 return -ENOMEM;
534 }
535
536 #ifdef ENABLE_DMA
537 /* Allocate DMA Descriptors */
538 if( wl_pci_dma_alloc( pdev, (struct wl_private *)dev->priv ) < 0 ) {
539 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
540 DBG_LEAVE( DbgInfo );
541 return -ENOMEM;
542 }
543 #endif
544
545 /* Register our private adapter structure with PCI */
546 pci_set_drvdata( pdev, dev );
547
548 /* Fill out bus specific information in the net_device struct */
549 dev->irq = pdev->irq;
550 SET_MODULE_OWNER( dev );
551
552 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
553 dev->base_addr = pdev->resource[0].start;
554
555 /* Initialize our device here */
556 if( !wl_adapter_insert( dev )) {
557 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
558 wl_device_dealloc( dev );
559 DBG_LEAVE( DbgInfo );
560 return -EINVAL;
561 }
562
563 /* Register our ISR */
564 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
565
566 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
567 if( result ) {
568 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
569 DBG_LEAVE( DbgInfo );
570 return result;
571 }
572
573 /* Make sure interrupts are enabled properly for CardBus */
574 lp = (struct wl_private *)dev->priv;
575
576 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
577 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
578 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
579 wl_pci_enable_cardbus_interrupts( pdev );
580 }
581
582 /* Enable bus mastering */
583 pci_set_master( pdev );
584
585 DBG_LEAVE( DbgInfo );
586 return 0;
587 } // wl_pci_setup
588 /*============================================================================*/
589
590 /*******************************************************************************
591 * wl_pci_enable_cardbus_interrupts()
592 *******************************************************************************
593 *
594 * DESCRIPTION:
595 *
596 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
597 * is done by writing bit 15 to the function event mask register. This
598 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
599 * space at byte offset 1f4 (7f4 for WARP).
600 *
601 * PARAMETERS:
602 *
603 * pdev - a pointer to the device's pci_dev structure
604 *
605 * RETURNS:
606 *
607 * N/A
608 *
609 ******************************************************************************/
610 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
611 {
612 u32 bar2_reg;
613 u32 mem_addr_bus;
614 u32 func_evt_mask_reg;
615 void *mem_addr_kern = NULL;
616 /*------------------------------------------------------------------------*/
617
618 DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
619 DBG_ENTER( DbgInfo );
620
621 /* Initialize to known bad values */
622 bar2_reg = 0xdeadbeef;
623 mem_addr_bus = 0xdeadbeef;
624
625 /* Read the BAR2 register; this register contains the base address of the
626 memory region where the function event mask register lives */
627 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
628 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
629
630 /* Once the base address is obtained, remap the memory region to kernel
631 space so we can retrieve the register */
632 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
633
634 #ifdef HERMES25
635 #define REG_OFFSET 0x07F4
636 #else
637 #define REG_OFFSET 0x01F4
638 #endif // HERMES25
639
640 #define BIT15 0x8000
641
642 /* Retrieve the functional event mask register, enable interrupts by
643 setting Bit 15, and write back the value */
644 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
645 func_evt_mask_reg |= BIT15;
646 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
647
648 /* Once complete, unmap the region and exit */
649 iounmap( mem_addr_kern );
650
651 DBG_LEAVE( DbgInfo );
652 return;
653 } // wl_pci_enable_cardbus_interrupts
654 /*============================================================================*/
655
656 #ifdef ENABLE_DMA
657 /*******************************************************************************
658 * wl_pci_dma_alloc()
659 *******************************************************************************
660 *
661 * DESCRIPTION:
662 *
663 * Allocates all resources needed for PCI/CardBus DMA operation
664 *
665 * PARAMETERS:
666 *
667 * pdev - a pointer to the device's pci_dev structure
668 * lp - the device's private adapter structure
669 *
670 * RETURNS:
671 *
672 * 0 on success
673 * errno value otherwise
674 *
675 ******************************************************************************/
676 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
677 {
678 int i;
679 int status = 0;
680 /*------------------------------------------------------------------------*/
681
682 DBG_FUNC( "wl_pci_dma_alloc" );
683 DBG_ENTER( DbgInfo );
684
685 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
686 //
687 // /* Alloc for the Tx chain and its reclaim descriptor */
688 // for( i = 0; i < NUM_TX_DESC; i++ ) {
689 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
690 // if( status == 0 ) {
691 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
692 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
693 // lp->dma.tx_rsc_ind++;
694 // } else {
695 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
696 // break;
697 // }
698 // }
699 // if( status == 0 ) {
700 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
701 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
702 // }
703 // /* Alloc for the Rx chain and its reclaim descriptor */
704 // if( status == 0 ) {
705 // for( i = 0; i < NUM_RX_DESC; i++ ) {
706 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
707 // if( status == 0 ) {
708 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
709 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
710 // lp->dma.rx_rsc_ind++;
711 // } else {
712 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
713 // break;
714 // }
715 // }
716 // }
717 // if( status == 0 ) {
718 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
719 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
720 // }
721 // /* Store status, as host should not call HCF functions if this fails */
722 // lp->dma.status = status; //;?all useages of dma.status have been commented out
723 // DBG_LEAVE( DbgInfo );
724 return status;
725 } // wl_pci_dma_alloc
726 /*============================================================================*/
727
728 /*******************************************************************************
729 * wl_pci_dma_free()
730 *******************************************************************************
731 *
732 * DESCRIPTION:
733 *
734 * Deallocated all resources needed for PCI/CardBus DMA operation
735 *
736 * PARAMETERS:
737 *
738 * pdev - a pointer to the device's pci_dev structure
739 * lp - the device's private adapter structure
740 *
741 * RETURNS:
742 *
743 * 0 on success
744 * errno value otherwise
745 *
746 ******************************************************************************/
747 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
748 {
749 int i;
750 int status = 0;
751 /*------------------------------------------------------------------------*/
752
753 DBG_FUNC( "wl_pci_dma_free" );
754 DBG_ENTER( DbgInfo );
755
756 /* Reclaim all Rx packets that were handed over to the HCF */
757 /* Do I need to do this? Before this free is called, I've already disabled
758 the port which will call wl_pci_dma_hcf_reclaim */
759 //if( lp->dma.status == 0 )
760 //{
761 // wl_pci_dma_hcf_reclaim( lp );
762 //}
763
764 /* Free everything needed for DMA Rx */
765 for( i = 0; i < NUM_RX_DESC; i++ ) {
766 if( lp->dma.rx_packet[i] ) {
767 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
768 if( status != 0 ) {
769 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
770 }
771 }
772 }
773 lp->dma.rx_rsc_ind = 0;
774
775 if( lp->dma.rx_reclaim_desc ) {
776 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
777 if( status != 0 ) {
778 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
779 }
780 }
781
782 /* Free everything needed for DMA Tx */
783 for( i = 0; i < NUM_TX_DESC; i++ ) {
784 if( lp->dma.tx_packet[i] ) {
785 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
786 if( status != 0 ) {
787 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
788 }
789 }
790 }
791 lp->dma.tx_rsc_ind = 0;
792
793 if( lp->dma.tx_reclaim_desc ) {
794 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
795 if( status != 0 ) {
796 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
797 }
798 }
799
800 DBG_LEAVE( DbgInfo );
801 return status;
802 } // wl_pci_dma_free
803
804 /*============================================================================*/
805
806 /*******************************************************************************
807 * wl_pci_dma_alloc_tx_packet()
808 *******************************************************************************
809 *
810 * DESCRIPTION:
811 *
812 * Allocates a single Tx packet, consisting of several descriptors and
813 * buffers. Data to transmit is first copied into the 'payload' buffer
814 * before being transmitted.
815 *
816 * PARAMETERS:
817 *
818 * pdev - a pointer to the device's pci_dev structure
819 * lp - the device's private adapter structure
820 * desc - a pointer which will reference the descriptor to be alloc'd.
821 *
822 * RETURNS:
823 *
824 * 0 on success
825 * errno value otherwise
826 *
827 ******************************************************************************/
828 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
829 DESC_STRCT **desc )
830 {
831 // int status = 0;
832 // /*------------------------------------------------------------------------*/
833 //
834 // if( desc == NULL ) {
835 // status = -EFAULT;
836 // }
837 // if( status == 0 ) {
838 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
839 // HCF_DMA_TX_BUF1_SIZE );
840 //
841 // if( status == 0 ) {
842 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
843 // &( (*desc)->next_desc_addr ),
844 // HCF_MAX_PACKET_SIZE );
845 // }
846 // }
847 // if( status == 0 ) {
848 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
849 // }
850 // return status;
851 } // wl_pci_dma_alloc_tx_packet
852 /*============================================================================*/
853
854 /*******************************************************************************
855 * wl_pci_dma_free_tx_packet()
856 *******************************************************************************
857 *
858 * DESCRIPTION:
859 *
860 * Frees a single Tx packet, described in the corresponding alloc function.
861 *
862 * PARAMETERS:
863 *
864 * pdev - a pointer to the device's pci_dev structure
865 * lp - the device's private adapter structure
866 * desc - a pointer which will reference the descriptor to be alloc'd.
867 *
868 * RETURNS:
869 *
870 * 0 on success
871 * errno value otherwise
872 *
873 ******************************************************************************/
874 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
875 DESC_STRCT **desc )
876 {
877 int status = 0;
878 /*------------------------------------------------------------------------*/
879
880 if( *desc == NULL ) {
881 DBG_PRINT( "Null descriptor\n" );
882 status = -EFAULT;
883 }
884 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
885 //descriptors, make this robust
886 if( status == 0 && (*desc)->next_desc_addr ) {
887 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
888 }
889 if( status == 0 ) {
890 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
891 }
892 return status;
893 } // wl_pci_dma_free_tx_packet
894 /*============================================================================*/
895
896 /*******************************************************************************
897 * wl_pci_dma_alloc_rx_packet()
898 *******************************************************************************
899 *
900 * DESCRIPTION:
901 *
902 * Allocates a single Rx packet, consisting of two descriptors and one
903 * contiguous buffer. THe buffer starts with the hermes-specific header.
904 * One descriptor points at the start, the other at offset 0x3a of the
905 * buffer.
906 *
907 * PARAMETERS:
908 *
909 * pdev - a pointer to the device's pci_dev structure
910 * lp - the device's private adapter structure
911 * desc - a pointer which will reference the descriptor to be alloc'd.
912 *
913 * RETURNS:
914 *
915 * 0 on success
916 * errno value otherwise
917 *
918 ******************************************************************************/
919 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
920 DESC_STRCT **desc )
921 {
922 int status = 0;
923 DESC_STRCT *p;
924 /*------------------------------------------------------------------------*/
925
926 // if( desc == NULL ) {
927 // status = -EFAULT;
928 // }
929 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
930 // //descriptors, make this robust
931 // if( status == 0 ) {
932 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
933 // }
934 // if( status == 0 ) {
935 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
936 // }
937 // if( status == 0 ) {
938 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
939 // }
940 // if( status == 0 ) {
941 // /* Size of 1st descriptor becomes 0x3a bytes */
942 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
943 //
944 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
945 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
946 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
947 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
948 // p->next_desc_addr = NULL;
949 //
950 // /* Chain 2nd descriptor to 1st descriptor */
951 // (*desc)->next_desc_addr = p;
952 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
953 // }
954
955 return status;
956 } // wl_pci_dma_alloc_rx_packet
957 /*============================================================================*/
958
959 /*******************************************************************************
960 * wl_pci_dma_free_rx_packet()
961 *******************************************************************************
962 *
963 * DESCRIPTION:
964 *
965 * Frees a single Rx packet, described in the corresponding alloc function.
966 *
967 * PARAMETERS:
968 *
969 * pdev - a pointer to the device's pci_dev structure
970 * lp - the device's private adapter structure
971 * desc - a pointer which will reference the descriptor to be alloc'd.
972 *
973 * RETURNS:
974 *
975 * 0 on success
976 * errno value otherwise
977 *
978 ******************************************************************************/
979 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
980 DESC_STRCT **desc )
981 {
982 int status = 0;
983 DESC_STRCT *p;
984 /*------------------------------------------------------------------------*/
985
986 if( *desc == NULL ) {
987 status = -EFAULT;
988 }
989 if( status == 0 ) {
990 p = (*desc)->next_desc_addr;
991
992 /* Free the 2nd descriptor */
993 if( p != NULL ) {
994 p->buf_addr = NULL;
995 p->buf_phys_addr = 0;
996
997 status = wl_pci_dma_free_desc( pdev, lp, &p );
998 }
999 }
1000
1001 /* Free the buffer and 1st descriptor */
1002 if( status == 0 ) {
1003 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
1004 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
1005 }
1006 return status;
1007 } // wl_pci_dma_free_rx_packet
1008 /*============================================================================*/
1009
1010 /*******************************************************************************
1011 * wl_pci_dma_alloc_desc_and_buf()
1012 *******************************************************************************
1013 *
1014 * DESCRIPTION:
1015 *
1016 * Allocates a DMA descriptor and buffer, and associates them with one
1017 * another.
1018 *
1019 * PARAMETERS:
1020 *
1021 * pdev - a pointer to the device's pci_dev structure
1022 * lp - the device's private adapter structure
1023 * desc - a pointer which will reference the descriptor to be alloc'd
1024 *
1025 * RETURNS:
1026 *
1027 * 0 on success
1028 * errno value otherwise
1029 *
1030 ******************************************************************************/
1031 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1032 DESC_STRCT **desc, int size )
1033 {
1034 int status = 0;
1035 /*------------------------------------------------------------------------*/
1036
1037 // if( desc == NULL ) {
1038 // status = -EFAULT;
1039 // }
1040 // if( status == 0 ) {
1041 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1042 //
1043 // if( status == 0 ) {
1044 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1045 // }
1046 // }
1047 return status;
1048 } // wl_pci_dma_alloc_desc_and_buf
1049 /*============================================================================*/
1050
1051 /*******************************************************************************
1052 * wl_pci_dma_free_desc_and_buf()
1053 *******************************************************************************
1054 *
1055 * DESCRIPTION:
1056 *
1057 * Frees a DMA descriptor and associated buffer.
1058 *
1059 * PARAMETERS:
1060 *
1061 * pdev - a pointer to the device's pci_dev structure
1062 * lp - the device's private adapter structure
1063 * desc - a pointer which will reference the descriptor to be alloc'd
1064 *
1065 * RETURNS:
1066 *
1067 * 0 on success
1068 * errno value otherwise
1069 *
1070 ******************************************************************************/
1071 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1072 DESC_STRCT **desc )
1073 {
1074 int status = 0;
1075 /*------------------------------------------------------------------------*/
1076
1077 if( desc == NULL ) {
1078 status = -EFAULT;
1079 }
1080 if( status == 0 && *desc == NULL ) {
1081 status = -EFAULT;
1082 }
1083 if( status == 0 ) {
1084 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1085
1086 if( status == 0 ) {
1087 status = wl_pci_dma_free_desc( pdev, lp, desc );
1088 }
1089 }
1090 return status;
1091 } // wl_pci_dma_free_desc_and_buf
1092 /*============================================================================*/
1093
1094 /*******************************************************************************
1095 * wl_pci_dma_alloc_desc()
1096 *******************************************************************************
1097 *
1098 * DESCRIPTION:
1099 *
1100 * Allocates one DMA descriptor in cache coherent memory.
1101 *
1102 * PARAMETERS:
1103 *
1104 * pdev - a pointer to the device's pci_dev structure
1105 * lp - the device's private adapter structure
1106 *
1107 * RETURNS:
1108 *
1109 * 0 on success
1110 * errno value otherwise
1111 *
1112 ******************************************************************************/
1113 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1114 DESC_STRCT **desc )
1115 {
1116 // int status = 0;
1117 // dma_addr_t pa;
1118 // /*------------------------------------------------------------------------*/
1119 //
1120 // DBG_FUNC( "wl_pci_dma_alloc_desc" );
1121 // DBG_ENTER( DbgInfo );
1122 //
1123 // if( desc == NULL ) {
1124 // status = -EFAULT;
1125 // }
1126 // if( status == 0 ) {
1127 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1128 // }
1129 // if( *desc == NULL ) {
1130 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1131 // status = -ENOMEM;
1132 // } else {
1133 // memset( *desc, 0, sizeof( DESC_STRCT ));
1134 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1135 // }
1136 // DBG_LEAVE( DbgInfo );
1137 // return status;
1138 } // wl_pci_dma_alloc_desc
1139 /*============================================================================*/
1140
1141 /*******************************************************************************
1142 * wl_pci_dma_free_desc()
1143 *******************************************************************************
1144 *
1145 * DESCRIPTION:
1146 *
1147 * Frees one DMA descriptor in cache coherent memory.
1148 *
1149 * PARAMETERS:
1150 *
1151 * pdev - a pointer to the device's pci_dev structure
1152 * lp - the device's private adapter structure
1153 *
1154 * RETURNS:
1155 *
1156 * 0 on success
1157 * errno value otherwise
1158 *
1159 ******************************************************************************/
1160 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1161 DESC_STRCT **desc )
1162 {
1163 int status = 0;
1164 /*------------------------------------------------------------------------*/
1165
1166 if( *desc == NULL ) {
1167 status = -EFAULT;
1168 }
1169 if( status == 0 ) {
1170 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1171 (*desc)->desc_phys_addr );
1172 }
1173 *desc = NULL;
1174 return status;
1175 } // wl_pci_dma_free_desc
1176 /*============================================================================*/
1177
1178 /*******************************************************************************
1179 * wl_pci_dma_alloc_buf()
1180 *******************************************************************************
1181 *
1182 * DESCRIPTION:
1183 *
1184 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1185 * descriptor with this buffer.
1186 *
1187 * PARAMETERS:
1188 *
1189 * pdev - a pointer to the device's pci_dev structure
1190 * lp - the device's private adapter structure
1191 *
1192 * RETURNS:
1193 *
1194 * 0 on success
1195 * errno value otherwise
1196 *
1197 ******************************************************************************/
1198 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1199 DESC_STRCT *desc, int size )
1200 {
1201 int status = 0;
1202 dma_addr_t pa;
1203 /*------------------------------------------------------------------------*/
1204
1205 // DBG_FUNC( "wl_pci_dma_alloc_buf" );
1206 // DBG_ENTER( DbgInfo );
1207 //
1208 // if( desc == NULL ) {
1209 // status = -EFAULT;
1210 // }
1211 // if( status == 0 && desc->buf_addr != NULL ) {
1212 // status = -EFAULT;
1213 // }
1214 // if( status == 0 ) {
1215 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1216 // }
1217 // if( desc->buf_addr == NULL ) {
1218 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1219 // status = -ENOMEM;
1220 // } else {
1221 // desc->buf_phys_addr = cpu_to_le32( pa );
1222 // SET_BUF_SIZE( desc, size );
1223 // }
1224 // DBG_LEAVE( DbgInfo );
1225 return status;
1226 } // wl_pci_dma_alloc_buf
1227 /*============================================================================*/
1228
1229 /*******************************************************************************
1230 * wl_pci_dma_free_buf()
1231 *******************************************************************************
1232 *
1233 * DESCRIPTION:
1234 *
1235 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1236 * descriptor with this buffer.
1237 *
1238 * PARAMETERS:
1239 *
1240 * pdev - a pointer to the device's pci_dev structure
1241 * lp - the device's private adapter structure
1242 *
1243 * RETURNS:
1244 *
1245 * 0 on success
1246 * errno value otherwise
1247 *
1248 ******************************************************************************/
1249 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1250 DESC_STRCT *desc )
1251 {
1252 int status = 0;
1253 /*------------------------------------------------------------------------*/
1254
1255 if( desc == NULL ) {
1256 status = -EFAULT;
1257 }
1258 if( status == 0 && desc->buf_addr == NULL ) {
1259 status = -EFAULT;
1260 }
1261 if( status == 0 ) {
1262 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1263 desc->buf_phys_addr );
1264
1265 desc->buf_addr = 0;
1266 desc->buf_phys_addr = 0;
1267 SET_BUF_SIZE( desc, 0 );
1268 }
1269 return status;
1270 } // wl_pci_dma_free_buf
1271 /*============================================================================*/
1272
1273 /*******************************************************************************
1274 * wl_pci_dma_hcf_supply()
1275 *******************************************************************************
1276 *
1277 * DESCRIPTION:
1278 *
1279 * Supply HCF with DMA-related resources. These consist of:
1280 * - buffers and descriptors for receive purposes
1281 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1282 * certain H25 DMA engine requirement
1283 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1284 * certain H25 DMA engine requirement
1285 *
1286 * This function is called at start-of-day or at re-initialization.
1287 *
1288 * PARAMETERS:
1289 *
1290 * lp - the device's private adapter structure
1291 *
1292 * RETURNS:
1293 *
1294 * 0 on success
1295 * errno value otherwise
1296 *
1297 ******************************************************************************/
1298 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1299 {
1300 int i;
1301 /*------------------------------------------------------------------------*/
1302
1303 DBG_FUNC( "wl_pci_dma_hcf_supply" );
1304 DBG_ENTER( DbgInfo );
1305
1306 //if( lp->dma.status == 0 );
1307 //{
1308 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1309 if( lp->dma.tx_reclaim_desc ) {
1310 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1311 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1312 lp->dma.tx_reclaim_desc = NULL;
1313 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1314 }
1315 if( lp->dma.rx_reclaim_desc ) {
1316 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1317 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1318 lp->dma.rx_reclaim_desc = NULL;
1319 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1320 }
1321 /* Hand over the Rx descriptor chain to the HCF */
1322 for( i = 0; i < NUM_RX_DESC; i++ ) {
1323 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1324 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1325 lp->dma.rx_packet[i] = NULL;
1326 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1327 }
1328 //}
1329
1330 DBG_LEAVE( DbgInfo );
1331 return;
1332 } // wl_pci_dma_hcf_supply
1333 /*============================================================================*/
1334
1335 /*******************************************************************************
1336 * wl_pci_dma_hcf_reclaim()
1337 *******************************************************************************
1338 *
1339 * DESCRIPTION:
1340 *
1341 * Return DMA-related resources from the HCF. These consist of:
1342 * - buffers and descriptors for receive purposes
1343 * - buffers and descriptors for transmit purposes
1344 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1345 * certain H25 DMA engine requirement
1346 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1347 * certain H25 DMA engine requirement
1348 *
1349 * This function is called at end-of-day or at re-initialization.
1350 *
1351 * PARAMETERS:
1352 *
1353 * lp - the device's private adapter structure
1354 *
1355 * RETURNS:
1356 *
1357 * 0 on success
1358 * errno value otherwise
1359 *
1360 ******************************************************************************/
1361 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1362 {
1363 int i;
1364 /*------------------------------------------------------------------------*/
1365
1366 DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1367 DBG_ENTER( DbgInfo );
1368
1369 wl_pci_dma_hcf_reclaim_rx( lp );
1370 for( i = 0; i < NUM_RX_DESC; i++ ) {
1371 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1372 // if( lp->dma.rx_packet[i] == NULL ) {
1373 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1374 // }
1375 }
1376
1377 wl_pci_dma_hcf_reclaim_tx( lp );
1378 for( i = 0; i < NUM_TX_DESC; i++ ) {
1379 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1380 // if( lp->dma.tx_packet[i] == NULL ) {
1381 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1382 // }
1383 }
1384
1385 DBG_LEAVE( DbgInfo );
1386 return;
1387 } // wl_pci_dma_hcf_reclaim
1388 /*============================================================================*/
1389
1390 /*******************************************************************************
1391 * wl_pci_dma_hcf_reclaim_rx()
1392 *******************************************************************************
1393 *
1394 * DESCRIPTION:
1395 *
1396 * Reclaim Rx packets that have already been processed by the HCF.
1397 *
1398 * PARAMETERS:
1399 *
1400 * lp - the device's private adapter structure
1401 *
1402 * RETURNS:
1403 *
1404 * 0 on success
1405 * errno value otherwise
1406 *
1407 ******************************************************************************/
1408 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1409 {
1410 int i;
1411 DESC_STRCT *p;
1412 /*------------------------------------------------------------------------*/
1413
1414 DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1415 DBG_ENTER( DbgInfo );
1416
1417 //if( lp->dma.status == 0 )
1418 //{
1419 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1420 if( p && p->buf_addr == NULL ) {
1421 /* A reclaim descriptor is being given back by the HCF. Reclaim
1422 descriptors have a NULL buf_addr */
1423 lp->dma.rx_reclaim_desc = p;
1424 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1425 continue;
1426 }
1427 for( i = 0; i < NUM_RX_DESC; i++ ) {
1428 if( lp->dma.rx_packet[i] == NULL ) {
1429 break;
1430 }
1431 }
1432 /* An Rx buffer descriptor is being given back by the HCF */
1433 lp->dma.rx_packet[i] = p;
1434 lp->dma.rx_rsc_ind++;
1435 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1436 }
1437 //}
1438 DBG_LEAVE( DbgInfo );
1439 } // wl_pci_dma_hcf_reclaim_rx
1440 /*============================================================================*/
1441
1442 /*******************************************************************************
1443 * wl_pci_dma_get_tx_packet()
1444 *******************************************************************************
1445 *
1446 * DESCRIPTION:
1447 *
1448 * Obtains a Tx descriptor from the chain to use for Tx.
1449 *
1450 * PARAMETERS:
1451 *
1452 * lp - a pointer to the device's wl_private structure.
1453 *
1454 * RETURNS:
1455 *
1456 * A pointer to the retrieved descriptor
1457 *
1458 ******************************************************************************/
1459 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1460 {
1461 int i;
1462 DESC_STRCT *desc = NULL;
1463 /*------------------------------------------------------------------------*/
1464
1465 for( i = 0; i < NUM_TX_DESC; i++ ) {
1466 if( lp->dma.tx_packet[i] ) {
1467 break;
1468 }
1469 }
1470
1471 if( i != NUM_TX_DESC ) {
1472 desc = lp->dma.tx_packet[i];
1473
1474 lp->dma.tx_packet[i] = NULL;
1475 lp->dma.tx_rsc_ind--;
1476
1477 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1478 }
1479
1480 return desc;
1481 } // wl_pci_dma_get_tx_packet
1482 /*============================================================================*/
1483
1484 /*******************************************************************************
1485 * wl_pci_dma_put_tx_packet()
1486 *******************************************************************************
1487 *
1488 * DESCRIPTION:
1489 *
1490 * Returns a Tx descriptor to the chain.
1491 *
1492 * PARAMETERS:
1493 *
1494 * lp - a pointer to the device's wl_private structure.
1495 * desc - a pointer to the descriptor to return.
1496 *
1497 * RETURNS:
1498 *
1499 * N/A
1500 *
1501 ******************************************************************************/
1502 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1503 {
1504 int i;
1505 /*------------------------------------------------------------------------*/
1506
1507 for( i = 0; i < NUM_TX_DESC; i++ ) {
1508 if( lp->dma.tx_packet[i] == NULL ) {
1509 break;
1510 }
1511 }
1512
1513 if( i != NUM_TX_DESC ) {
1514 lp->dma.tx_packet[i] = desc;
1515 lp->dma.tx_rsc_ind++;
1516 }
1517 } // wl_pci_dma_put_tx_packet
1518 /*============================================================================*/
1519
1520 /*******************************************************************************
1521 * wl_pci_dma_hcf_reclaim_tx()
1522 *******************************************************************************
1523 *
1524 * DESCRIPTION:
1525 *
1526 * Reclaim Tx packets that have either been processed by the HCF due to a
1527 * port disable or a Tx completion.
1528 *
1529 * PARAMETERS:
1530 *
1531 * lp - the device's private adapter structure
1532 *
1533 * RETURNS:
1534 *
1535 * 0 on success
1536 * errno value otherwise
1537 *
1538 ******************************************************************************/
1539 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1540 {
1541 int i;
1542 DESC_STRCT *p;
1543 /*------------------------------------------------------------------------*/
1544
1545 DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1546 DBG_ENTER( DbgInfo );
1547
1548 //if( lp->dma.status == 0 )
1549 //{
1550 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1551
1552 if( p != NULL && p->buf_addr == NULL ) {
1553 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1554 descriptors have a NULL buf_addr */
1555 lp->dma.tx_reclaim_desc = p;
1556 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1557 continue;
1558 }
1559 for( i = 0; i < NUM_TX_DESC; i++ ) {
1560 if( lp->dma.tx_packet[i] == NULL ) {
1561 break;
1562 }
1563 }
1564 /* An Rx buffer descriptor is being given back by the HCF */
1565 lp->dma.tx_packet[i] = p;
1566 lp->dma.tx_rsc_ind++;
1567 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1568 }
1569 //}
1570
1571 if( lp->netif_queue_on == FALSE ) {
1572 netif_wake_queue( lp->dev );
1573 WL_WDS_NETIF_WAKE_QUEUE( lp );
1574 lp->netif_queue_on = TRUE;
1575 }
1576 DBG_LEAVE( DbgInfo );
1577 return;
1578 } // wl_pci_dma_hcf_reclaim_tx
1579 /*============================================================================*/
1580 #endif // ENABLE_DMA