1/******************************************************************************* 2 * Agere Systems Inc. 3 * Wireless device driver for Linux (wlags49). 4 * 5 * Copyright (c) 1998-2003 Agere Systems Inc. 6 * All rights reserved. 7 * http://www.agere.com 8 * 9 * Initially developed by TriplePoint, Inc. 10 * http://www.triplepoint.com 11 * 12 *------------------------------------------------------------------------------ 13 * 14 * This file contains processing and initialization specific to PCI/miniPCI 15 * devices. 16 * 17 *------------------------------------------------------------------------------ 18 * 19 * SOFTWARE LICENSE 20 * 21 * This software is provided subject to the following terms and conditions, 22 * which you should read carefully before using the software. Using this 23 * software indicates your acceptance of these terms and conditions. If you do 24 * not agree with these terms and conditions, do not use the software. 25 * 26 * Copyright © 2003 Agere Systems Inc. 27 * All rights reserved. 28 * 29 * Redistribution and use in source or binary forms, with or without 30 * modifications, are permitted provided that the following conditions are met: 31 * 32 * . Redistributions of source code must retain the above copyright notice, this 33 * list of conditions and the following Disclaimer as comments in the code as 34 * well as in the documentation and/or other materials provided with the 35 * distribution. 36 * 37 * . Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following Disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * . Neither the name of Agere Systems Inc. nor the names of the contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * Disclaimer 46 * 47 * THIS SOFTWARE IS PROVIDED AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, 48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF 49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY 50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN 51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY 52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 58 * DAMAGE. 59 * 60 ******************************************************************************/ 61 62/******************************************************************************* 63 * include files 64 ******************************************************************************/ 65#include <wireless/wl_version.h> 66 67#include <linux/module.h> 68#include <linux/kernel.h> 69#include <linux/errno.h> 70#include <linux/pci.h> 71#include <linux/init.h> 72#include <linux/sched.h> 73#include <linux/ptrace.h> 74#include <linux/ctype.h> 75#include <linux/string.h> 76//#include <linux/timer.h> 77#include <linux/interrupt.h> 78#include <linux/in.h> 79#include <linux/delay.h> 80#include <asm/io.h> 81#include <asm/irq.h> 82#include <asm/bitops.h> 83#include <asm/uaccess.h> 84 85#include <linux/ethtool.h> 86#include <linux/netdevice.h> 87#include <linux/etherdevice.h> 88#include <linux/skbuff.h> 89#include <linux/if_arp.h> 90#include <linux/ioport.h> 91 92#include <hcf/debug.h> 93 94#include <hcf.h> 95#include <dhf.h> 96#include <hcfdef.h> 97 98#include <wireless/wl_if.h> 99#include <wireless/wl_internal.h> 100#include <wireless/wl_util.h> 101#include <wireless/wl_main.h> 102#include <wireless/wl_netdev.h> 103#include <wireless/wl_pci.h> 104 105 106/******************************************************************************* 107 * global variables 108 ******************************************************************************/ 109#if DBG 110extern dbg_info_t *DbgInfo; 111#endif // DBG 112 113/* define the PCI device Table Cardname and id tables */ 114static struct pci_device_id wl_pci_tbl[] = { 115 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), }, 116 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), }, 117 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), }, 118 119 { } /* Terminating entry */ 120}; 121 122MODULE_DEVICE_TABLE(pci, wl_pci_tbl); 123 124/******************************************************************************* 125 * function prototypes 126 ******************************************************************************/ 127int wl_pci_probe( struct pci_dev *pdev, 128 const struct pci_device_id *ent ); 129void wl_pci_remove(struct pci_dev *pdev); 130int 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 ******************************************************************************/ 163static 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 170}; 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{ 225 //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module 226 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 387 * PCI subsystem finds a new PCI device which matches the information contained 388 * 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 ******************************************************************************/ 401int wl_pci_probe( struct pci_dev *pdev, 402 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 426 * PCI subsystem detects that a PCI device which matches the information 427 * 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 ******************************************************************************/ 438void wl_pci_remove(struct pci_dev *pdev) 439{ 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 452 dev = pci_get_drvdata( pdev ); 453 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 463 wl_pci_dma_free( pdev, dev->priv ); 464#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" ); 526 wl_device_dealloc(dev); 527 DBG_LEAVE( DbgInfo ); 528 return -ENOMEM; 529 } 530 531#ifdef ENABLE_DMA 532 /* Allocate DMA Descriptors */ 533 if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) { 534 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" ); 535 wl_device_dealloc(dev); 536 DBG_LEAVE( DbgInfo ); 537 return -ENOMEM; 538 } 539#endif 540 541 /* Register our private adapter structure with PCI */ 542 pci_set_drvdata( pdev, dev ); 543 544 /* Fill out bus specific information in the net_device struct */ 545 dev->irq = pdev->irq; 546 SET_MODULE_OWNER( dev ); 547 548 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start ); 549 dev->base_addr = pdev->resource[0].start; 550 551 /* Initialize our device here */ 552 if( !wl_adapter_insert( dev )) { 553 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" ); 554 wl_device_dealloc( dev ); 555 DBG_LEAVE( DbgInfo ); 556 return -EINVAL; 557 } 558 559 /* Register our ISR */ 560 DBG_TRACE( DbgInfo, "Registering ISR...\n" ); 561 562 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev); 563 if( result ) { 564 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" ); 565 wl_remove(dev); 566 wl_device_dealloc(dev); 567 DBG_LEAVE( DbgInfo ); 568 return result; 569 } 570 571 /* Make sure interrupts are enabled properly for CardBus */ 572 lp = dev->priv; 573 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 901 * contiguous buffer. The buffer starts with the hermes-specific header. 902 * 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 1579