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