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