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