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