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