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