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