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