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