Ignore:
Timestamp:
2006-06-19T21:59:53+02:00 (10 years ago)
Author:
nbd
Message:

remove the wl.o build from the kernel patch and move the driver along with wl, nas and wlc into packages/broadcom-wl

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/buildroot-ng/openwrt/target/linux/brcm-2.4/patches/001-bcm47xx.patch

    r4003 r4009  
    1588715887 # 
    1588815888 if [ "$CONFIG_ACER_PICA_61" = "y" ]; then 
    15889 @@ -554,6 +567,13 @@ 
     15889@@ -554,6 +567,12 @@ 
    1589015890    define_bool CONFIG_SWAP_IO_SPACE_L y 
    1589115891    define_bool CONFIG_BOOT_ELF32 y 
     
    1589615896+   define_bool CONFIG_NEW_TIME_C y 
    1589715897+   define_bool CONFIG_NEW_IRQ y 
    15898 +   define_bool CONFIG_HND y 
    1589915898+fi 
    1590015899 if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then 
     
    1626616265 #if defined(__powerpc__) || defined(__alpha__) 
    1626716266        cval >>= 8; 
    16268 diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in 
    16269 --- linux.old/drivers/net/Config.in     2006-04-27 18:04:38.000000000 +0200 
    16270 +++ linux.dev/drivers/net/Config.in     2006-04-27 19:24:19.000000000 +0200 
    16271 @@ -2,6 +2,8 @@ 
    16272  # Network device configuration 
    16273  # 
    16274   
    16275 +tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI 
    16276 + 
    16277  source drivers/net/arcnet/Config.in 
    16278   
    16279  tristate 'Dummy net driver support' CONFIG_DUMMY 
    1628016267diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile 
    1628116268--- linux.old/drivers/net/Makefile      2006-04-27 18:04:38.000000000 +0200 
     
    1629016277 obj-m           := 
    1629116278 obj-n           := 
    16292 @@ -39,6 +41,7 @@ 
    16293    obj-$(CONFIG_ISDN) += slhc.o 
    16294  endif 
    16295   
    16296 +subdir-$(CONFIG_WL) += wl 
    16297  subdir-$(CONFIG_NET_PCMCIA) += pcmcia 
    16298  subdir-$(CONFIG_NET_WIRELESS) += wireless 
    16299  subdir-$(CONFIG_TULIP) += tulip 
    16300 diff -urN linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in 
    16301 --- linux.old/drivers/net/wireless/Config.in    2006-04-27 18:04:38.000000000 +0200 
    16302 +++ linux.dev/drivers/net/wireless/Config.in    2006-05-04 01:42:48.000000000 +0200 
    16303 @@ -13,6 +13,7 @@ 
    16304  fi 
    16305   
    16306  if [ "$CONFIG_PCI" = "y" ]; then 
    16307 +   dep_tristate '    Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL 
    16308     dep_tristate '    Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL 
    16309     dep_tristate '    Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL 
    16310     dep_tristate '    Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL 
    16311 diff -urN linux.old/drivers/net/wl/patchtable.pl linux.dev/drivers/net/wl/patchtable.pl 
    16312 --- linux.old/drivers/net/wl/patchtable.pl      1970-01-01 01:00:00.000000000 +0100 
    16313 +++ linux.dev/drivers/net/wl/patchtable.pl      2006-04-28 01:33:52.000000000 +0200 
    16314 @@ -0,0 +1,54 @@ 
    16315 +#!/usr/bin/perl 
    16316 +use strict; 
    16317 + 
    16318 +my $TABLE = pack("V", 0xbadc0ded); 
    16319 +my $TABLE_SIZE = 512; 
    16320 +my $SLT1 = "\x01\x00\x00\x00"; 
    16321 +my $SLT2 = "\x02\x00\x00\x00"; 
    16322 +my $ACKW = "\x03\x00\x00\x00"; 
    16323 +my $PTABLE_END = "\xff\xff\xff\xff"; 
    16324 + 
    16325 +my $addr = ""; 
    16326 +my $opcode = ""; 
    16327 +my $function = ""; 
    16328 + 
    16329 +sub add_entry { 
    16330 +       my $key = shift; 
    16331 +       my $value = shift; 
    16332 +       my $default = shift; 
    16333 + 
    16334 +       $TABLE .= $key; 
    16335 +       $TABLE .= pack("V", $value); 
    16336 +       $TABLE .= pack("V", $default); 
    16337 +} 
    16338 + 
    16339 +while (<>) { 
    16340 +       $addr = $opcode = ""; 
    16341 +       /^\w{8}\s*<(.*)>:$/ and $function = $1; 
    16342 +       /^\s*(\w+):\s*(\w{8})\s*/ and do { 
    16343 +               $addr = $1; 
    16344 +               $opcode = $2; 
    16345 +       }; 
    16346 + 
    16347 +       ($function eq 'wlc_update_slot_timing') and do { 
    16348 +               # li    a2,9    -- short slot time 
    16349 +               ($opcode eq '24060009') and add_entry($SLT1, hex($addr), hex($opcode)); 
    16350 +               # li    v0,519  -- 510 + short slot time 
    16351 +               ($opcode eq '24020207') and add_entry($SLT2, hex($addr), hex($opcode)); 
    16352 +                
    16353 +               # li    a2,20   -- long slot time 
    16354 +               ($opcode eq '24060014') and add_entry($SLT1, hex($addr), hex($opcode)); 
    16355 +               # li    v0,530  -- 510 + long slot time 
    16356 +               ($opcode eq '24020212') and add_entry($SLT2, hex($addr), hex($opcode)); 
    16357 +       }; 
    16358 +       ($function eq 'wlc_d11hdrs') and do { 
    16359 +               # ori   s6,s6,0x1 -- ack flag (new) 
    16360 +               ($opcode eq '36d60001') and add_entry($ACKW, hex($addr), hex($opcode)); 
    16361 +               # ori   s3,s3,0x1 -- ack flag (old) 
    16362 +               ($opcode eq '36730001') and add_entry($ACKW, hex($addr), hex($opcode)); 
    16363 +       } 
    16364 +} 
    16365 + 
    16366 +$TABLE .= $PTABLE_END; 
    16367 +$TABLE .= ("\x00" x ($TABLE_SIZE - length($TABLE))); 
    16368 +print $TABLE; 
    16369 diff -urN linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile 
    16370 --- linux.old/drivers/net/wl/Makefile   1970-01-01 01:00:00.000000000 +0100 
    16371 +++ linux.dev/drivers/net/wl/Makefile   2006-04-28 01:33:52.000000000 +0200 
    16372 @@ -0,0 +1,32 @@ 
    16373 +# 
    16374 +# Makefile for the Broadcom wl driver 
    16375 +# 
    16376 +# Copyright 2004, Broadcom Corporation 
    16377 +# All Rights Reserved. 
    16378 +#  
    16379 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    16380 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    16381 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    16382 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    16383 +# 
    16384 +# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ 
    16385 + 
    16386 +EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER 
    16387 + 
    16388 +O_TARGET       := wl_link.o 
    16389 + 
    16390 +obj-y          := wl_mod.o 
    16391 +obj-y          += bcmutils.o hnddma.o linux_osl.o 
    16392 + 
    16393 +obj-m          := $(O_TARGET) 
    16394 + 
    16395 +wl_mod.o: wl_apsta.o 
    16396 +       sed -e 's,eth%d,wl%d\x00,g' < $< > $@ 
    16397 + 
    16398 +wl.o: wl_link.o 
    16399 +       $(OBJDUMP) -d $< | perl patchtable.pl > patchtable.bin 
    16400 +       cat wl_link.o patchtable.bin > $@ 
    16401 + 
    16402 +modules: wl.o 
    16403 + 
    16404 +include $(TOPDIR)/Rules.make 
    16405 diff -urN linux.old/drivers/net/wl/bcmip.h linux.dev/drivers/net/wl/bcmip.h 
    16406 --- linux.old/drivers/net/wl/bcmip.h    1970-01-01 01:00:00.000000000 +0100 
    16407 +++ linux.dev/drivers/net/wl/bcmip.h    2006-04-28 02:11:28.000000000 +0200 
    16408 @@ -0,0 +1,101 @@ 
    16409 +/* 
    16410 + * Copyright 2006, Broadcom Corporation 
    16411 + * All Rights Reserved. 
    16412 + *  
    16413 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    16414 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    16415 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    16416 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    16417 + * 
    16418 + * Fundamental constants relating to IP Protocol 
    16419 + * 
    16420 + * $Id: bcmip.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ 
    16421 + */ 
    16422 + 
    16423 +#ifndef _bcmip_h_ 
    16424 +#define _bcmip_h_ 
    16425 + 
    16426 +/* IPV4 and IPV6 common */ 
    16427 +#define IP_VER_OFFSET          0x0     /* offset to version field */ 
    16428 +#define IP_VER_MASK            0xf0    /* version mask */ 
    16429 +#define IP_VER_SHIFT           4       /* version shift */ 
    16430 +#define IP_VER_4               4       /* version number for IPV4 */ 
    16431 +#define IP_VER_6               6       /* version number for IPV6 */ 
    16432 + 
    16433 +#define IP_VER(ip_body) \ 
    16434 +       ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) 
    16435 + 
    16436 +#define IP_PROT_ICMP           0x1     /* ICMP protocol */ 
    16437 +#define IP_PROT_TCP            0x6     /* TCP protocol */ 
    16438 +#define IP_PROT_UDP            0x11    /* UDP protocol type */ 
    16439 + 
    16440 +/* IPV4 field offsets */ 
    16441 +#define IPV4_VER_HL_OFFSET     0       /* version and ihl byte offset */ 
    16442 +#define IPV4_TOS_OFFSET                1       /* type of service offset */ 
    16443 +#define IPV4_PROT_OFFSET       9       /* protocol type offset */ 
    16444 +#define IPV4_CHKSUM_OFFSET     10      /* IP header checksum offset */ 
    16445 +#define IPV4_SRC_IP_OFFSET     12      /* src IP addr offset */ 
    16446 +#define IPV4_DEST_IP_OFFSET    16      /* dest IP addr offset */ 
    16447 + 
    16448 +/* IPV4 field decodes */ 
    16449 +#define IPV4_VER_MASK          0xf0    /* IPV4 version mask */ 
    16450 +#define IPV4_VER_SHIFT         4       /* IPV4 version shift */ 
    16451 + 
    16452 +#define IPV4_HLEN_MASK         0x0f    /* IPV4 header length mask */ 
    16453 +#define IPV4_HLEN(ipv4_body)   (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) 
    16454 + 
    16455 +#define IPV4_ADDR_LEN          4       /* IPV4 address length */ 
    16456 + 
    16457 +#define IPV4_ADDR_NULL(a)      ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ 
    16458 +                                 ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) 
    16459 + 
    16460 +#define        IPV4_TOS_DSCP_MASK      0xfc    /* DiffServ codepoint mask */ 
    16461 +#define        IPV4_TOS_DSCP_SHIFT     2       /* DiffServ codepoint shift */ 
    16462 + 
    16463 +#define        IPV4_TOS(ipv4_body)     (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) 
    16464 + 
    16465 +#define        IPV4_TOS_PREC_MASK      0xe0    /* Historical precedence mask */ 
    16466 +#define        IPV4_TOS_PREC_SHIFT     5       /* Historical precedence shift */ 
    16467 + 
    16468 +#define IPV4_TOS_LOWDELAY      0x10    /* Lowest delay requested */ 
    16469 +#define IPV4_TOS_THROUGHPUT    0x8     /* Best throughput requested */ 
    16470 +#define IPV4_TOS_RELIABILITY   0x4     /* Most reliable delivery requested */ 
    16471 + 
    16472 +#define IPV4_PROT(ipv4_body)   (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) 
    16473 + 
    16474 +#define IPV4_ADDR_STR_LEN      16      /* Max IP address length in string format */ 
    16475 + 
    16476 +/* IPV6 field offsets */ 
    16477 +#define IPV6_PAYLOAD_LEN_OFFSET        4       /* payload length offset */ 
    16478 +#define IPV6_NEXT_HDR_OFFSET   6       /* next header/protocol offset */ 
    16479 +#define IPV6_HOP_LIMIT_OFFSET  7       /* hop limit offset */ 
    16480 +#define IPV6_SRC_IP_OFFSET     8       /* src IP addr offset */ 
    16481 +#define IPV6_DEST_IP_OFFSET    24      /* dst IP addr offset */ 
    16482 + 
    16483 +/* IPV6 field decodes */ 
    16484 +#define IPV6_TRAFFIC_CLASS(ipv6_body) \ 
    16485 +       (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ 
    16486 +        ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) 
    16487 + 
    16488 +#define IPV6_FLOW_LABEL(ipv6_body) \ 
    16489 +       (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ 
    16490 +        (((uint8 *)(ipv6_body))[2] << 8) | \ 
    16491 +        (((uint8 *)(ipv6_body))[3])) 
    16492 + 
    16493 +#define IPV6_PAYLOAD_LEN(ipv6_body) \ 
    16494 +       ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ 
    16495 +        ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) 
    16496 + 
    16497 +#define IPV6_NEXT_HDR(ipv6_body) \ 
    16498 +       (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) 
    16499 + 
    16500 +#define IPV6_PROT(ipv6_body)   IPV6_NEXT_HDR(ipv6_body) 
    16501 + 
    16502 +#define IPV6_ADDR_LEN          16      /* IPV6 address length */ 
    16503 + 
    16504 +/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ 
    16505 +#define IP_TOS(ip_body) \ 
    16506 +       (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ 
    16507 +        IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) 
    16508 + 
    16509 +#endif /* _bcmip_h_ */ 
    16510 diff -urN linux.old/drivers/net/wl/bcmutils.c linux.dev/drivers/net/wl/bcmutils.c 
    16511 --- linux.old/drivers/net/wl/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 
    16512 +++ linux.dev/drivers/net/wl/bcmutils.c 2006-04-28 02:27:20.000000000 +0200 
    16513 @@ -0,0 +1,857 @@ 
    16514 +/* 
    16515 + * Misc useful OS-independent routines. 
    16516 + * 
    16517 + * Copyright 2006, Broadcom Corporation 
    16518 + * All Rights Reserved. 
    16519 + *  
    16520 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    16521 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    16522 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    16523 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    16524 + * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ 
    16525 + */ 
    16526 + 
    16527 +#include <typedefs.h> 
    16528 +#include <bcmdefs.h> 
    16529 +#include <stdarg.h> 
    16530 +#include <osl.h> 
    16531 +#include "linux_osl.h" 
    16532 +#include "pktq.h" 
    16533 +#include <bcmutils.h> 
    16534 +#include <sbutils.h> 
    16535 +#include <bcmnvram.h> 
    16536 +#include <bcmendian.h> 
    16537 +#include <bcmdevs.h> 
    16538 +#include "bcmip.h" 
    16539 + 
    16540 +#define ETHER_TYPE_8021Q       0x8100 
    16541 +#define ETHER_TYPE_IP          0x0800 
    16542 +#define VLAN_PRI_SHIFT             13 
    16543 +#define VLAN_PRI_MASK               7 
    16544 + 
    16545 + 
    16546 +struct  ether_header { 
    16547 +       uint8   ether_dhost[6]; 
    16548 +       uint8   ether_shost[6]; 
    16549 +       uint16  ether_type; 
    16550 +} __attribute__((packed)); 
    16551 + 
    16552 + 
    16553 +struct ethervlan_header { 
    16554 +       uint8   ether_dhost[6]; 
    16555 +       uint8   ether_shost[6]; 
    16556 +       uint16  vlan_type;              /* 0x8100 */ 
    16557 +       uint16  vlan_tag;               /* priority, cfi and vid */ 
    16558 +       uint16  ether_type; 
    16559 +}; 
    16560 + 
    16561 +/* copy a pkt buffer chain into a buffer */ 
    16562 +uint 
    16563 +pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) 
    16564 +{ 
    16565 +       uint n, ret = 0; 
    16566 + 
    16567 +       if (len < 0) 
    16568 +               len = 4096;     /* "infinite" */ 
    16569 + 
    16570 +       /* skip 'offset' bytes */ 
    16571 +       for (; p && offset; p = PKTNEXT(osh, p)) { 
    16572 +               if (offset < (uint)PKTLEN(osh, p)) 
    16573 +                       break; 
    16574 +               offset -= PKTLEN(osh, p); 
    16575 +       } 
    16576 + 
    16577 +       if (!p) 
    16578 +               return 0; 
    16579 + 
    16580 +       /* copy the data */ 
    16581 +       for (; p && len; p = PKTNEXT(osh, p)) { 
    16582 +               n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); 
    16583 +               bcopy(PKTDATA(osh, p) + offset, buf, n); 
    16584 +               buf += n; 
    16585 +               len -= n; 
    16586 +               ret += n; 
    16587 +               offset = 0; 
    16588 +       } 
    16589 + 
    16590 +       return ret; 
    16591 +} 
    16592 + 
    16593 +/* return total length of buffer chain */ 
    16594 +uint 
    16595 +pkttotlen(osl_t *osh, void *p) 
    16596 +{ 
    16597 +       uint total; 
    16598 + 
    16599 +       total = 0; 
    16600 +       for (; p; p = PKTNEXT(osh, p)) 
    16601 +               total += PKTLEN(osh, p); 
    16602 +       return (total); 
    16603 +} 
    16604 + 
    16605 +/* return the last buffer of chained pkt */ 
    16606 +void * 
    16607 +pktlast(osl_t *osh, void *p) 
    16608 +{ 
    16609 +       for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) 
    16610 +               ; 
    16611 + 
    16612 +       return (p); 
    16613 +} 
    16614 + 
    16615 + 
    16616 +/* 
    16617 + * osl multiple-precedence packet queue 
    16618 + * hi_prec is always >= the number of the highest non-empty queue 
    16619 + */ 
    16620 +void * 
    16621 +pktq_penq(struct pktq *pq, int prec, void *p) 
    16622 +{ 
    16623 +       struct pktq_prec *q; 
    16624 + 
    16625 +       ASSERT(prec >= 0 && prec < pq->num_prec); 
    16626 +       ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */ 
    16627 + 
    16628 +       ASSERT(!pktq_full(pq)); 
    16629 +       ASSERT(!pktq_pfull(pq, prec)); 
    16630 + 
    16631 +       q = &pq->q[prec]; 
    16632 + 
    16633 +       if (q->head) 
    16634 +               PKTSETLINK(q->tail, p); 
    16635 +       else 
    16636 +               q->head = p; 
    16637 + 
    16638 +       q->tail = p; 
    16639 +       q->len++; 
    16640 + 
    16641 +       pq->len++; 
    16642 + 
    16643 +       if (pq->hi_prec < prec) 
    16644 +               pq->hi_prec = (uint8)prec; 
    16645 + 
    16646 +       return p; 
    16647 +} 
    16648 + 
    16649 +void * 
    16650 +pktq_penq_head(struct pktq *pq, int prec, void *p) 
    16651 +{ 
    16652 +       struct pktq_prec *q; 
    16653 + 
    16654 +       ASSERT(prec >= 0 && prec < pq->num_prec); 
    16655 +       ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */ 
    16656 + 
    16657 +       ASSERT(!pktq_full(pq)); 
    16658 +       ASSERT(!pktq_pfull(pq, prec)); 
    16659 + 
    16660 +       q = &pq->q[prec]; 
    16661 + 
    16662 +       if (q->head == NULL) 
    16663 +               q->tail = p; 
    16664 + 
    16665 +       PKTSETLINK(p, q->head); 
    16666 +       q->head = p; 
    16667 +       q->len++; 
    16668 + 
    16669 +       pq->len++; 
    16670 + 
    16671 +       if (pq->hi_prec < prec) 
    16672 +               pq->hi_prec = (uint8)prec; 
    16673 + 
    16674 +       return p; 
    16675 +} 
    16676 + 
    16677 +void * 
    16678 +pktq_pdeq(struct pktq *pq, int prec) 
    16679 +{ 
    16680 +       struct pktq_prec *q; 
    16681 +       void *p; 
    16682 + 
    16683 +       ASSERT(prec >= 0 && prec < pq->num_prec); 
    16684 + 
    16685 +       q = &pq->q[prec]; 
    16686 + 
    16687 +       if ((p = q->head) == NULL) 
    16688 +               return NULL; 
    16689 + 
    16690 +       if ((q->head = PKTLINK(p)) == NULL) 
    16691 +               q->tail = NULL; 
    16692 + 
    16693 +       q->len--; 
    16694 + 
    16695 +       pq->len--; 
    16696 + 
    16697 +       PKTSETLINK(p, NULL); 
    16698 + 
    16699 +       return p; 
    16700 +} 
    16701 + 
    16702 +void * 
    16703 +pktq_pdeq_tail(struct pktq *pq, int prec) 
    16704 +{ 
    16705 +       struct pktq_prec *q; 
    16706 +       void *p, *prev; 
    16707 + 
    16708 +       ASSERT(prec >= 0 && prec < pq->num_prec); 
    16709 + 
    16710 +       q = &pq->q[prec]; 
    16711 + 
    16712 +       if ((p = q->head) == NULL) 
    16713 +               return NULL; 
    16714 + 
    16715 +       for (prev = NULL; p != q->tail; p = PKTLINK(p)) 
    16716 +               prev = p; 
    16717 + 
    16718 +       if (prev) 
    16719 +               PKTSETLINK(prev, NULL); 
    16720 +       else 
    16721 +               q->head = NULL; 
    16722 + 
    16723 +       q->tail = prev; 
    16724 +       q->len--; 
    16725 + 
    16726 +       pq->len--; 
    16727 + 
    16728 +       return p; 
    16729 +} 
    16730 + 
    16731 +void 
    16732 +pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) 
    16733 +{ 
    16734 +       struct pktq_prec *q; 
    16735 +       void *p; 
    16736 + 
    16737 +       q = &pq->q[prec]; 
    16738 +       p = q->head; 
    16739 +       while (p) { 
    16740 +               q->head = PKTLINK(p); 
    16741 +               PKTSETLINK(p, NULL); 
    16742 +               PKTFREE(osh, p, dir); 
    16743 +               q->len--; 
    16744 +               pq->len--; 
    16745 +               p = q->head; 
    16746 +       } 
    16747 +       ASSERT(q->len == 0); 
    16748 +       q->tail = NULL; 
    16749 +} 
    16750 + 
    16751 +bool 
    16752 +pktq_pdel(struct pktq *pq, void *pktbuf, int prec) 
    16753 +{ 
    16754 +       struct pktq_prec *q; 
    16755 +       void *p; 
    16756 + 
    16757 +       ASSERT(prec >= 0 && prec < pq->num_prec); 
    16758 + 
    16759 +       if (!pktbuf) 
    16760 +               return FALSE; 
    16761 + 
    16762 +       q = &pq->q[prec]; 
    16763 + 
    16764 +       if (q->head == pktbuf) { 
    16765 +               if ((q->head = PKTLINK(pktbuf)) == NULL) 
    16766 +                       q->tail = NULL; 
    16767 +       } else { 
    16768 +               for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) 
    16769 +                       ; 
    16770 +               if (p == NULL) 
    16771 +                       return FALSE; 
    16772 + 
    16773 +               PKTSETLINK(p, PKTLINK(pktbuf)); 
    16774 +               if (q->tail == pktbuf) 
    16775 +                       q->tail = p; 
    16776 +       } 
    16777 + 
    16778 +       q->len--; 
    16779 +       pq->len--; 
    16780 +       PKTSETLINK(pktbuf, NULL); 
    16781 +       return TRUE; 
    16782 +} 
    16783 + 
    16784 +void 
    16785 +pktq_init(struct pktq *pq, int num_prec, int max_len) 
    16786 +{ 
    16787 +       int prec; 
    16788 + 
    16789 +       ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); 
    16790 + 
    16791 +       bzero(pq, sizeof(*pq)); 
    16792 + 
    16793 +       pq->num_prec = (uint16)num_prec; 
    16794 + 
    16795 +       pq->max = (uint16)max_len; 
    16796 + 
    16797 +       for (prec = 0; prec < num_prec; prec++) 
    16798 +               pq->q[prec].max = pq->max; 
    16799 +} 
    16800 + 
    16801 +void * 
    16802 +pktq_deq(struct pktq *pq, int *prec_out) 
    16803 +{ 
    16804 +       struct pktq_prec *q; 
    16805 +       void *p; 
    16806 +       int prec; 
    16807 + 
    16808 +       if (pq->len == 0) 
    16809 +               return NULL; 
    16810 + 
    16811 +       while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    16812 +               pq->hi_prec--; 
    16813 + 
    16814 +       q = &pq->q[prec]; 
    16815 + 
    16816 +       if ((p = q->head) == NULL) 
    16817 +               return NULL; 
    16818 + 
    16819 +       if ((q->head = PKTLINK(p)) == NULL) 
    16820 +               q->tail = NULL; 
    16821 + 
    16822 +       q->len--; 
    16823 + 
    16824 +       pq->len--; 
    16825 + 
    16826 +       if (prec_out) 
    16827 +               *prec_out = prec; 
    16828 + 
    16829 +       PKTSETLINK(p, NULL); 
    16830 + 
    16831 +       return p; 
    16832 +} 
    16833 + 
    16834 +void * 
    16835 +pktq_deq_tail(struct pktq *pq, int *prec_out) 
    16836 +{ 
    16837 +       struct pktq_prec *q; 
    16838 +       void *p, *prev; 
    16839 +       int prec; 
    16840 + 
    16841 +       if (pq->len == 0) 
    16842 +               return NULL; 
    16843 + 
    16844 +       for (prec = 0; prec < pq->hi_prec; prec++) 
    16845 +               if (pq->q[prec].head) 
    16846 +                       break; 
    16847 + 
    16848 +       q = &pq->q[prec]; 
    16849 + 
    16850 +       if ((p = q->head) == NULL) 
    16851 +               return NULL; 
    16852 + 
    16853 +       for (prev = NULL; p != q->tail; p = PKTLINK(p)) 
    16854 +               prev = p; 
    16855 + 
    16856 +       if (prev) 
    16857 +               PKTSETLINK(prev, NULL); 
    16858 +       else 
    16859 +               q->head = NULL; 
    16860 + 
    16861 +       q->tail = prev; 
    16862 +       q->len--; 
    16863 + 
    16864 +       pq->len--; 
    16865 + 
    16866 +       if (prec_out) 
    16867 +               *prec_out = prec; 
    16868 + 
    16869 +       PKTSETLINK(p, NULL); 
    16870 + 
    16871 +       return p; 
    16872 +} 
    16873 + 
    16874 +void * 
    16875 +pktq_peek(struct pktq *pq, int *prec_out) 
    16876 +{ 
    16877 +       int prec; 
    16878 + 
    16879 +       if (pq->len == 0) 
    16880 +               return NULL; 
    16881 + 
    16882 +       while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    16883 +               pq->hi_prec--; 
    16884 + 
    16885 +       if (prec_out) 
    16886 +               *prec_out = prec; 
    16887 + 
    16888 +       return (pq->q[prec].head); 
    16889 +} 
    16890 + 
    16891 +void * 
    16892 +pktq_peek_tail(struct pktq *pq, int *prec_out) 
    16893 +{ 
    16894 +       int prec; 
    16895 + 
    16896 +       if (pq->len == 0) 
    16897 +               return NULL; 
    16898 + 
    16899 +       for (prec = 0; prec < pq->hi_prec; prec++) 
    16900 +               if (pq->q[prec].head) 
    16901 +                       break; 
    16902 + 
    16903 +       if (prec_out) 
    16904 +               *prec_out = prec; 
    16905 + 
    16906 +       return (pq->q[prec].tail); 
    16907 +} 
    16908 + 
    16909 +void 
    16910 +pktq_flush(osl_t *osh, struct pktq *pq, bool dir) 
    16911 +{ 
    16912 +       int prec; 
    16913 +       for (prec = 0; prec < pq->num_prec; prec++) 
    16914 +               pktq_pflush(osh, pq, prec, dir); 
    16915 +       ASSERT(pq->len == 0); 
    16916 +} 
    16917 + 
    16918 +/* Return sum of lengths of a specific set of precedences */ 
    16919 +int 
    16920 +pktq_mlen(struct pktq *pq, uint prec_bmp) 
    16921 +{ 
    16922 +       int prec, len; 
    16923 + 
    16924 +       len = 0; 
    16925 + 
    16926 +       for (prec = 0; prec <= pq->hi_prec; prec++) 
    16927 +               if (prec_bmp & (1 << prec)) 
    16928 +                       len += pq->q[prec].len; 
    16929 + 
    16930 +       return len; 
    16931 +} 
    16932 + 
    16933 +/* Priority dequeue from a specific set of precedences */ 
    16934 +void * 
    16935 +pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) 
    16936 +{ 
    16937 +       struct pktq_prec *q; 
    16938 +       void *p; 
    16939 +       int prec; 
    16940 + 
    16941 +       if (pq->len == 0) 
    16942 +               return NULL; 
    16943 + 
    16944 +       while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    16945 +               pq->hi_prec--; 
    16946 + 
    16947 +       while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) 
    16948 +               if (prec-- == 0) 
    16949 +                       return NULL; 
    16950 + 
    16951 +       q = &pq->q[prec]; 
    16952 + 
    16953 +       if ((p = q->head) == NULL) 
    16954 +               return NULL; 
    16955 + 
    16956 +       if ((q->head = PKTLINK(p)) == NULL) 
    16957 +               q->tail = NULL; 
    16958 + 
    16959 +       q->len--; 
    16960 + 
    16961 +       if (prec_out) 
    16962 +               *prec_out = prec; 
    16963 + 
    16964 +       pq->len--; 
    16965 + 
    16966 +       PKTSETLINK(p, NULL); 
    16967 + 
    16968 +       return p; 
    16969 +} 
    16970 + 
    16971 +char* 
    16972 +bcmstrcat(char *dest, const char *src) 
    16973 +{ 
    16974 +       strcpy(&dest[strlen(dest)], src); 
    16975 +       return (dest); 
    16976 +} 
    16977 + 
    16978 +char* 
    16979 +bcm_ether_ntoa(struct ether_addr *ea, char *buf) 
    16980 +{ 
    16981 +       sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", 
    16982 +               ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, 
    16983 +               ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); 
    16984 +       return (buf); 
    16985 +} 
    16986 + 
    16987 +/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ 
    16988 +int 
    16989 +bcm_ether_atoe(char *p, struct ether_addr *ea) 
    16990 +{ 
    16991 +       int i = 0; 
    16992 + 
    16993 +       for (;;) { 
    16994 +               ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); 
    16995 +               if (!*p++ || i == 6) 
    16996 +                       break; 
    16997 +       } 
    16998 + 
    16999 +       return (i == 6); 
    17000 +} 
    17001 + 
    17002 +/* Takes an Ethernet frame and sets out-of-bound PKTPRIO 
    17003 + * Also updates the inplace vlan tag if requested 
    17004 + */ 
    17005 +void 
    17006 +pktsetprio(void *pkt, bool update_vtag) 
    17007 +{ 
    17008 +       struct ether_header *eh; 
    17009 +       struct ethervlan_header *evh; 
    17010 +       uint8 *pktdata; 
    17011 +       int priority = 0; 
    17012 + 
    17013 +       pktdata = (uint8 *) PKTDATA(NULL, pkt); 
    17014 +       ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); 
    17015 + 
    17016 +       eh = (struct ether_header *) pktdata; 
    17017 + 
    17018 +       if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { 
    17019 +               uint16 vlan_tag; 
    17020 +               int vlan_prio, dscp_prio = 0; 
    17021 + 
    17022 +               evh = (struct ethervlan_header *)eh; 
    17023 + 
    17024 +               vlan_tag = ntoh16(evh->vlan_tag); 
    17025 +               vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; 
    17026 + 
    17027 +               if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { 
    17028 +                       uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); 
    17029 +                       uint8 tos_tc = IP_TOS(ip_body); 
    17030 +                       dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); 
    17031 +               } 
    17032 + 
    17033 +               /* DSCP priority gets precedence over 802.1P (vlan tag) */ 
    17034 +               priority = (dscp_prio != 0) ? dscp_prio : vlan_prio; 
    17035 + 
    17036 +               /*  
    17037 +                * If the DSCP priority is not the same as the VLAN priority, 
    17038 +                * then overwrite the priority field in the vlan tag, with the 
    17039 +                * DSCP priority value. This is required for Linux APs because 
    17040 +                * the VLAN driver on Linux, overwrites the skb->priority field 
    17041 +                * with the priority value in the vlan tag 
    17042 +                */ 
    17043 +               if (update_vtag && (priority != vlan_prio)) { 
    17044 +                       vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); 
    17045 +                       vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; 
    17046 +                       evh->vlan_tag = hton16(vlan_tag); 
    17047 +               } 
    17048 +       } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { 
    17049 +               uint8 *ip_body = pktdata + sizeof(struct ether_header); 
    17050 +               uint8 tos_tc = IP_TOS(ip_body); 
    17051 +               priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); 
    17052 +       } 
    17053 + 
    17054 +       ASSERT(priority >= 0 && priority <= MAXPRIO); 
    17055 +       PKTSETPRIO(pkt, priority); 
    17056 +} 
    17057 + 
    17058 +static char bcm_undeferrstr[BCME_STRLEN]; 
    17059 + 
    17060 +static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; 
    17061 + 
    17062 +/* Convert the Error codes into related Error strings  */ 
    17063 +const char * 
    17064 +bcmerrorstr(int bcmerror) 
    17065 +{ 
    17066 +       int abs_bcmerror; 
    17067 + 
    17068 +       abs_bcmerror = ABS(bcmerror); 
    17069 + 
    17070 +       /* check if someone added a bcmerror code but forgot to add errorstring */ 
    17071 +       ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); 
    17072 +       if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { 
    17073 +               sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); 
    17074 +               return bcm_undeferrstr; 
    17075 +       } 
    17076 + 
    17077 +       ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); 
    17078 + 
    17079 +       return bcmerrorstrtable[abs_bcmerror]; 
    17080 +} 
    17081 + 
    17082 + 
    17083 +int 
    17084 +bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) 
    17085 +{ 
    17086 +       int bcmerror = 0; 
    17087 + 
    17088 +       /* length check on io buf */ 
    17089 +       switch (vi->type) { 
    17090 +       case IOVT_BOOL: 
    17091 +       case IOVT_INT8: 
    17092 +       case IOVT_INT16: 
    17093 +       case IOVT_INT32: 
    17094 +       case IOVT_UINT8: 
    17095 +       case IOVT_UINT16: 
    17096 +       case IOVT_UINT32: 
    17097 +               /* all integers are int32 sized args at the ioctl interface */ 
    17098 +               if (len < (int)sizeof(int)) { 
    17099 +                       bcmerror = BCME_BUFTOOSHORT; 
    17100 +               } 
    17101 +               break; 
    17102 + 
    17103 +       case IOVT_BUFFER: 
    17104 +               /* buffer must meet minimum length requirement */ 
    17105 +               if (len < vi->minlen) { 
    17106 +                       bcmerror = BCME_BUFTOOSHORT; 
    17107 +               } 
    17108 +               break; 
    17109 + 
    17110 +       case IOVT_VOID: 
    17111 +               if (!set) { 
    17112 +                       /* Cannot return nil... */ 
    17113 +                       bcmerror = BCME_UNSUPPORTED; 
    17114 +               } else if (len) { 
    17115 +                       /* Set is an action w/o parameters */ 
    17116 +                       bcmerror = BCME_BUFTOOLONG; 
    17117 +               } 
    17118 +               break; 
    17119 + 
    17120 +       default: 
    17121 +               /* unknown type for length check in iovar info */ 
    17122 +               ASSERT(0); 
    17123 +               bcmerror = BCME_UNSUPPORTED; 
    17124 +       } 
    17125 + 
    17126 +       return bcmerror; 
    17127 +} 
    17128 + 
    17129 +#define CRC_INNER_LOOP(n, c, x) \ 
    17130 +                   (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] 
    17131 + 
    17132 +static uint32 crc32_table[256] = { 
    17133 +    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 
    17134 +    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
    17135 +    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 
    17136 +    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
    17137 +    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 
    17138 +    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
    17139 +    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 
    17140 +    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
    17141 +    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 
    17142 +    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
    17143 +    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 
    17144 +    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
    17145 +    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 
    17146 +    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
    17147 +    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 
    17148 +    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
    17149 +    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 
    17150 +    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
    17151 +    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 
    17152 +    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
    17153 +    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 
    17154 +    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
    17155 +    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 
    17156 +    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
    17157 +    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 
    17158 +    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
    17159 +    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 
    17160 +    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
    17161 +    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 
    17162 +    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
    17163 +    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 
    17164 +    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
    17165 +    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 
    17166 +    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
    17167 +    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 
    17168 +    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
    17169 +    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 
    17170 +    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
    17171 +    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 
    17172 +    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
    17173 +    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 
    17174 +    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
    17175 +    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 
    17176 +    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
    17177 +    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 
    17178 +    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
    17179 +    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 
    17180 +    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
    17181 +    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 
    17182 +    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
    17183 +    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 
    17184 +    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
    17185 +    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 
    17186 +    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
    17187 +    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 
    17188 +    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
    17189 +    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 
    17190 +    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
    17191 +    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 
    17192 +    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
    17193 +    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 
    17194 +    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
    17195 +    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 
    17196 +    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 
    17197 +}; 
    17198 + 
    17199 +uint32 
    17200 +hndcrc32( 
    17201 +    uint8 *pdata,  /* pointer to array of data to process */ 
    17202 +    uint   nbytes, /* number of input data bytes to process */ 
    17203 +    uint32 crc     /* either CRC32_INIT_VALUE or previous return value */ 
    17204 +) 
    17205 +{ 
    17206 +       uint8 *pend; 
    17207 +#ifdef __mips__ 
    17208 +       uint8 tmp[4]; 
    17209 +       ulong *tptr = (ulong *)tmp; 
    17210 + 
    17211 +       /* in case the beginning of the buffer isn't aligned */ 
    17212 +       pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); 
    17213 +       nbytes -= (pend - pdata); 
    17214 +       while (pdata < pend) 
    17215 +               CRC_INNER_LOOP(32, crc, *pdata++); 
    17216 + 
    17217 +       /* handle bulk of data as 32-bit words */ 
    17218 +       pend = pdata + (nbytes & 0xfffffffc); 
    17219 +       while (pdata < pend) { 
    17220 +               *tptr = *(ulong *)pdata; 
    17221 +               pdata += sizeof(ulong *); 
    17222 +               CRC_INNER_LOOP(32, crc, tmp[0]); 
    17223 +               CRC_INNER_LOOP(32, crc, tmp[1]); 
    17224 +               CRC_INNER_LOOP(32, crc, tmp[2]); 
    17225 +               CRC_INNER_LOOP(32, crc, tmp[3]); 
    17226 +       } 
    17227 + 
    17228 +       /* 1-3 bytes at end of buffer */ 
    17229 +       pend = pdata + (nbytes & 0x03); 
    17230 +       while (pdata < pend) 
    17231 +               CRC_INNER_LOOP(32, crc, *pdata++); 
    17232 +#else 
    17233 +       pend = pdata + nbytes; 
    17234 +       while (pdata < pend) 
    17235 +               CRC_INNER_LOOP(32, crc, *pdata++); 
    17236 +#endif /* __mips__ */ 
    17237 + 
    17238 +       return crc; 
    17239 +} 
    17240 + 
    17241 + 
    17242 +/* 
    17243 + * Advance from the current 1-byte tag/1-byte length/variable-length value 
    17244 + * triple, to the next, returning a pointer to the next. 
    17245 + * If the current or next TLV is invalid (does not fit in given buffer length), 
    17246 + * NULL is returned. 
    17247 + * *buflen is not modified if the TLV elt parameter is invalid, or is decremented 
    17248 + * by the TLV paramter's length if it is valid. 
    17249 + */ 
    17250 +bcm_tlv_t * 
    17251 +bcm_next_tlv(bcm_tlv_t *elt, int *buflen) 
    17252 +{ 
    17253 +       int len; 
    17254 + 
    17255 +       /* validate current elt */ 
    17256 +       if (!bcm_valid_tlv(elt, *buflen)) 
    17257 +               return NULL; 
    17258 + 
    17259 +       /* advance to next elt */ 
    17260 +       len = elt->len; 
    17261 +       elt = (bcm_tlv_t*)(elt->data + len); 
    17262 +       *buflen -= (2 + len); 
    17263 + 
    17264 +       /* validate next elt */ 
    17265 +       if (!bcm_valid_tlv(elt, *buflen)) 
    17266 +               return NULL; 
    17267 + 
    17268 +       return elt; 
    17269 +} 
    17270 + 
    17271 +/* 
    17272 + * Traverse a string of 1-byte tag/1-byte length/variable-length value 
    17273 + * triples, returning a pointer to the substring whose first element 
    17274 + * matches tag 
    17275 + */ 
    17276 +bcm_tlv_t * 
    17277 +bcm_parse_tlvs(void *buf, int buflen, uint key) 
    17278 +{ 
    17279 +       bcm_tlv_t *elt; 
    17280 +       int totlen; 
    17281 + 
    17282 +       elt = (bcm_tlv_t*)buf; 
    17283 +       totlen = buflen; 
    17284 + 
    17285 +       /* find tagged parameter */ 
    17286 +       while (totlen >= 2) { 
    17287 +               int len = elt->len; 
    17288 + 
    17289 +               /* validate remaining totlen */ 
    17290 +               if ((elt->id == key) && (totlen >= (len + 2))) 
    17291 +                       return (elt); 
    17292 + 
    17293 +               elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); 
    17294 +               totlen -= (len + 2); 
    17295 +       } 
    17296 + 
    17297 +       return NULL; 
    17298 +} 
    17299 + 
    17300 +/* 
    17301 + * Traverse a string of 1-byte tag/1-byte length/variable-length value 
    17302 + * triples, returning a pointer to the substring whose first element 
    17303 + * matches tag.  Stop parsing when we see an element whose ID is greater 
    17304 + * than the target key. 
    17305 + */ 
    17306 +bcm_tlv_t * 
    17307 +bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) 
    17308 +{ 
    17309 +       bcm_tlv_t *elt; 
    17310 +       int totlen; 
    17311 + 
    17312 +       elt = (bcm_tlv_t*)buf; 
    17313 +       totlen = buflen; 
    17314 + 
    17315 +       /* find tagged parameter */ 
    17316 +       while (totlen >= 2) { 
    17317 +               uint id = elt->id; 
    17318 +               int len = elt->len; 
    17319 + 
    17320 +               /* Punt if we start seeing IDs > than target key */ 
    17321 +               if (id > key) 
    17322 +                       return (NULL); 
    17323 + 
    17324 +               /* validate remaining totlen */ 
    17325 +               if ((id == key) && (totlen >= (len + 2))) 
    17326 +                       return (elt); 
    17327 + 
    17328 +               elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); 
    17329 +               totlen -= (len + 2); 
    17330 +       } 
    17331 +       return NULL; 
    17332 +} 
    17333 + 
    17334 + 
    17335 +/* Initialization of bcmstrbuf structure */ 
    17336 +void 
    17337 +bcm_binit(struct bcmstrbuf *b, char *buf, uint size) 
    17338 +{ 
    17339 +       b->origsize = b->size = size; 
    17340 +       b->origbuf = b->buf = buf; 
    17341 +} 
    17342 + 
    17343 +/* Buffer sprintf wrapper to guard against buffer overflow */ 
    17344 +int 
    17345 +bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) 
    17346 +{ 
    17347 +       va_list ap; 
    17348 +       int r; 
    17349 + 
    17350 +       va_start(ap, fmt); 
    17351 +       r = vsnprintf(b->buf, b->size, fmt, ap); 
    17352 + 
    17353 +       /* Non Ansi C99 compliant returns -1, 
    17354 +        * Ansi compliant return r >= b->size, 
    17355 +        * bcmstdlib returns 0, handle all 
    17356 +        */ 
    17357 +       if ((r == -1) || (r >= (int)b->size) || (r == 0)) 
    17358 +       { 
    17359 +               b->size = 0; 
    17360 +       } 
    17361 +       else 
    17362 +       { 
    17363 +               b->size -= r; 
    17364 +               b->buf += r; 
    17365 +       } 
    17366 + 
    17367 +       va_end(ap); 
    17368 + 
    17369 +       return r; 
    17370 +} 
    17371 diff -urN linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c 
    17372 --- linux.old/drivers/net/wl/hnddma.c   1970-01-01 01:00:00.000000000 +0100 
    17373 +++ linux.dev/drivers/net/wl/hnddma.c   2006-05-02 17:42:13.000000000 +0200 
    17374 @@ -0,0 +1,1157 @@ 
    17375 +/* 
    17376 + * Generic Broadcom Home Networking Division (HND) DMA module. 
    17377 + * This supports the following chips: BCM42xx, 44xx, 47xx . 
    17378 + * 
    17379 + * Copyright 2006, Broadcom Corporation 
    17380 + * All Rights Reserved. 
    17381 + *  
    17382 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    17383 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    17384 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    17385 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    17386 + * 
    17387 + * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $ 
    17388 + */ 
    17389 + 
    17390 +#include <typedefs.h> 
    17391 +#include <bcmdefs.h> 
    17392 +#include <osl.h> 
    17393 +#include "linux_osl.h" 
    17394 +#include <bcmendian.h> 
    17395 +#include <sbconfig.h> 
    17396 +#include <bcmutils.h> 
    17397 +#include <bcmdevs.h> 
    17398 +#include <sbutils.h> 
    17399 + 
    17400 +#include "sbhnddma.h" 
    17401 +#include "hnddma.h" 
    17402 + 
    17403 +/* debug/trace */ 
    17404 +#define        DMA_ERROR(args) 
    17405 +#define        DMA_TRACE(args) 
    17406 + 
    17407 +/* default dma message level (if input msg_level pointer is null in dma_attach()) */ 
    17408 +static uint dma_msg_level = 
    17409 +       0; 
    17410 + 
    17411 +#define        MAXNAMEL        8               /* 8 char names */ 
    17412 + 
    17413 +#define        DI_INFO(dmah)   (dma_info_t *)dmah 
    17414 + 
    17415 +/* dma engine software state */ 
    17416 +typedef struct dma_info { 
    17417 +       struct hnddma_pub hnddma;       /* exported structure, don't use hnddma_t, 
    17418 +                                        * which could be const 
    17419 +                                        */ 
    17420 +       uint            *msg_level;     /* message level pointer */ 
    17421 +       char            name[MAXNAMEL]; /* callers name for diag msgs */ 
    17422 + 
    17423 +       void            *osh;           /* os handle */ 
    17424 +       sb_t            *sbh;           /* sb handle */ 
    17425 + 
    17426 +       bool            dma64;          /* dma64 enabled */ 
    17427 +       bool            addrext;        /* this dma engine supports DmaExtendedAddrChanges */ 
    17428 + 
    17429 +       dma32regs_t     *d32txregs;     /* 32 bits dma tx engine registers */ 
    17430 +       dma32regs_t     *d32rxregs;     /* 32 bits dma rx engine registers */ 
    17431 +       dma64regs_t     *d64txregs;     /* 64 bits dma tx engine registers */ 
    17432 +       dma64regs_t     *d64rxregs;     /* 64 bits dma rx engine registers */ 
    17433 + 
    17434 +       uint32          dma64align;     /* either 8k or 4k depends on number of dd */ 
    17435 +       dma32dd_t       *txd32;         /* pointer to dma32 tx descriptor ring */ 
    17436 +       dma64dd_t       *txd64;         /* pointer to dma64 tx descriptor ring */ 
    17437 +       uint            ntxd;           /* # tx descriptors tunable */ 
    17438 +       uint            txin;           /* index of next descriptor to reclaim */ 
    17439 +       uint            txout;          /* index of next descriptor to post */ 
    17440 +       void            **txp;          /* pointer to parallel array of pointers to packets */ 
    17441 +       osldma_t        *tx_dmah;       /* DMA TX descriptor ring handle */ 
    17442 +       osldma_t        **txp_dmah;     /* DMA TX packet data handle */ 
    17443 +       ulong           txdpa;          /* physical address of descriptor ring */ 
    17444 +       uint            txdalign;       /* #bytes added to alloc'd mem to align txd */ 
    17445 +       uint            txdalloc;       /* #bytes allocated for the ring */ 
    17446 + 
    17447 +       dma32dd_t       *rxd32;         /* pointer to dma32 rx descriptor ring */ 
    17448 +       dma64dd_t       *rxd64;         /* pointer to dma64 rx descriptor ring */ 
    17449 +       uint            nrxd;           /* # rx descriptors tunable */ 
    17450 +       uint            rxin;           /* index of next descriptor to reclaim */ 
    17451 +       uint            rxout;          /* index of next descriptor to post */ 
    17452 +       void            **rxp;          /* pointer to parallel array of pointers to packets */ 
    17453 +       osldma_t        *rx_dmah;       /* DMA RX descriptor ring handle */ 
    17454 +       osldma_t        **rxp_dmah;     /* DMA RX packet data handle */ 
    17455 +       ulong           rxdpa;          /* physical address of descriptor ring */ 
    17456 +       uint            rxdalign;       /* #bytes added to alloc'd mem to align rxd */ 
    17457 +       uint            rxdalloc;       /* #bytes allocated for the ring */ 
    17458 + 
    17459 +       /* tunables */ 
    17460 +       uint            rxbufsize;      /* rx buffer size in bytes, 
    17461 +                                          not including the extra headroom 
    17462 +                                       */ 
    17463 +       uint            nrxpost;        /* # rx buffers to keep posted */ 
    17464 +       uint            rxoffset;       /* rxcontrol offset */ 
    17465 +       uint            ddoffsetlow;    /* add to get dma address of descriptor ring, low 32 bits */ 
    17466 +       uint            ddoffsethigh;   /*   high 32 bits */ 
    17467 +       uint            dataoffsetlow;  /* add to get dma address of data buffer, low 32 bits */ 
    17468 +       uint            dataoffsethigh; /*   high 32 bits */ 
    17469 +} dma_info_t; 
    17470 + 
    17471 +/* descriptor bumping macros */ 
    17472 +#define        XXD(x, n)       ((x) & ((n) - 1))       /* faster than %, but n must be power of 2 */ 
    17473 +#define        TXD(x)          XXD((x), di->ntxd) 
    17474 +#define        RXD(x)          XXD((x), di->nrxd) 
    17475 +#define        NEXTTXD(i)      TXD(i + 1) 
    17476 +#define        PREVTXD(i)      TXD(i - 1) 
    17477 +#define        NEXTRXD(i)      RXD(i + 1) 
    17478 +#define        NTXDACTIVE(h, t)        TXD(t - h) 
    17479 +#define        NRXDACTIVE(h, t)        RXD(t - h) 
    17480 + 
    17481 +/* macros to convert between byte offsets and indexes */ 
    17482 +#define        B2I(bytes, type)        ((bytes) / sizeof(type)) 
    17483 +#define        I2B(index, type)        ((index) * sizeof(type)) 
    17484 + 
    17485 +#define        PCI32ADDR_HIGH          0xc0000000      /* address[31:30] */ 
    17486 +#define        PCI32ADDR_HIGH_SHIFT    30              /* address[31:30] */ 
    17487 + 
    17488 + 
    17489 +/* common prototypes */ 
    17490 +static bool _dma_isaddrext(dma_info_t *di); 
    17491 +static bool dma32_alloc(dma_info_t *di, uint direction); 
    17492 +static void _dma_detach(dma_info_t *di); 
    17493 +static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa); 
    17494 +static void _dma_rxinit(dma_info_t *di); 
    17495 +static void *_dma_rx(dma_info_t *di); 
    17496 +static void _dma_rxfill(dma_info_t *di); 
    17497 +static void _dma_rxreclaim(dma_info_t *di); 
    17498 +static void _dma_rxenable(dma_info_t *di); 
    17499 +static void * _dma_getnextrxp(dma_info_t *di, bool forceall); 
    17500 + 
    17501 +static void _dma_txblock(dma_info_t *di); 
    17502 +static void _dma_txunblock(dma_info_t *di); 
    17503 +static uint _dma_txactive(dma_info_t *di); 
    17504 + 
    17505 +static void* _dma_peeknexttxp(dma_info_t *di); 
    17506 +static uintptr _dma_getvar(dma_info_t *di, char *name); 
    17507 +static void _dma_counterreset(dma_info_t *di); 
    17508 +static void _dma_fifoloopbackenable(dma_info_t *di); 
    17509 + 
    17510 +/* ** 32 bit DMA prototypes */ 
    17511 +static bool dma32_alloc(dma_info_t *di, uint direction); 
    17512 +static bool dma32_txreset(dma_info_t *di); 
    17513 +static bool dma32_rxreset(dma_info_t *di); 
    17514 +static bool dma32_txsuspendedidle(dma_info_t *di); 
    17515 +static int  dma32_txfast(dma_info_t *di, void *p0, bool commit); 
    17516 +static void *dma32_getnexttxp(dma_info_t *di, bool forceall); 
    17517 +static void *dma32_getnextrxp(dma_info_t *di, bool forceall); 
    17518 +static void dma32_txrotate(dma_info_t *di); 
    17519 +static bool dma32_rxidle(dma_info_t *di); 
    17520 +static void dma32_txinit(dma_info_t *di); 
    17521 +static bool dma32_txenabled(dma_info_t *di); 
    17522 +static void dma32_txsuspend(dma_info_t *di); 
    17523 +static void dma32_txresume(dma_info_t *di); 
    17524 +static bool dma32_txsuspended(dma_info_t *di); 
    17525 +static void dma32_txreclaim(dma_info_t *di, bool forceall); 
    17526 +static bool dma32_txstopped(dma_info_t *di); 
    17527 +static bool dma32_rxstopped(dma_info_t *di); 
    17528 +static bool dma32_rxenabled(dma_info_t *di); 
    17529 +static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); 
    17530 + 
    17531 + 
    17532 +static di_fcn_t dma32proc = { 
    17533 +       (di_detach_t)_dma_detach, 
    17534 +       (di_txinit_t)dma32_txinit, 
    17535 +       (di_txreset_t)dma32_txreset, 
    17536 +       (di_txenabled_t)dma32_txenabled, 
    17537 +       (di_txsuspend_t)dma32_txsuspend, 
    17538 +       (di_txresume_t)dma32_txresume, 
    17539 +       (di_txsuspended_t)dma32_txsuspended, 
    17540 +       (di_txsuspendedidle_t)dma32_txsuspendedidle, 
    17541 +       (di_txfast_t)dma32_txfast, 
    17542 +       (di_txstopped_t)dma32_txstopped, 
    17543 +       (di_txreclaim_t)dma32_txreclaim, 
    17544 +       (di_getnexttxp_t)dma32_getnexttxp, 
    17545 +       (di_peeknexttxp_t)_dma_peeknexttxp, 
    17546 +       (di_txblock_t)_dma_txblock, 
    17547 +       (di_txunblock_t)_dma_txunblock, 
    17548 +       (di_txactive_t)_dma_txactive, 
    17549 +       (di_txrotate_t)dma32_txrotate, 
    17550 + 
    17551 +       (di_rxinit_t)_dma_rxinit, 
    17552 +       (di_rxreset_t)dma32_rxreset, 
    17553 +       (di_rxidle_t)dma32_rxidle, 
    17554 +       (di_rxstopped_t)dma32_rxstopped, 
    17555 +       (di_rxenable_t)_dma_rxenable, 
    17556 +       (di_rxenabled_t)dma32_rxenabled, 
    17557 +       (di_rx_t)_dma_rx, 
    17558 +       (di_rxfill_t)_dma_rxfill, 
    17559 +       (di_rxreclaim_t)_dma_rxreclaim, 
    17560 +       (di_getnextrxp_t)_dma_getnextrxp, 
    17561 + 
    17562 +       (di_fifoloopbackenable_t)_dma_fifoloopbackenable, 
    17563 +       (di_getvar_t)_dma_getvar, 
    17564 +       (di_counterreset_t)_dma_counterreset, 
    17565 + 
    17566 +       NULL, 
    17567 +       NULL, 
    17568 +       NULL, 
    17569 +       34 
    17570 +}; 
    17571 + 
    17572 +hnddma_t * 
    17573 +dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, 
    17574 +           uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) 
    17575 +{ 
    17576 +       dma_info_t *di; 
    17577 +       uint size; 
    17578 + 
    17579 +       /* allocate private info structure */ 
    17580 +       if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { 
    17581 +               return (NULL); 
    17582 +       } 
    17583 +       bzero((char *)di, sizeof(dma_info_t)); 
    17584 + 
    17585 +       di->msg_level = msg_level ? msg_level : &dma_msg_level; 
    17586 + 
    17587 +       /* old chips w/o sb is no longer supported */ 
    17588 +       ASSERT(sbh != NULL); 
    17589 + 
    17590 +       /* check arguments */ 
    17591 +       ASSERT(ISPOWEROF2(ntxd)); 
    17592 +       ASSERT(ISPOWEROF2(nrxd)); 
    17593 +       if (nrxd == 0) 
    17594 +               ASSERT(dmaregsrx == NULL); 
    17595 +       if (ntxd == 0) 
    17596 +               ASSERT(dmaregstx == NULL); 
    17597 + 
    17598 + 
    17599 +       /* init dma reg pointer */ 
    17600 +       ASSERT(ntxd <= D32MAXDD); 
    17601 +       ASSERT(nrxd <= D32MAXDD); 
    17602 +       di->d32txregs = (dma32regs_t *)dmaregstx; 
    17603 +       di->d32rxregs = (dma32regs_t *)dmaregsrx; 
    17604 + 
    17605 +       DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " 
    17606 +                  "rxoffset %d dmaregstx %p dmaregsrx %p\n", 
    17607 +                  name, "DMA32", osh, ntxd, nrxd, rxbufsize, 
    17608 +                  nrxpost, rxoffset, dmaregstx, dmaregsrx)); 
    17609 + 
    17610 +       /* make a private copy of our callers name */ 
    17611 +       strncpy(di->name, name, MAXNAMEL); 
    17612 +       di->name[MAXNAMEL-1] = '\0'; 
    17613 + 
    17614 +       di->osh = osh; 
    17615 +       di->sbh = sbh; 
    17616 + 
    17617 +       /* save tunables */ 
    17618 +       di->ntxd = ntxd; 
    17619 +       di->nrxd = nrxd; 
    17620 + 
    17621 +       /* the actual dma size doesn't include the extra headroom */ 
    17622 +       if (rxbufsize > BCMEXTRAHDROOM) 
    17623 +               di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; 
    17624 +       else 
    17625 +               di->rxbufsize = rxbufsize; 
    17626 + 
    17627 +       di->nrxpost = nrxpost; 
    17628 +       di->rxoffset = rxoffset; 
    17629 + 
    17630 +       /* 
    17631 +        * figure out the DMA physical address offset for dd and data 
    17632 +        *   for old chips w/o sb, use zero 
    17633 +        *   for new chips w sb, 
    17634 +        *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset 
    17635 +        *     Other bus: use zero 
    17636 +        *     SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor 
    17637 +        */ 
    17638 +       di->ddoffsetlow = 0; 
    17639 +       di->dataoffsetlow = 0; 
    17640 +       /* for pci bus, add offset */ 
    17641 +       if (sbh->bustype == PCI_BUS) { 
    17642 +               di->ddoffsetlow = SB_PCI_DMA; 
    17643 +               di->ddoffsethigh = 0; 
    17644 +               di->dataoffsetlow =  di->ddoffsetlow; 
    17645 +               di->dataoffsethigh =  di->ddoffsethigh; 
    17646 +       } 
    17647 + 
    17648 +#if defined(__mips__) && defined(IL_BIGENDIAN) 
    17649 +       di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; 
    17650 +#endif 
    17651 + 
    17652 +       di->addrext = _dma_isaddrext(di); 
    17653 + 
    17654 +       /* allocate tx packet pointer vector */ 
    17655 +       if (ntxd) { 
    17656 +               size = ntxd * sizeof(void *); 
    17657 +               if ((di->txp = MALLOC(osh, size)) == NULL) { 
    17658 +                       DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", 
    17659 +                                  di->name, MALLOCED(osh))); 
    17660 +                       goto fail; 
    17661 +               } 
    17662 +               bzero((char *)di->txp, size); 
    17663 +       } 
    17664 + 
    17665 +       /* allocate rx packet pointer vector */ 
    17666 +       if (nrxd) { 
    17667 +               size = nrxd * sizeof(void *); 
    17668 +               if ((di->rxp = MALLOC(osh, size)) == NULL) { 
    17669 +                       DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", 
    17670 +                                  di->name, MALLOCED(osh))); 
    17671 +                       goto fail; 
    17672 +               } 
    17673 +               bzero((char *)di->rxp, size); 
    17674 +       } 
    17675 + 
    17676 +       /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ 
    17677 +       if (ntxd) { 
    17678 +               if (!dma32_alloc(di, DMA_TX)) 
    17679 +                       goto fail; 
    17680 +       } 
    17681 + 
    17682 +       /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ 
    17683 +       if (nrxd) { 
    17684 +               if (!dma32_alloc(di, DMA_RX)) 
    17685 +                       goto fail; 
    17686 +       } 
    17687 + 
    17688 +       if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { 
    17689 +               DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", 
    17690 +                          di->name, di->txdpa)); 
    17691 +               goto fail; 
    17692 +       } 
    17693 +       if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { 
    17694 +               DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", 
    17695 +                          di->name, di->rxdpa)); 
    17696 +               goto fail; 
    17697 +       } 
    17698 + 
    17699 +       DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " 
    17700 +                  "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, 
    17701 +                  di->dataoffsethigh, di->addrext)); 
    17702 + 
    17703 +       /* allocate tx packet pointer vector and DMA mapping vectors */ 
    17704 +       if (ntxd) { 
    17705 + 
    17706 +               size = ntxd * sizeof(osldma_t **); 
    17707 +               if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) 
    17708 +                       goto fail; 
    17709 +               bzero((char*)di->txp_dmah, size); 
    17710 +       }else 
    17711 +               di->txp_dmah = NULL; 
    17712 + 
    17713 +       /* allocate rx packet pointer vector and DMA mapping vectors */ 
    17714 +       if (nrxd) { 
    17715 + 
    17716 +               size = nrxd * sizeof(osldma_t **); 
    17717 +               if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) 
    17718 +                       goto fail; 
    17719 +               bzero((char*)di->rxp_dmah, size); 
    17720 + 
    17721 +       } else 
    17722 +               di->rxp_dmah = NULL; 
    17723 + 
    17724 +       /* initialize opsvec of function pointers */ 
    17725 +       di->hnddma.di_fn = dma32proc; 
    17726 + 
    17727 +       return ((hnddma_t *)di); 
    17728 + 
    17729 +fail: 
    17730 +       _dma_detach(di); 
    17731 +       return (NULL); 
    17732 +} 
    17733 + 
    17734 +/* init the tx or rx descriptor */ 
    17735 +static INLINE void 
    17736 +dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags, 
    17737 +             uint32 bufcount) 
    17738 +{ 
    17739 +       /* dma32 uses 32 bits control to fit both flags and bufcounter */ 
    17740 +       *flags = *flags | (bufcount & CTRL_BC_MASK); 
    17741 + 
    17742 +       if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    17743 +               W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); 
    17744 +               W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); 
    17745 +       } else { 
    17746 +               /* address extension */ 
    17747 +               uint32 ae; 
    17748 +               ASSERT(di->addrext); 
    17749 +               ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    17750 +               pa &= ~PCI32ADDR_HIGH; 
    17751 + 
    17752 +               *flags |= (ae << CTRL_AE_SHIFT); 
    17753 +               W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); 
    17754 +               W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); 
    17755 +       } 
    17756 +} 
    17757 + 
    17758 +static bool 
    17759 +_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) 
    17760 +{ 
    17761 +       uint32 w; 
    17762 + 
    17763 +       OR_REG(osh, &dma32regs->control, XC_AE); 
    17764 +       w = R_REG(osh, &dma32regs->control); 
    17765 +       AND_REG(osh, &dma32regs->control, ~XC_AE); 
    17766 +       return ((w & XC_AE) == XC_AE); 
    17767 +} 
    17768 + 
    17769 +/* !! may be called with core in reset */ 
    17770 +static void 
    17771 +_dma_detach(dma_info_t *di) 
    17772 +{ 
    17773 +       if (di == NULL) 
    17774 +               return; 
    17775 + 
    17776 +       DMA_TRACE(("%s: dma_detach\n", di->name)); 
    17777 + 
    17778 +       /* shouldn't be here if descriptors are unreclaimed */ 
    17779 +       ASSERT(di->txin == di->txout); 
    17780 +       ASSERT(di->rxin == di->rxout); 
    17781 + 
    17782 +       /* free dma descriptor rings */ 
    17783 +       if (di->txd32) 
    17784 +               DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), 
    17785 +                                   di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); 
    17786 +       if (di->rxd32) 
    17787 +               DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), 
    17788 +                                   di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); 
    17789 + 
    17790 +       /* free packet pointer vectors */ 
    17791 +       if (di->txp) 
    17792 +               MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); 
    17793 +       if (di->rxp) 
    17794 +               MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); 
    17795 + 
    17796 +       /* free tx packet DMA handles */ 
    17797 +       if (di->txp_dmah) 
    17798 +               MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **)); 
    17799 + 
    17800 +       /* free rx packet DMA handles */ 
    17801 +       if (di->rxp_dmah) 
    17802 +               MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **)); 
    17803 + 
    17804 +       /* free our private info structure */ 
    17805 +       MFREE(di->osh, (void *)di, sizeof(dma_info_t)); 
    17806 + 
    17807 +} 
    17808 + 
    17809 +/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ 
    17810 +static bool 
    17811 +_dma_isaddrext(dma_info_t *di) 
    17812 +{ 
    17813 +       if (di->d32txregs) 
    17814 +               return (_dma32_addrext(di->osh, di->d32txregs)); 
    17815 +       else if (di->d32rxregs) 
    17816 +               return (_dma32_addrext(di->osh, di->d32rxregs)); 
    17817 +       return FALSE; 
    17818 +} 
    17819 + 
    17820 +/* initialize descriptor table base address */ 
    17821 +static void 
    17822 +_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) 
    17823 +{ 
    17824 +       if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    17825 +               if (direction == DMA_TX) 
    17826 +                       W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
    17827 +               else 
    17828 +                       W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
    17829 +       } else { 
    17830 +               /* dma32 address extension */ 
    17831 +               uint32 ae; 
    17832 +               ASSERT(di->addrext); 
    17833 + 
    17834 +               /* shift the high bit(s) from pa to ae */ 
    17835 +               ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    17836 +               pa &= ~PCI32ADDR_HIGH; 
    17837 + 
    17838 +               if (direction == DMA_TX) { 
    17839 +                       W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
    17840 +                       SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <<XC_AE_SHIFT); 
    17841 +               } else { 
    17842 +                       W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
    17843 +                       SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <<RC_AE_SHIFT); 
    17844 +               } 
    17845 +       } 
    17846 +} 
    17847 + 
    17848 +static void 
    17849 +_dma_fifoloopbackenable(dma_info_t *di) 
    17850 +{ 
    17851 +       DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); 
    17852 +       OR_REG(di->osh, &di->d32txregs->control, XC_LE); 
    17853 +} 
    17854 + 
    17855 +static void 
    17856 +_dma_rxinit(dma_info_t *di) 
    17857 +{ 
    17858 +       DMA_TRACE(("%s: dma_rxinit\n", di->name)); 
    17859 + 
    17860 +       if (di->nrxd == 0) 
    17861 +               return; 
    17862 + 
    17863 +       di->rxin = di->rxout = 0; 
    17864 + 
    17865 +       /* clear rx descriptor ring */ 
    17866 +       BZERO_SM((void *)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); 
    17867 +       _dma_rxenable(di); 
    17868 +       _dma_ddtable_init(di, DMA_RX, di->rxdpa); 
    17869 +} 
    17870 + 
    17871 +static void 
    17872 +_dma_rxenable(dma_info_t *di) 
    17873 +{ 
    17874 +       DMA_TRACE(("%s: dma_rxenable\n", di->name)); 
    17875 + 
    17876 +       W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); 
    17877 +} 
    17878 + 
    17879 +/* !! rx entry routine, returns a pointer to the next frame received, 
    17880 + * or NULL if there are no more 
    17881 + */ 
    17882 +static void * 
    17883 +_dma_rx(dma_info_t *di) 
    17884 +{ 
    17885 +       void *p; 
    17886 +       uint len; 
    17887 +       int skiplen = 0; 
    17888 + 
    17889 +       while ((p = _dma_getnextrxp(di, FALSE))) { 
    17890 +               /* skip giant packets which span multiple rx descriptors */ 
    17891 +               if (skiplen > 0) { 
    17892 +                       skiplen -= di->rxbufsize; 
    17893 +                       if (skiplen < 0) 
    17894 +                               skiplen = 0; 
    17895 +                       PKTFREE(di->osh, p, FALSE); 
    17896 +                       continue; 
    17897 +               } 
    17898 + 
    17899 +               len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); 
    17900 +               DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); 
    17901 + 
    17902 +               /* bad frame length check */ 
    17903 +               if (len > (di->rxbufsize - di->rxoffset)) { 
    17904 +                       DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); 
    17905 +                       if (len > 0) 
    17906 +                               skiplen = len - (di->rxbufsize - di->rxoffset); 
    17907 +                       PKTFREE(di->osh, p, FALSE); 
    17908 +                       di->hnddma.rxgiants++; 
    17909 +                       continue; 
    17910 +               } 
    17911 + 
    17912 +               /* set actual length */ 
    17913 +               PKTSETLEN(di->osh, p, (di->rxoffset + len)); 
    17914 + 
    17915 +               break; 
    17916 +       } 
    17917 + 
    17918 +       return (p); 
    17919 +} 
    17920 + 
    17921 +/* post receive buffers */ 
    17922 +static void 
    17923 +_dma_rxfill(dma_info_t *di) 
    17924 +{ 
    17925 +       void *p; 
    17926 +       uint rxin, rxout; 
    17927 +       uint32 flags = 0; 
    17928 +       uint n; 
    17929 +       uint i; 
    17930 +       uint32 pa; 
    17931 +       uint extra_offset = 0; 
    17932 + 
    17933 +       /* 
    17934 +        * Determine how many receive buffers we're lacking 
    17935 +        * from the full complement, allocate, initialize, 
    17936 +        * and post them, then update the chip rx lastdscr. 
    17937 +        */ 
    17938 + 
    17939 +       rxin = di->rxin; 
    17940 +       rxout = di->rxout; 
    17941 + 
    17942 +       n = di->nrxpost - NRXDACTIVE(rxin, rxout); 
    17943 + 
    17944 +       DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); 
    17945 + 
    17946 +       if (di->rxbufsize > BCMEXTRAHDROOM) 
    17947 +               extra_offset = BCMEXTRAHDROOM; 
    17948 + 
    17949 +       for (i = 0; i < n; i++) { 
    17950 +               /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the 
    17951 +                  size to be allocated 
    17952 +               */ 
    17953 +               if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset, 
    17954 +                               FALSE)) == NULL) { 
    17955 +                       DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); 
    17956 +                       di->hnddma.rxnobuf++; 
    17957 +                       break; 
    17958 +               } 
    17959 +               /* reserve an extra headroom, if applicable */ 
    17960 +               if (extra_offset) 
    17961 +                       PKTPULL(di->osh, p, extra_offset); 
    17962 + 
    17963 +               /* Do a cached write instead of uncached write since DMA_MAP 
    17964 +                * will flush the cache. 
    17965 +                */ 
    17966 +               *(uint32*)(PKTDATA(di->osh, p)) = 0; 
    17967 + 
    17968 +               pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), 
    17969 +                                     di->rxbufsize, DMA_RX, p); 
    17970 + 
    17971 +               ASSERT(ISALIGNED(pa, 4)); 
    17972 + 
    17973 +               /* save the free packet pointer */ 
    17974 +               ASSERT(di->rxp[rxout] == NULL); 
    17975 +               di->rxp[rxout] = p; 
    17976 + 
    17977 +               /* reset flags for each descriptor */ 
    17978 +               flags = 0; 
    17979 +               if (rxout == (di->nrxd - 1)) 
    17980 +                       flags = CTRL_EOT; 
    17981 +               dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); 
    17982 +               rxout = NEXTRXD(rxout); 
    17983 +       } 
    17984 + 
    17985 +       di->rxout = rxout; 
    17986 + 
    17987 +       /* update the chip lastdscr pointer */ 
    17988 +       W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); 
    17989 +} 
    17990 + 
    17991 +/* like getnexttxp but no reclaim */ 
    17992 +static void * 
    17993 +_dma_peeknexttxp(dma_info_t *di) 
    17994 +{ 
    17995 +       uint end, i; 
    17996 + 
    17997 +       if (di->ntxd == 0) 
    17998 +               return (NULL); 
    17999 + 
    18000 +       end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); 
    18001 + 
    18002 +       for (i = di->txin; i != end; i = NEXTTXD(i)) 
    18003 +               if (di->txp[i]) 
    18004 +                       return (di->txp[i]); 
    18005 + 
    18006 +       return (NULL); 
    18007 +} 
    18008 + 
    18009 +static void 
    18010 +_dma_rxreclaim(dma_info_t *di) 
    18011 +{ 
    18012 +       void *p; 
    18013 + 
    18014 +       /* "unused local" warning suppression for OSLs that 
    18015 +        * define PKTFREE() without using the di->osh arg 
    18016 +        */ 
    18017 +       di = di; 
    18018 + 
    18019 +       DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); 
    18020 + 
    18021 +       while ((p = _dma_getnextrxp(di, TRUE))) 
    18022 +               PKTFREE(di->osh, p, FALSE); 
    18023 +} 
    18024 + 
    18025 +static void * 
    18026 +_dma_getnextrxp(dma_info_t *di, bool forceall) 
    18027 +{ 
    18028 +       if (di->nrxd == 0) 
    18029 +               return (NULL); 
    18030 + 
    18031 +       return dma32_getnextrxp(di, forceall); 
    18032 +} 
    18033 + 
    18034 +static void 
    18035 +_dma_txblock(dma_info_t *di) 
    18036 +{ 
    18037 +       di->hnddma.txavail = 0; 
    18038 +} 
    18039 + 
    18040 +static void 
    18041 +_dma_txunblock(dma_info_t *di) 
    18042 +{ 
    18043 +       di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; 
    18044 +} 
    18045 + 
    18046 +static uint 
    18047 +_dma_txactive(dma_info_t *di) 
    18048 +{ 
    18049 +       return (NTXDACTIVE(di->txin, di->txout)); 
    18050 +} 
    18051 + 
    18052 +static void 
    18053 +_dma_counterreset(dma_info_t *di) 
    18054 +{ 
    18055 +       /* reset all software counter */ 
    18056 +       di->hnddma.rxgiants = 0; 
    18057 +       di->hnddma.rxnobuf = 0; 
    18058 +       di->hnddma.txnobuf = 0; 
    18059 +} 
    18060 + 
    18061 +/* get the address of the var in order to change later */ 
    18062 +static uintptr 
    18063 +_dma_getvar(dma_info_t *di, char *name) 
    18064 +{ 
    18065 +       if (!strcmp(name, "&txavail")) 
    18066 +               return ((uintptr) &(di->hnddma.txavail)); 
    18067 +       else { 
    18068 +               ASSERT(0); 
    18069 +       } 
    18070 +       return (0); 
    18071 +} 
    18072 + 
    18073 +void 
    18074 +dma_txpioloopback(osl_t *osh, dma32regs_t *regs) 
    18075 +{ 
    18076 +       OR_REG(osh, &regs->control, XC_LE); 
    18077 +} 
    18078 + 
    18079 + 
    18080 + 
    18081 +/* 32 bits DMA functions */ 
    18082 +static void 
    18083 +dma32_txinit(dma_info_t *di) 
    18084 +{ 
    18085 +       DMA_TRACE(("%s: dma_txinit\n", di->name)); 
    18086 + 
    18087 +       if (di->ntxd == 0) 
    18088 +               return; 
    18089 + 
    18090 +       di->txin = di->txout = 0; 
    18091 +       di->hnddma.txavail = di->ntxd - 1; 
    18092 + 
    18093 +       /* clear tx descriptor ring */ 
    18094 +       BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t))); 
    18095 +       W_REG(di->osh, &di->d32txregs->control, XC_XE); 
    18096 +       _dma_ddtable_init(di, DMA_TX, di->txdpa); 
    18097 +} 
    18098 + 
    18099 +static bool 
    18100 +dma32_txenabled(dma_info_t *di) 
    18101 +{ 
    18102 +       uint32 xc; 
    18103 + 
    18104 +       /* If the chip is dead, it is not enabled :-) */ 
    18105 +       xc = R_REG(di->osh, &di->d32txregs->control); 
    18106 +       return ((xc != 0xffffffff) && (xc & XC_XE)); 
    18107 +} 
    18108 + 
    18109 +static void 
    18110 +dma32_txsuspend(dma_info_t *di) 
    18111 +{ 
    18112 +       DMA_TRACE(("%s: dma_txsuspend\n", di->name)); 
    18113 + 
    18114 +       if (di->ntxd == 0) 
    18115 +               return; 
    18116 + 
    18117 +       OR_REG(di->osh, &di->d32txregs->control, XC_SE); 
    18118 +} 
    18119 + 
    18120 +static void 
    18121 +dma32_txresume(dma_info_t *di) 
    18122 +{ 
    18123 +       DMA_TRACE(("%s: dma_txresume\n", di->name)); 
    18124 + 
    18125 +       if (di->ntxd == 0) 
    18126 +               return; 
    18127 + 
    18128 +       AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); 
    18129 +} 
    18130 + 
    18131 +static bool 
    18132 +dma32_txsuspended(dma_info_t *di) 
    18133 +{ 
    18134 +       return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); 
    18135 +} 
    18136 + 
    18137 +static void 
    18138 +dma32_txreclaim(dma_info_t *di, bool forceall) 
    18139 +{ 
    18140 +       void *p; 
    18141 + 
    18142 +       DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); 
    18143 + 
    18144 +       while ((p = dma32_getnexttxp(di, forceall))) 
    18145 +               PKTFREE(di->osh, p, TRUE); 
    18146 +} 
    18147 + 
    18148 +static bool 
    18149 +dma32_txstopped(dma_info_t *di) 
    18150 +{ 
    18151 +       return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); 
    18152 +} 
    18153 + 
    18154 +static bool 
    18155 +dma32_rxstopped(dma_info_t *di) 
    18156 +{ 
    18157 +       return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); 
    18158 +} 
    18159 + 
    18160 +static bool 
    18161 +dma32_alloc(dma_info_t *di, uint direction) 
    18162 +{ 
    18163 +       uint size; 
    18164 +       uint ddlen; 
    18165 +       void *va; 
    18166 + 
    18167 +       ddlen = sizeof(dma32dd_t); 
    18168 + 
    18169 +       size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); 
    18170 + 
    18171 +       if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) 
    18172 +               size += D32RINGALIGN; 
    18173 + 
    18174 + 
    18175 +       if (direction == DMA_TX) { 
    18176 +               if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) { 
    18177 +                       DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", 
    18178 +                                  di->name)); 
    18179 +                       return FALSE; 
    18180 +               } 
    18181 + 
    18182 +               di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); 
    18183 +               di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); 
    18184 +               di->txdpa += di->txdalign; 
    18185 +               di->txdalloc = size; 
    18186 +               ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); 
    18187 +       } else { 
    18188 +               if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) { 
    18189 +                       DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", 
    18190 +                                  di->name)); 
    18191 +                       return FALSE; 
    18192 +               } 
    18193 +               di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); 
    18194 +               di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); 
    18195 +               di->rxdpa += di->rxdalign; 
    18196 +               di->rxdalloc = size; 
    18197 +               ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); 
    18198 +       } 
    18199 + 
    18200 +       return TRUE; 
    18201 +} 
    18202 + 
    18203 +static bool 
    18204 +dma32_txreset(dma_info_t *di) 
    18205 +{ 
    18206 +       uint32 status; 
    18207 + 
    18208 +       if (di->ntxd == 0) 
    18209 +               return TRUE; 
    18210 + 
    18211 +       /* suspend tx DMA first */ 
    18212 +       W_REG(di->osh, &di->d32txregs->control, XC_SE); 
    18213 +       SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) 
    18214 +                != XS_XS_DISABLED) && 
    18215 +                (status != XS_XS_IDLE) && 
    18216 +                (status != XS_XS_STOPPED), 
    18217 +                (10000)); 
    18218 + 
    18219 +       W_REG(di->osh, &di->d32txregs->control, 0); 
    18220 +       SPINWAIT(((status = (R_REG(di->osh, 
    18221 +                &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), 
    18222 +                10000); 
    18223 + 
    18224 +       /* wait for the last transaction to complete */ 
    18225 +       OSL_DELAY(300); 
    18226 + 
    18227 +       return (status == XS_XS_DISABLED); 
    18228 +} 
    18229 + 
    18230 +static bool 
    18231 +dma32_rxidle(dma_info_t *di) 
    18232 +{ 
    18233 +       DMA_TRACE(("%s: dma_rxidle\n", di->name)); 
    18234 + 
    18235 +       if (di->nrxd == 0) 
    18236 +               return TRUE; 
    18237 + 
    18238 +       return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == 
    18239 +               R_REG(di->osh, &di->d32rxregs->ptr)); 
    18240 +} 
    18241 + 
    18242 +static bool 
    18243 +dma32_rxreset(dma_info_t *di) 
    18244 +{ 
    18245 +       uint32 status; 
    18246 + 
    18247 +       if (di->nrxd == 0) 
    18248 +               return TRUE; 
    18249 + 
    18250 +       W_REG(di->osh, &di->d32rxregs->control, 0); 
    18251 +       SPINWAIT(((status = (R_REG(di->osh, 
    18252 +                &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), 
    18253 +                10000); 
    18254 + 
    18255 +       return (status == RS_RS_DISABLED); 
    18256 +} 
    18257 + 
    18258 +static bool 
    18259 +dma32_rxenabled(dma_info_t *di) 
    18260 +{ 
    18261 +       uint32 rc; 
    18262 + 
    18263 +       rc = R_REG(di->osh, &di->d32rxregs->control); 
    18264 +       return ((rc != 0xffffffff) && (rc & RC_RE)); 
    18265 +} 
    18266 + 
    18267 +static bool 
    18268 +dma32_txsuspendedidle(dma_info_t *di) 
    18269 +{ 
    18270 +       if (di->ntxd == 0) 
    18271 +               return TRUE; 
    18272 + 
    18273 +       if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) 
    18274 +               return 0; 
    18275 + 
    18276 +       if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) 
    18277 +               return 0; 
    18278 + 
    18279 +       OSL_DELAY(2); 
    18280 +       return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); 
    18281 +} 
    18282 + 
    18283 +/* !! tx entry routine 
    18284 + * supports full 32bit dma engine buffer addressing so 
    18285 + * dma buffers can cross 4 Kbyte page boundaries. 
    18286 + */ 
    18287 +static int 
    18288 +dma32_txfast(dma_info_t *di, void *p0, bool commit) 
    18289 +{ 
    18290 +       void *p, *next; 
    18291 +       uchar *data; 
    18292 +       uint len; 
    18293 +       uint txout; 
    18294 +       uint32 flags = 0; 
    18295 +       uint32 pa; 
    18296 + 
    18297 +       DMA_TRACE(("%s: dma_txfast\n", di->name)); 
    18298 + 
    18299 +       txout = di->txout; 
    18300 + 
    18301 +       /* 
    18302 +        * Walk the chain of packet buffers 
    18303 +        * allocating and initializing transmit descriptor entries. 
    18304 +        */ 
    18305 +       for (p = p0; p; p = next) { 
    18306 +               data = PKTDATA(di->osh, p); 
    18307 +               len = PKTLEN(di->osh, p); 
    18308 +               next = PKTNEXT(di->osh, p); 
    18309 + 
    18310 +               /* return nonzero if out of tx descriptors */ 
    18311 +               if (NEXTTXD(txout) == di->txin) 
    18312 +                       goto outoftxd; 
    18313 + 
    18314 +               if (len == 0) 
    18315 +                       continue; 
    18316 + 
    18317 +               /* get physical address of buffer start */ 
    18318 +               pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); 
    18319 + 
    18320 +               flags = 0; 
    18321 +               if (p == p0) 
    18322 +                       flags |= CTRL_SOF; 
    18323 +               if (next == NULL) 
    18324 +                       flags |= (CTRL_IOC | CTRL_EOF); 
    18325 +               if (txout == (di->ntxd - 1)) 
    18326 +                       flags |= CTRL_EOT; 
    18327 + 
    18328 +               dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); 
    18329 +               ASSERT(di->txp[txout] == NULL); 
    18330 + 
    18331 +               txout = NEXTTXD(txout); 
    18332 +       } 
    18333 + 
    18334 +       /* if last txd eof not set, fix it */ 
    18335 +       if (!(flags & CTRL_EOF)) 
    18336 +               W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); 
    18337 + 
    18338 +       /* save the packet */ 
    18339 +       di->txp[PREVTXD(txout)] = p0; 
    18340 + 
    18341 +       /* bump the tx descriptor index */ 
    18342 +       di->txout = txout; 
    18343 + 
    18344 +       /* kick the chip */ 
    18345 +       if (commit) 
    18346 +               W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); 
    18347 + 
    18348 +       /* tx flow control */ 
    18349 +       di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; 
    18350 + 
    18351 +       return (0); 
    18352 + 
    18353 +outoftxd: 
    18354 +       DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); 
    18355 +       PKTFREE(di->osh, p0, TRUE); 
    18356 +       di->hnddma.txavail = 0; 
    18357 +       di->hnddma.txnobuf++; 
    18358 +       return (-1); 
    18359 +} 
    18360 + 
    18361 +/* 
    18362 + * Reclaim next completed txd (txds if using chained buffers) and 
    18363 + * return associated packet. 
    18364 + * If 'force' is true, reclaim txd(s) and return associated packet 
    18365 + * regardless of the value of the hardware "curr" pointer. 
    18366 + */ 
    18367 +static void * 
    18368 +dma32_getnexttxp(dma_info_t *di, bool forceall) 
    18369 +{ 
    18370 +       uint start, end, i; 
    18371 +       void *txp; 
    18372 + 
    18373 +       DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); 
    18374 + 
    18375 +       if (di->ntxd == 0) 
    18376 +               return (NULL); 
    18377 + 
    18378 +       txp = NULL; 
    18379 + 
    18380 +       start = di->txin; 
    18381 +       if (forceall) 
    18382 +               end = di->txout; 
    18383 +       else 
    18384 +               end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); 
    18385 + 
    18386 +       if ((start == 0) && (end > di->txout)) 
    18387 +               goto bogus; 
    18388 + 
    18389 +       for (i = start; i != end && !txp; i = NEXTTXD(i)) { 
    18390 +               DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), 
    18391 +                         (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), 
    18392 +                         DMA_TX, di->txp[i]); 
    18393 + 
    18394 +               W_SM(&di->txd32[i].addr, 0xdeadbeef); 
    18395 +               txp = di->txp[i]; 
    18396 +               di->txp[i] = NULL; 
    18397 +       } 
    18398 + 
    18399 +       di->txin = i; 
    18400 + 
    18401 +       /* tx flow control */ 
    18402 +       di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; 
    18403 + 
    18404 +       return (txp); 
    18405 + 
    18406 +bogus: 
    18407 +/* 
    18408 +       DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", 
    18409 +               start, end, di->txout, forceall)); 
    18410 +*/ 
    18411 +       return (NULL); 
    18412 +} 
    18413 + 
    18414 +static void * 
    18415 +dma32_getnextrxp(dma_info_t *di, bool forceall) 
    18416 +{ 
    18417 +       uint i; 
    18418 +       void *rxp; 
    18419 + 
    18420 +       /* if forcing, dma engine must be disabled */ 
    18421 +       ASSERT(!forceall || !dma32_rxenabled(di)); 
    18422 + 
    18423 +       i = di->rxin; 
    18424 + 
    18425 +       /* return if no packets posted */ 
    18426 +       if (i == di->rxout) 
    18427 +               return (NULL); 
    18428 + 
    18429 +       /* ignore curr if forceall */ 
    18430 +       if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) 
    18431 +               return (NULL); 
    18432 + 
    18433 +       /* get the packet pointer that corresponds to the rx descriptor */ 
    18434 +       rxp = di->rxp[i]; 
    18435 +       ASSERT(rxp); 
    18436 +       di->rxp[i] = NULL; 
    18437 + 
    18438 +       /* clear this packet from the descriptor ring */ 
    18439 +       DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), 
    18440 +                 di->rxbufsize, DMA_RX, rxp); 
    18441 + 
    18442 +       W_SM(&di->rxd32[i].addr, 0xdeadbeef); 
    18443 + 
    18444 +       di->rxin = NEXTRXD(i); 
    18445 + 
    18446 +       return (rxp); 
    18447 +} 
    18448 + 
    18449 +/* 
    18450 + * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). 
    18451 + */ 
    18452 +static void 
    18453 +dma32_txrotate(dma_info_t *di) 
    18454 +{ 
    18455 +       uint ad; 
    18456 +       uint nactive; 
    18457 +       uint rot; 
    18458 +       uint old, new; 
    18459 +       uint32 w; 
    18460 +       uint first, last; 
    18461 + 
    18462 +       ASSERT(dma32_txsuspendedidle(di)); 
    18463 + 
    18464 +       nactive = _dma_txactive(di); 
    18465 +       ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); 
    18466 +       rot = TXD(ad - di->txin); 
    18467 + 
    18468 +       ASSERT(rot < di->ntxd); 
    18469 + 
    18470 +       /* full-ring case is a lot harder - don't worry about this */ 
    18471 +       if (rot >= (di->ntxd - nactive)) { 
    18472 +               DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); 
    18473 +               return; 
    18474 +       } 
    18475 + 
    18476 +       first = di->txin; 
    18477 +       last = PREVTXD(di->txout); 
    18478 + 
    18479 +       /* move entries starting at last and moving backwards to first */ 
    18480 +       for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { 
    18481 +               new = TXD(old + rot); 
    18482 + 
    18483 +               /* 
    18484 +                * Move the tx dma descriptor. 
    18485 +                * EOT is set only in the last entry in the ring. 
    18486 +                */ 
    18487 +               w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; 
    18488 +               if (new == (di->ntxd - 1)) 
    18489 +                       w |= CTRL_EOT; 
    18490 +               W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); 
    18491 +               W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); 
    18492 + 
    18493 +               /* zap the old tx dma descriptor address field */ 
    18494 +               W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); 
    18495 + 
    18496 +               /* move the corresponding txp[] entry */ 
    18497 +               ASSERT(di->txp[new] == NULL); 
    18498 +               di->txp[new] = di->txp[old]; 
    18499 +               di->txp[old] = NULL; 
    18500 +       } 
    18501 + 
    18502 +       /* update txin and txout */ 
    18503 +       di->txin = ad; 
    18504 +       di->txout = TXD(di->txout + rot); 
    18505 +       di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; 
    18506 + 
    18507 +       /* kick the chip */ 
    18508 +       W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); 
    18509 +} 
    18510 + 
    18511 + 
    18512 +uint 
    18513 +dma_addrwidth(sb_t *sbh, void *dmaregs) 
    18514 +{ 
    18515 +       dma32regs_t *dma32regs; 
    18516 +       osl_t *osh; 
    18517 + 
    18518 +       osh = sb_osh(sbh); 
    18519 + 
    18520 +       /* Start checking for 32-bit / 30-bit addressing */ 
    18521 +       dma32regs = (dma32regs_t *)dmaregs; 
    18522 + 
    18523 +       /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ 
    18524 +       if ((BUSTYPE(sbh->bustype) == SB_BUS) || 
    18525 +           ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) || 
    18526 +           (_dma32_addrext(osh, dma32regs))) 
    18527 +               return (DMADDRWIDTH_32); 
    18528 + 
    18529 +       /* Fallthru */ 
    18530 +       return (DMADDRWIDTH_30); 
    18531 +} 
    18532 diff -urN linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h 
    18533 --- linux.old/drivers/net/wl/hnddma.h   1970-01-01 01:00:00.000000000 +0100 
    18534 +++ linux.dev/drivers/net/wl/hnddma.h   2006-04-28 02:20:44.000000000 +0200 
    18535 @@ -0,0 +1,156 @@ 
    18536 +/* 
    18537 + * Generic Broadcom Home Networking Division (HND) DMA engine SW interface 
    18538 + * This supports the following chips: BCM42xx, 44xx, 47xx . 
    18539 + * 
    18540 + * Copyright 2006, Broadcom Corporation 
    18541 + * All Rights Reserved. 
    18542 + *  
    18543 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    18544 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    18545 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    18546 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    18547 + * $Id: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ 
    18548 + */ 
    18549 + 
    18550 +#ifndef        _hnddma_h_ 
    18551 +#define        _hnddma_h_ 
    18552 + 
    18553 +typedef const struct hnddma_pub hnddma_t; 
    18554 + 
    18555 +/* dma function type */ 
    18556 +typedef void (*di_detach_t)(hnddma_t *dmah); 
    18557 +typedef bool (*di_txreset_t)(hnddma_t *dmah); 
    18558 +typedef bool (*di_rxreset_t)(hnddma_t *dmah); 
    18559 +typedef bool (*di_rxidle_t)(hnddma_t *dmah); 
    18560 +typedef void (*di_txinit_t)(hnddma_t *dmah); 
    18561 +typedef bool (*di_txenabled_t)(hnddma_t *dmah); 
    18562 +typedef void (*di_rxinit_t)(hnddma_t *dmah); 
    18563 +typedef void (*di_txsuspend_t)(hnddma_t *dmah); 
    18564 +typedef void (*di_txresume_t)(hnddma_t *dmah); 
    18565 +typedef bool (*di_txsuspended_t)(hnddma_t *dmah); 
    18566 +typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); 
    18567 +typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); 
    18568 +typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); 
    18569 +typedef bool  (*di_txstopped_t)(hnddma_t *dmah); 
    18570 +typedef bool  (*di_rxstopped_t)(hnddma_t *dmah); 
    18571 +typedef bool  (*di_rxenable_t)(hnddma_t *dmah); 
    18572 +typedef bool  (*di_rxenabled_t)(hnddma_t *dmah); 
    18573 +typedef void* (*di_rx_t)(hnddma_t *dmah); 
    18574 +typedef void (*di_rxfill_t)(hnddma_t *dmah); 
    18575 +typedef void (*di_txreclaim_t)(hnddma_t *dmah, bool forceall); 
    18576 +typedef void (*di_rxreclaim_t)(hnddma_t *dmah); 
    18577 +typedef        uintptr (*di_getvar_t)(hnddma_t *dmah, char *name); 
    18578 +typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, bool forceall); 
    18579 +typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); 
    18580 +typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); 
    18581 +typedef void (*di_txblock_t)(hnddma_t *dmah); 
    18582 +typedef void (*di_txunblock_t)(hnddma_t *dmah); 
    18583 +typedef uint (*di_txactive_t)(hnddma_t *dmah); 
    18584 +typedef void (*di_txrotate_t)(hnddma_t *dmah); 
    18585 +typedef void (*di_counterreset_t)(hnddma_t *dmah); 
    18586 +typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); 
    18587 +typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); 
    18588 +typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); 
    18589 + 
    18590 +/* dma opsvec */ 
    18591 +typedef struct di_fcn_s { 
    18592 +       di_detach_t             detach; 
    18593 +       di_txinit_t             txinit; 
    18594 +       di_txreset_t            txreset; 
    18595 +       di_txenabled_t          txenabled; 
    18596 +       di_txsuspend_t          txsuspend; 
    18597 +       di_txresume_t           txresume; 
    18598 +       di_txsuspended_t        txsuspended; 
    18599 +       di_txsuspendedidle_t    txsuspendedidle; 
    18600 +       di_txfast_t             txfast; 
    18601 +       di_txstopped_t          txstopped; 
    18602 +       di_txreclaim_t          txreclaim; 
    18603 +       di_getnexttxp_t         getnexttxp; 
    18604 +       di_peeknexttxp_t        peeknexttxp; 
    18605 +       di_txblock_t            txblock; 
    18606 +       di_txunblock_t          txunblock; 
    18607 +       di_txactive_t           txactive; 
    18608 +       di_txrotate_t           txrotate; 
    18609 + 
    18610 +       di_rxinit_t             rxinit; 
    18611 +       di_rxreset_t            rxreset; 
    18612 +       di_rxidle_t             rxidle; 
    18613 +       di_rxstopped_t          rxstopped; 
    18614 +       di_rxenable_t           rxenable; 
    18615 +       di_rxenabled_t          rxenabled; 
    18616 +       di_rx_t                 rx; 
    18617 +       di_rxfill_t             rxfill; 
    18618 +       di_rxreclaim_t          rxreclaim; 
    18619 +       di_getnextrxp_t         getnextrxp; 
    18620 + 
    18621 +       di_fifoloopbackenable_t fifoloopbackenable; 
    18622 +       di_getvar_t             d_getvar; 
    18623 +       di_counterreset_t       counterreset; 
    18624 +       di_dump_t               dump; 
    18625 +       di_dumptx_t             dumptx; 
    18626 +       di_dumprx_t             dumprx; 
    18627 +       uint                    endnum; 
    18628 +} di_fcn_t; 
    18629 + 
    18630 +/* 
    18631 + * Exported data structure (read-only) 
    18632 + */ 
    18633 +/* export structure */ 
    18634 +struct hnddma_pub { 
    18635 +       di_fcn_t        di_fn;          /* DMA function pointers */ 
    18636 +       uint            txavail;        /* # free tx descriptors */ 
    18637 + 
    18638 +       /* rx error counters */ 
    18639 +       uint            rxgiants;       /* rx giant frames */ 
    18640 +       uint            rxnobuf;        /* rx out of dma descriptors */ 
    18641 +       /* tx error counters */ 
    18642 +       uint            txnobuf;        /* tx out of dma descriptors */ 
    18643 +}; 
    18644 + 
    18645 + 
    18646 +extern hnddma_t * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, 
    18647 +                             uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, 
    18648 +                             uint *msg_level); 
    18649 +#define dma_detach(di)                 ((di)->di_fn.detach(di)) 
    18650 +#define dma_txreset(di)                        ((di)->di_fn.txreset(di)) 
    18651 +#define dma_rxreset(di)                        ((di)->di_fn.rxreset(di)) 
    18652 +#define dma_rxidle(di)                 ((di)->di_fn.rxidle(di)) 
    18653 +#define dma_txinit(di)                  ((di)->di_fn.txinit(di)) 
    18654 +#define dma_txenabled(di)               ((di)->di_fn.txenabled(di)) 
    18655 +#define dma_rxinit(di)                  ((di)->di_fn.rxinit(di)) 
    18656 +#define dma_txsuspend(di)               ((di)->di_fn.txsuspend(di)) 
    18657 +#define dma_txresume(di)                ((di)->di_fn.txresume(di)) 
    18658 +#define dma_txsuspended(di)             ((di)->di_fn.txsuspended(di)) 
    18659 +#define dma_txsuspendedidle(di)         ((di)->di_fn.txsuspendedidle(di)) 
    18660 +#define dma_txfast(di, p, commit)      ((di)->di_fn.txfast(di, p, commit)) 
    18661 +#define dma_fifoloopbackenable(di)      ((di)->di_fn.fifoloopbackenable(di)) 
    18662 +#define dma_txstopped(di)               ((di)->di_fn.txstopped(di)) 
    18663 +#define dma_rxstopped(di)               ((di)->di_fn.rxstopped(di)) 
    18664 +#define dma_rxenable(di)                ((di)->di_fn.rxenable(di)) 
    18665 +#define dma_rxenabled(di)               ((di)->di_fn.rxenabled(di)) 
    18666 +#define dma_rx(di)                      ((di)->di_fn.rx(di)) 
    18667 +#define dma_rxfill(di)                  ((di)->di_fn.rxfill(di)) 
    18668 +#define dma_txreclaim(di, forceall)    ((di)->di_fn.txreclaim(di, forceall)) 
    18669 +#define dma_rxreclaim(di)               ((di)->di_fn.rxreclaim(di)) 
    18670 +#define dma_getvar(di, name)           ((di)->di_fn.d_getvar(di, name)) 
    18671 +#define dma_getnexttxp(di, forceall)    ((di)->di_fn.getnexttxp(di, forceall)) 
    18672 +#define dma_getnextrxp(di, forceall)    ((di)->di_fn.getnextrxp(di, forceall)) 
    18673 +#define dma_peeknexttxp(di)             ((di)->di_fn.peeknexttxp(di)) 
    18674 +#define dma_txblock(di)                 ((di)->di_fn.txblock(di)) 
    18675 +#define dma_txunblock(di)               ((di)->di_fn.txunblock(di)) 
    18676 +#define dma_txactive(di)                ((di)->di_fn.txactive(di)) 
    18677 +#define dma_txrotate(di)                ((di)->di_fn.txrotate(di)) 
    18678 +#define dma_counterreset(di)            ((di)->di_fn.counterreset(di)) 
    18679 + 
    18680 +#define DMA_DUMP_SIZE 2048 
    18681 +/* return addresswidth allowed 
    18682 + * This needs to be done after SB attach but before dma attach. 
    18683 + * SB attach provides ability to probe backplane and dma core capabilities 
    18684 + * This info is needed by DMA_ALLOC_CONSISTENT in dma attach 
    18685 + */ 
    18686 +extern uint dma_addrwidth(sb_t *sbh, void *dmaregs); 
    18687 + 
    18688 +/* pio helpers */ 
    18689 +void dma_txpioloopback(osl_t *osh, dma32regs_t *); 
    18690 + 
    18691 +#endif /* _hnddma_h_ */ 
    18692 diff -urN linux.old/drivers/net/wl/linux_osl.c linux.dev/drivers/net/wl/linux_osl.c 
    18693 --- linux.old/drivers/net/wl/linux_osl.c        1970-01-01 01:00:00.000000000 +0100 
    18694 +++ linux.dev/drivers/net/wl/linux_osl.c        2006-04-28 02:29:46.000000000 +0200 
    18695 @@ -0,0 +1,269 @@ 
    18696 +/* 
    18697 + * Linux OS Independent Layer 
    18698 + * 
    18699 + * Copyright 2006, Broadcom Corporation 
    18700 + * All Rights Reserved. 
    18701 + *  
    18702 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    18703 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    18704 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    18705 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    18706 + * 
    18707 + * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $ 
    18708 + */ 
    18709 + 
    18710 +#define LINUX_OSL 
    18711 + 
    18712 +#include <typedefs.h> 
    18713 +#include <bcmendian.h> 
    18714 +#include <linux/module.h> 
    18715 +#include <linuxver.h> 
    18716 +#include <bcmdefs.h> 
    18717 +#include <osl.h> 
    18718 +#include "linux_osl.h" 
    18719 +#include <bcmutils.h> 
    18720 +#include <linux/delay.h> 
    18721 +#ifdef mips 
    18722 +#include <asm/paccess.h> 
    18723 +#endif /* mips */ 
    18724 +#include <pcicfg.h> 
    18725 + 
    18726 +#define PCI_CFG_RETRY          10       
    18727 + 
    18728 +#define OS_HANDLE_MAGIC                0x1234abcd      /* Magic # to recognise osh */ 
    18729 +#define BCM_MEM_FILENAME_LEN   24              /* Mem. filename length */ 
    18730 + 
    18731 +typedef struct bcm_mem_link { 
    18732 +       struct bcm_mem_link *prev; 
    18733 +       struct bcm_mem_link *next; 
    18734 +       uint    size; 
    18735 +       int     line; 
    18736 +       char    file[BCM_MEM_FILENAME_LEN]; 
    18737 +} bcm_mem_link_t; 
    18738 + 
    18739 +static int16 linuxbcmerrormap[] =  \ 
    18740 +{      0,                      /* 0 */ 
    18741 +       -EINVAL,                /* BCME_ERROR */ 
    18742 +       -EINVAL,                /* BCME_BADARG */ 
    18743 +       -EINVAL,                /* BCME_BADOPTION */ 
    18744 +       -EINVAL,                /* BCME_NOTUP */ 
    18745 +       -EINVAL,                /* BCME_NOTDOWN */ 
    18746 +       -EINVAL,                /* BCME_NOTAP */ 
    18747 +       -EINVAL,                /* BCME_NOTSTA */ 
    18748 +       -EINVAL,                /* BCME_BADKEYIDX */ 
    18749 +       -EINVAL,                /* BCME_RADIOOFF */ 
    18750 +       -EINVAL,                /* BCME_NOTBANDLOCKED */ 
    18751 +       -EINVAL,                /* BCME_NOCLK */ 
    18752 +       -EINVAL,                /* BCME_BADRATESET */ 
    18753 +       -EINVAL,                /* BCME_BADBAND */ 
    18754 +       -E2BIG,                 /* BCME_BUFTOOSHORT */ 
    18755 +       -E2BIG,                 /* BCME_BUFTOOLONG */ 
    18756 +       -EBUSY,                 /* BCME_BUSY */ 
    18757 +       -EINVAL,                /* BCME_NOTASSOCIATED */ 
    18758 +       -EINVAL,                /* BCME_BADSSIDLEN */ 
    18759 +       -EINVAL,                /* BCME_OUTOFRANGECHAN */ 
    18760 +       -EINVAL,                /* BCME_BADCHAN */ 
    18761 +       -EFAULT,                /* BCME_BADADDR */ 
    18762 +       -ENOMEM,                /* BCME_NORESOURCE */ 
    18763 +       -EOPNOTSUPP,            /* BCME_UNSUPPORTED */ 
    18764 +       -EMSGSIZE,              /* BCME_BADLENGTH */ 
    18765 +       -EINVAL,                /* BCME_NOTREADY */ 
    18766 +       -EPERM,                 /* BCME_NOTPERMITTED */ 
    18767 +       -ENOMEM,                /* BCME_NOMEM */ 
    18768 +       -EINVAL,                /* BCME_ASSOCIATED */ 
    18769 +       -ERANGE,                /* BCME_RANGE */ 
    18770 +       -EINVAL,                /* BCME_NOTFOUND */ 
    18771 +       -EINVAL,                /* BCME_WME_NOT_ENABLED */ 
    18772 +       -EINVAL,                /* BCME_TSPEC_NOTFOUND */ 
    18773 +       -EINVAL,                /* BCME_ACM_NOTSUPPORTED */ 
    18774 +       -EINVAL,                /* BCME_NOT_WME_ASSOCIATION */ 
    18775 +       -EIO,                   /* BCME_SDIO_ERROR */ 
    18776 +       -ENODEV                 /* BCME_DONGLE_DOWN */ 
    18777 +}; 
    18778 + 
    18779 +/* translate bcmerrors into linux errors */ 
    18780 +int 
    18781 +osl_error(int bcmerror) 
    18782 +{ 
    18783 +       int abs_bcmerror; 
    18784 +       int array_size = ARRAYSIZE(linuxbcmerrormap); 
    18785 + 
    18786 +       abs_bcmerror = ABS(bcmerror); 
    18787 + 
    18788 +       if (bcmerror > 0) 
    18789 +               abs_bcmerror = 0; 
    18790 + 
    18791 +       else if (abs_bcmerror >= array_size) 
    18792 +               abs_bcmerror = BCME_ERROR; 
    18793 + 
    18794 +       return linuxbcmerrormap[abs_bcmerror]; 
    18795 +} 
    18796 + 
    18797 +osl_t * 
    18798 +osl_attach(void *pdev, bool pkttag) 
    18799 +{ 
    18800 +       osl_t *osh; 
    18801 + 
    18802 +       osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); 
    18803 +       ASSERT(osh); 
    18804 + 
    18805 +       bzero(osh, sizeof(osl_t)); 
    18806 + 
    18807 +       /* 
    18808 +        * check the cases where 
    18809 +        * 1.Error code Added to bcmerror table, but forgot to add it to the OS 
    18810 +        * dependent error code 
    18811 +        * 2. Error code is added to the bcmerror table, but forgot to add the 
    18812 +        * corresponding errorstring(dummy call to bcmerrorstr) 
    18813 +        */ 
    18814 +       bcmerrorstr(0); 
    18815 +       ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); 
    18816 + 
    18817 +       osh->magic = OS_HANDLE_MAGIC; 
    18818 +       osh->malloced = 0; 
    18819 +       osh->failed = 0; 
    18820 +       osh->dbgmem_list = NULL; 
    18821 +       osh->pdev = pdev; 
    18822 +       osh->pub.pkttag = pkttag; 
    18823 + 
    18824 +       return osh; 
    18825 +} 
    18826 + 
    18827 +void 
    18828 +osl_detach(osl_t *osh) 
    18829 +{ 
    18830 +       if (osh == NULL) 
    18831 +               return; 
    18832 + 
    18833 +       ASSERT(osh->magic == OS_HANDLE_MAGIC); 
    18834 +       kfree(osh); 
    18835 +} 
    18836 + 
    18837 +/* Return a new packet. zero out pkttag */ 
    18838 +void* 
    18839 +osl_pktget(osl_t *osh, uint len, bool send) 
    18840 +{ 
    18841 +       struct sk_buff *skb; 
    18842 + 
    18843 +       if ((skb = dev_alloc_skb(len))) { 
    18844 +               skb_put(skb, len); 
    18845 +               skb->priority = 0; 
    18846 + 
    18847 +#ifdef BCMDBG_PKT 
    18848 +       pktlist_add(&(osh->pktlist), (void *) skb); 
    18849 +#endif  /* BCMDBG_PKT */ 
    18850 + 
    18851 +               osh->pub.pktalloced++; 
    18852 +       } 
    18853 + 
    18854 +       return ((void*) skb); 
    18855 +} 
    18856 + 
    18857 +/* Free the driver packet. Free the tag if present */ 
    18858 +void 
    18859 +osl_pktfree(osl_t *osh, void *p) 
    18860 +{ 
    18861 +       struct sk_buff *skb, *nskb; 
    18862 + 
    18863 +       skb = (struct sk_buff*) p; 
    18864 + 
    18865 +       /* perversion: we use skb->next to chain multi-skb packets */ 
    18866 +       while (skb) { 
    18867 +               nskb = skb->next; 
    18868 +               skb->next = NULL; 
    18869 + 
    18870 +#ifdef BCMDBG_PKT 
    18871 +               pktlist_remove(&(osh->pktlist), (void *) skb); 
    18872 +#endif  /* BCMDBG_PKT */ 
    18873 + 
    18874 +               if (skb->destructor) { 
    18875 +                       /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists 
    18876 +                        */ 
    18877 +                       dev_kfree_skb_any(skb); 
    18878 +               } else { 
    18879 +                       /* can free immediately (even in_irq()) if destructor does not exist */ 
    18880 +                       dev_kfree_skb(skb); 
    18881 +               } 
    18882 + 
    18883 +               osh->pub.pktalloced--; 
    18884 + 
    18885 +               skb = nskb; 
    18886 +       } 
    18887 +} 
    18888 + 
    18889 +void* 
    18890 +osl_malloc(osl_t *osh, uint size) 
    18891 +{ 
    18892 +       void *addr; 
    18893 + 
    18894 +       /* only ASSERT if osh is defined */ 
    18895 +       if (osh) 
    18896 +               ASSERT(osh->magic == OS_HANDLE_MAGIC); 
    18897 + 
    18898 +       if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { 
    18899 +               if (osh) 
    18900 +                       osh->failed++; 
    18901 +               return (NULL); 
    18902 +       } 
    18903 +       if (osh) 
    18904 +               osh->malloced += size; 
    18905 + 
    18906 +       return (addr); 
    18907 +} 
    18908 + 
    18909 +void 
    18910 +osl_mfree(osl_t *osh, void *addr, uint size) 
    18911 +{ 
    18912 +       if (osh) { 
    18913 +               ASSERT(osh->magic == OS_HANDLE_MAGIC); 
    18914 +               osh->malloced -= size; 
    18915 +       } 
    18916 +       kfree(addr); 
    18917 +} 
    18918 + 
    18919 +uint 
    18920 +osl_malloced(osl_t *osh) 
    18921 +{ 
    18922 +       ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); 
    18923 +       return (osh->malloced); 
    18924 +} 
    18925 + 
    18926 +uint osl_malloc_failed(osl_t *osh) 
    18927 +{ 
    18928 +       ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); 
    18929 +       return (osh->failed); 
    18930 +} 
    18931 + 
    18932 +#undef osl_delay 
    18933 +void 
    18934 +osl_delay(uint usec) 
    18935 +{ 
    18936 +       OSL_DELAY(usec); 
    18937 +} 
    18938 + 
    18939 +/* Clone a packet. 
    18940 + * The pkttag contents are NOT cloned. 
    18941 + */ 
    18942 +void * 
    18943 +osl_pktdup(osl_t *osh, void *skb) 
    18944 +{ 
    18945 +       void * p; 
    18946 + 
    18947 +       if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) 
    18948 +               return NULL; 
    18949 + 
    18950 +       /* skb_clone copies skb->cb.. we don't want that */ 
    18951 +       if (osh->pub.pkttag) 
    18952 +               bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); 
    18953 + 
    18954 +       /* Increment the packet counter */ 
    18955 +       osh->pub.pktalloced++; 
    18956 +       return (p); 
    18957 +} 
    18958 + 
    18959 +uint 
    18960 +osl_pktalloced(osl_t *osh) 
    18961 +{ 
    18962 +       return (osh->pub.pktalloced); 
    18963 +} 
    18964 + 
    18965 diff -urN linux.old/drivers/net/wl/linux_osl.h linux.dev/drivers/net/wl/linux_osl.h 
    18966 --- linux.old/drivers/net/wl/linux_osl.h        1970-01-01 01:00:00.000000000 +0100 
    18967 +++ linux.dev/drivers/net/wl/linux_osl.h        2006-05-02 17:44:29.000000000 +0200 
    18968 @@ -0,0 +1,171 @@ 
    18969 +/* 
    18970 + * Linux OS Independent Layer 
    18971 + * 
    18972 + * Copyright 2006, Broadcom Corporation 
    18973 + * All Rights Reserved. 
    18974 + *  
    18975 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    18976 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    18977 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    18978 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    18979 + * 
    18980 + * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ 
    18981 + */ 
    18982 + 
    18983 +#ifndef _linux_osl_h_ 
    18984 +#define _linux_osl_h_ 
    18985 + 
    18986 +#include <typedefs.h> 
    18987 +#include <linuxver.h> 
    18988 +#include <osl.h> 
    18989 + 
    18990 +#define OSL_PKTTAG_SZ     32 /* Size of PktTag */ 
    18991 + 
    18992 +/* osl handle type forward declaration */ 
    18993 +typedef struct osl_dmainfo osldma_t; 
    18994 + 
    18995 +/* OSL initialization */ 
    18996 +extern osl_t *osl_attach(void *pdev, bool pkttag); 
    18997 +extern void osl_detach(osl_t *osh); 
    18998 + 
    18999 +/* host/bus architecture-specific byte swap */ 
    19000 +#define BUS_SWAP32(v)          (v) 
    19001 +#define        MALLOC_FAILED(osh)      osl_malloc_failed((osh)) 
    19002 + 
    19003 +extern void *osl_malloc(osl_t *osh, uint size); 
    19004 +extern void osl_mfree(osl_t *osh, void *addr, uint size); 
    19005 +extern uint osl_malloced(osl_t *osh); 
    19006 +extern uint osl_malloc_failed(osl_t *osh); 
    19007 + 
    19008 +/* API for DMA addressing capability */ 
    19009 +#define        DMA_MAP(osh, va, size, direction, p) \ 
    19010 +       osl_dma_map((osh), (va), (size), (direction)) 
    19011 +#define        DMA_UNMAP(osh, pa, size, direction, p) \ 
    19012 +       osl_dma_unmap((osh), (pa), (size), (direction)) 
    19013 +static inline uint 
    19014 +osl_dma_map(void *osh, void *va, uint size, int direction) 
    19015 +{ 
    19016 +       int dir; 
    19017 +       struct pci_dev *dev; 
    19018 + 
    19019 +       dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); 
    19020 +       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; 
    19021 +       return (pci_map_single(dev, va, size, dir)); 
    19022 +} 
    19023 + 
    19024 +static inline void 
    19025 +osl_dma_unmap(void *osh, uint pa, uint size, int direction) 
    19026 +{ 
    19027 +       int dir; 
    19028 +       struct pci_dev *dev; 
    19029 + 
    19030 +       dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); 
    19031 +       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; 
    19032 +       pci_unmap_single(dev, (uint32)pa, size, dir); 
    19033 +} 
    19034 + 
    19035 +#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) 
    19036 +#define        DMA_CONSISTENT_ALIGN    PAGE_SIZE 
    19037 +#define        DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \ 
    19038 +       osl_dma_alloc_consistent((osh), (size), (pap)) 
    19039 +#define        DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ 
    19040 +       osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) 
    19041 +static inline void* 
    19042 +osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) 
    19043 +{ 
    19044 +       return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); 
    19045 +} 
    19046 + 
    19047 +static inline void 
    19048 +osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) 
    19049 +{ 
    19050 +       pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); 
    19051 +} 
    19052 + 
    19053 + 
    19054 +/* register access macros */ 
    19055 +#if defined(BCMJTAG) 
    19056 +#include <bcmjtag.h> 
    19057 +#define        R_REG(osh, r)   bcmjtag_read(NULL, (uint32)(r), sizeof(*(r))) 
    19058 +#define        W_REG(osh, r, v)        bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r))) 
    19059 +#endif /* defined(BCMSDIO) */ 
    19060 + 
    19061 +/* packet primitives */ 
    19062 +#define        PKTGET(osh, len, send)          osl_pktget((osh), (len), (send)) 
    19063 +#define        PKTFREE(osh, skb, send)         osl_pktfree((osh), (skb)) 
    19064 +#define        PKTDATA(osh, skb)               (((struct sk_buff*)(skb))->data) 
    19065 +#define        PKTLEN(osh, skb)                (((struct sk_buff*)(skb))->len) 
    19066 +#define PKTHEADROOM(osh, skb)          (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) 
    19067 +#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) 
    19068 +#define        PKTNEXT(osh, skb)               (((struct sk_buff*)(skb))->next) 
    19069 +#define        PKTSETNEXT(osh, skb, x)         (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) 
    19070 +#define        PKTSETLEN(osh, skb, len)        __skb_trim((struct sk_buff*)(skb), (len)) 
    19071 +#define        PKTPUSH(osh, skb, bytes)        skb_push((struct sk_buff*)(skb), (bytes)) 
    19072 +#define        PKTPULL(osh, skb, bytes)        skb_pull((struct sk_buff*)(skb), (bytes)) 
    19073 +#define        PKTDUP(osh, skb)                osl_pktdup((osh), (skb)) 
    19074 +#define        PKTTAG(skb)                     ((void*)(((struct sk_buff*)(skb))->cb)) 
    19075 +#define PKTALLOCED(osh)                        osl_pktalloced((osh)) 
    19076 +#define PKTLIST_DUMP(osh, buf) 
    19077 + 
    19078 +/* Convert a native(OS) packet to driver packet. 
    19079 + * In the process, native packet is destroyed, there is no copying 
    19080 + * Also, a packettag is zeroed out 
    19081 + */ 
    19082 +static INLINE void * 
    19083 +osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) 
    19084 +{ 
    19085 +       struct sk_buff *nskb; 
    19086 + 
    19087 +       if (osh->pkttag) 
    19088 +               bzero((void*)skb->cb, OSL_PKTTAG_SZ); 
    19089 + 
    19090 +       /* Increment the packet counter */ 
    19091 +       for (nskb = skb; nskb; nskb = nskb->next) { 
    19092 +               osh->pktalloced++; 
    19093 +       } 
    19094 + 
    19095 +       return (void *)skb; 
    19096 +} 
    19097 +#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((struct osl_pubinfo *)osh), \ 
    19098 +                                                       (struct sk_buff*)(skb)) 
    19099 + 
    19100 +/* Convert a driver packet to native(OS) packet 
    19101 + * In the process, packettag is zeroed out before sending up 
    19102 + * IP code depends on skb->cb to be setup correctly with various options 
    19103 + * In our case, that means it should be 0 
    19104 + */ 
    19105 +static INLINE struct sk_buff * 
    19106 +osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) 
    19107 +{ 
    19108 +       struct sk_buff *nskb; 
    19109 + 
    19110 +       if (osh->pkttag) 
    19111 +               bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); 
    19112 + 
    19113 +       /* Decrement the packet counter */ 
    19114 +       for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { 
    19115 +               osh->pktalloced--; 
    19116 +       } 
    19117 + 
    19118 +       return (struct sk_buff *)pkt; 
    19119 +} 
    19120 +#define PKTTONATIVE(osh, pkt)          osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) 
    19121 + 
    19122 +#define        PKTLINK(skb)                    (((struct sk_buff*)(skb))->prev) 
    19123 +#define        PKTSETLINK(skb, x)              (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) 
    19124 +#define        PKTPRIO(skb)                    (((struct sk_buff*)(skb))->priority) 
    19125 +#define        PKTSETPRIO(skb, x)              (((struct sk_buff*)(skb))->priority = (x)) 
    19126 +#define PKTSHARED(skb)                  (((struct sk_buff*)(skb))->cloned) 
    19127 + 
    19128 +extern void *osl_pktget(osl_t *osh, uint len, bool send); 
    19129 +extern void osl_pktfree(osl_t *osh, void *skb); 
    19130 +extern void *osl_pktdup(osl_t *osh, void *skb); 
    19131 +extern uint osl_pktalloced(osl_t *osh); 
    19132 + 
    19133 +#define OSL_ERROR(bcmerror)    osl_error(bcmerror) 
    19134 +extern int osl_error(int bcmerror); 
    19135 + 
    19136 +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ 
    19137 +#define        PKTBUFSZ        2048   /* largest reasonable packet buffer, driver uses for ethernet MTU */ 
    19138 + 
    19139 +#endif /* _linux_osl_h_ */ 
    19140 diff -urN linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h 
    19141 --- linux.old/drivers/net/wl/pktq.h     1970-01-01 01:00:00.000000000 +0100 
    19142 +++ linux.dev/drivers/net/wl/pktq.h     2006-04-28 02:11:49.000000000 +0200 
    19143 @@ -0,0 +1,97 @@ 
    19144 +/* 
    19145 + * Misc useful os-independent macros and functions. 
    19146 + * 
    19147 + * Copyright 2006, Broadcom Corporation 
    19148 + * All Rights Reserved. 
    19149 + *  
    19150 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    19151 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    19152 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    19153 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    19154 + * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ 
    19155 + */ 
    19156 + 
    19157 +#ifndef        _pktq_h_ 
    19158 +#define        _pktq_h_ 
    19159 +#include <osl.h> 
    19160 + 
    19161 +/* osl multi-precedence packet queue */ 
    19162 + 
    19163 +#define PKTQ_LEN_DEFAULT        128    /* Max 128 packets */ 
    19164 +#define PKTQ_MAX_PREC           16     /* Maximum precedence levels */ 
    19165 + 
    19166 +struct pktq { 
    19167 +       struct pktq_prec { 
    19168 +               void *head;     /* first packet to dequeue */ 
    19169 +               void *tail;     /* last packet to dequeue */ 
    19170 +               uint16 len;     /* number of queued packets */ 
    19171 +               uint16 max;     /* maximum number of queued packets */ 
    19172 +       } q[PKTQ_MAX_PREC]; 
    19173 +       uint16 num_prec;        /* number of precedences in use */ 
    19174 +       uint16 hi_prec;         /* rapid dequeue hint (>= highest non-empty prec) */ 
    19175 +       uint16 max;             /* total max packets */ 
    19176 +       uint16 len;             /* total number of packets */ 
    19177 +}; 
    19178 + 
    19179 +#define PKTQ_PREC_ITER(pq, prec)        for (prec = (pq)->num_prec - 1; prec >= 0; prec--) 
    19180 + 
    19181 +/* forward definition of ether_addr structure used by some function prototypes */ 
    19182 + 
    19183 +struct ether_addr; 
    19184 + 
    19185 +/* operations on a specific precedence in packet queue */ 
    19186 + 
    19187 +#define pktq_psetmax(pq, prec, _max)    ((pq)->q[prec].max = (_max)) 
    19188 +#define pktq_plen(pq, prec)             ((pq)->q[prec].len) 
    19189 +#define pktq_pavail(pq, prec)           ((pq)->q[prec].max - (pq)->q[prec].len) 
    19190 +#define pktq_pfull(pq, prec)            ((pq)->q[prec].len >= (pq)->q[prec].max) 
    19191 +#define pktq_pempty(pq, prec)           ((pq)->q[prec].len == 0) 
    19192 + 
    19193 +#define pktq_ppeek(pq, prec)            ((pq)->q[prec].head) 
    19194 +#define pktq_ppeek_tail(pq, prec)       ((pq)->q[prec].tail) 
    19195 + 
    19196 +extern void *pktq_penq(struct pktq *pq, int prec, void *p); 
    19197 +extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); 
    19198 +extern void *pktq_pdeq(struct pktq *pq, int prec); 
    19199 +extern void *pktq_pdeq_tail(struct pktq *pq, int prec); 
    19200 +/* Empty the queue at particular precedence level */ 
    19201 +extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); 
    19202 +/* Remove a specified packet from its queue */ 
    19203 +extern bool pktq_pdel(struct pktq *pq, void *p, int prec); 
    19204 + 
    19205 +/* operations on a set of precedences in packet queue */ 
    19206 + 
    19207 +extern int pktq_mlen(struct pktq *pq, uint prec_bmp); 
    19208 +extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); 
    19209 + 
    19210 +/* operations on packet queue as a whole */ 
    19211 + 
    19212 +#define pktq_len(pq)                    ((int)(pq)->len) 
    19213 +#define pktq_max(pq)                    ((int)(pq)->max) 
    19214 +#define pktq_avail(pq)                  ((int)((pq)->max - (pq)->len)) 
    19215 +#define pktq_full(pq)                   ((pq)->len >= (pq)->max) 
    19216 +#define pktq_empty(pq)                  ((pq)->len == 0) 
    19217 + 
    19218 +/* operations for single precedence queues */ 
    19219 +#define pktenq(pq, p)          pktq_penq((pq), 0, (p)) 
    19220 +#define pktenq_head(pq, p)     pktq_penq_head((pq), 0, (p)) 
    19221 +#define pktdeq(pq)             pktq_pdeq((pq), 0) 
    19222 +#define pktdeq_tail(pq)                pktq_pdeq_tail((pq), 0) 
    19223 + 
    19224 +extern void pktq_init(struct pktq *pq, int num_prec, int max_len); 
    19225 +/* prec_out may be NULL if caller is not interested in return value */ 
    19226 +extern void *pktq_deq(struct pktq *pq, int *prec_out); 
    19227 +extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); 
    19228 +extern void *pktq_peek(struct pktq *pq, int *prec_out); 
    19229 +extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); 
    19230 +extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */ 
    19231 + 
    19232 +/* externs */ 
    19233 +/* packet */ 
    19234 +extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); 
    19235 +extern uint pkttotlen(osl_t *osh, void *p); 
    19236 +extern void *pktlast(osl_t *osh, void *p); 
    19237 + 
    19238 +extern void pktsetprio(void *pkt, bool update_vtag); 
    19239 + 
    19240 +#endif /* _pktq_h_ */ 
    19241 diff -urN linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h 
    19242 --- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 
    19243 +++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-28 02:20:47.000000000 +0200 
    19244 @@ -0,0 +1,284 @@ 
    19245 +/* 
    19246 + * Generic Broadcom Home Networking Division (HND) DMA engine HW interface 
    19247 + * This supports the following chips: BCM42xx, 44xx, 47xx . 
    19248 + * 
    19249 + * Copyright 2006, Broadcom Corporation 
    19250 + * All Rights Reserved. 
    19251 + *  
    19252 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    19253 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    19254 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    19255 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    19256 + * 
    19257 + * $Id: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $ 
    19258 + */ 
    19259 + 
    19260 +#ifndef        _sbhnddma_h_ 
    19261 +#define        _sbhnddma_h_ 
    19262 + 
    19263 +/* DMA structure: 
    19264 + *  support two DMA engines: 32 bits address or 64 bit addressing 
    19265 + *  basic DMA register set is per channel(transmit or receive) 
    19266 + *  a pair of channels is defined for convenience 
    19267 + */ 
    19268 + 
    19269 + 
    19270 +/* 32 bits addressing */ 
    19271 + 
    19272 +/* dma registers per channel(xmt or rcv) */ 
    19273 +typedef volatile struct { 
    19274 +       uint32  control;                /* enable, et al */ 
    19275 +       uint32  addr;                   /* descriptor ring base address (4K aligned) */ 
    19276 +       uint32  ptr;                    /* last descriptor posted to chip */ 
    19277 +       uint32  status;                 /* current active descriptor, et al */ 
    19278 +} dma32regs_t; 
    19279 + 
    19280 +typedef volatile struct { 
    19281 +       dma32regs_t     xmt;            /* dma tx channel */ 
    19282 +       dma32regs_t     rcv;            /* dma rx channel */ 
    19283 +} dma32regp_t; 
    19284 + 
    19285 +typedef volatile struct {      /* diag access */ 
    19286 +       uint32  fifoaddr;               /* diag address */ 
    19287 +       uint32  fifodatalow;            /* low 32bits of data */ 
    19288 +       uint32  fifodatahigh;           /* high 32bits of data */ 
    19289 +       uint32  pad;                    /* reserved */ 
    19290 +} dma32diag_t; 
    19291 + 
    19292 +/* 
    19293 + * DMA Descriptor 
    19294 + * Descriptors are only read by the hardware, never written back. 
    19295 + */ 
    19296 +typedef volatile struct { 
    19297 +       uint32  ctrl;           /* misc control bits & bufcount */ 
    19298 +       uint32  addr;           /* data buffer address */ 
    19299 +} dma32dd_t; 
    19300 + 
    19301 +/* 
    19302 + * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. 
    19303 + */ 
    19304 +#define        D32MAXRINGSZ    4096 
    19305 +#define        D32RINGALIGN    4096 
    19306 +#define        D32MAXDD        (D32MAXRINGSZ / sizeof (dma32dd_t)) 
    19307 + 
    19308 +/* transmit channel control */ 
    19309 +#define        XC_XE           ((uint32)1 << 0)        /* transmit enable */ 
    19310 +#define        XC_SE           ((uint32)1 << 1)        /* transmit suspend request */ 
    19311 +#define        XC_LE           ((uint32)1 << 2)        /* loopback enable */ 
    19312 +#define        XC_FL           ((uint32)1 << 4)        /* flush request */ 
    19313 +#define        XC_AE           ((uint32)3 << 16)       /* address extension bits */ 
    19314 +#define        XC_AE_SHIFT     16 
    19315 + 
    19316 +/* transmit descriptor table pointer */ 
    19317 +#define        XP_LD_MASK      0xfff                   /* last valid descriptor */ 
    19318 + 
    19319 +/* transmit channel status */ 
    19320 +#define        XS_CD_MASK      0x0fff                  /* current descriptor pointer */ 
    19321 +#define        XS_XS_MASK      0xf000                  /* transmit state */ 
    19322 +#define        XS_XS_SHIFT     12 
    19323 +#define        XS_XS_DISABLED  0x0000                  /* disabled */ 
    19324 +#define        XS_XS_ACTIVE    0x1000                  /* active */ 
    19325 +#define        XS_XS_IDLE      0x2000                  /* idle wait */ 
    19326 +#define        XS_XS_STOPPED   0x3000                  /* stopped */ 
    19327 +#define        XS_XS_SUSP      0x4000                  /* suspend pending */ 
    19328 +#define        XS_XE_MASK      0xf0000                 /* transmit errors */ 
    19329 +#define        XS_XE_SHIFT     16 
    19330 +#define        XS_XE_NOERR     0x00000                 /* no error */ 
    19331 +#define        XS_XE_DPE       0x10000                 /* descriptor protocol error */ 
    19332 +#define        XS_XE_DFU       0x20000                 /* data fifo underrun */ 
    19333 +#define        XS_XE_BEBR      0x30000                 /* bus error on buffer read */ 
    19334 +#define        XS_XE_BEDA      0x40000                 /* bus error on descriptor access */ 
    19335 +#define        XS_AD_MASK      0xfff00000              /* active descriptor */ 
    19336 +#define        XS_AD_SHIFT     20 
    19337 + 
    19338 +/* receive channel control */ 
    19339 +#define        RC_RE           ((uint32)1 << 0)        /* receive enable */ 
    19340 +#define        RC_RO_MASK      0xfe                    /* receive frame offset */ 
    19341 +#define        RC_RO_SHIFT     1 
    19342 +#define        RC_FM           ((uint32)1 << 8)        /* direct fifo receive (pio) mode */ 
    19343 +#define        RC_AE           ((uint32)3 << 16)       /* address extension bits */ 
    19344 +#define        RC_AE_SHIFT     16 
    19345 + 
    19346 +/* receive descriptor table pointer */ 
    19347 +#define        RP_LD_MASK      0xfff                   /* last valid descriptor */ 
    19348 + 
    19349 +/* receive channel status */ 
    19350 +#define        RS_CD_MASK      0x0fff                  /* current descriptor pointer */ 
    19351 +#define        RS_RS_MASK      0xf000                  /* receive state */ 
    19352 +#define        RS_RS_SHIFT     12 
    19353 +#define        RS_RS_DISABLED  0x0000                  /* disabled */ 
    19354 +#define        RS_RS_ACTIVE    0x1000                  /* active */ 
    19355 +#define        RS_RS_IDLE      0x2000                  /* idle wait */ 
    19356 +#define        RS_RS_STOPPED   0x3000                  /* reserved */ 
    19357 +#define        RS_RE_MASK      0xf0000                 /* receive errors */ 
    19358 +#define        RS_RE_SHIFT     16 
    19359 +#define        RS_RE_NOERR     0x00000                 /* no error */ 
    19360 +#define        RS_RE_DPE       0x10000                 /* descriptor protocol error */ 
    19361 +#define        RS_RE_DFO       0x20000                 /* data fifo overflow */ 
    19362 +#define        RS_RE_BEBW      0x30000                 /* bus error on buffer write */ 
    19363 +#define        RS_RE_BEDA      0x40000                 /* bus error on descriptor access */ 
    19364 +#define        RS_AD_MASK      0xfff00000              /* active descriptor */ 
    19365 +#define        RS_AD_SHIFT     20 
    19366 + 
    19367 +/* fifoaddr */ 
    19368 +#define        FA_OFF_MASK     0xffff                  /* offset */ 
    19369 +#define        FA_SEL_MASK     0xf0000                 /* select */ 
    19370 +#define        FA_SEL_SHIFT    16 
    19371 +#define        FA_SEL_XDD      0x00000                 /* transmit dma data */ 
    19372 +#define        FA_SEL_XDP      0x10000                 /* transmit dma pointers */ 
    19373 +#define        FA_SEL_RDD      0x40000                 /* receive dma data */ 
    19374 +#define        FA_SEL_RDP      0x50000                 /* receive dma pointers */ 
    19375 +#define        FA_SEL_XFD      0x80000                 /* transmit fifo data */ 
    19376 +#define        FA_SEL_XFP      0x90000                 /* transmit fifo pointers */ 
    19377 +#define        FA_SEL_RFD      0xc0000                 /* receive fifo data */ 
    19378 +#define        FA_SEL_RFP      0xd0000                 /* receive fifo pointers */ 
    19379 +#define        FA_SEL_RSD      0xe0000                 /* receive frame status data */ 
    19380 +#define        FA_SEL_RSP      0xf0000                 /* receive frame status pointers */ 
    19381 + 
    19382 +/* descriptor control flags */ 
    19383 +#define        CTRL_BC_MASK    0x1fff                  /* buffer byte count */ 
    19384 +#define        CTRL_AE         ((uint32)3 << 16)       /* address extension bits */ 
    19385 +#define        CTRL_AE_SHIFT   16 
    19386 +#define        CTRL_EOT        ((uint32)1 << 28)       /* end of descriptor table */ 
    19387 +#define        CTRL_IOC        ((uint32)1 << 29)       /* interrupt on completion */ 
    19388 +#define        CTRL_EOF        ((uint32)1 << 30)       /* end of frame */ 
    19389 +#define        CTRL_SOF        ((uint32)1 << 31)       /* start of frame */ 
    19390 + 
    19391 +/* control flags in the range [27:20] are core-specific and not defined here */ 
    19392 +#define        CTRL_CORE_MASK  0x0ff00000 
    19393 + 
    19394 +/* 64 bits addressing */ 
    19395 + 
    19396 +/* dma registers per channel(xmt or rcv) */ 
    19397 +typedef volatile struct { 
    19398 +       uint32  control;                /* enable, et al */ 
    19399 +       uint32  ptr;                    /* last descriptor posted to chip */ 
    19400 +       uint32  addrlow;                /* descriptor ring base address low 32-bits (8K aligned) */ 
    19401 +       uint32  addrhigh;               /* descriptor ring base address bits 63:32 (8K aligned) */ 
    19402 +       uint32  status0;                /* current descriptor, xmt state */ 
    19403 +       uint32  status1;                /* active descriptor, xmt error */ 
    19404 +} dma64regs_t; 
    19405 + 
    19406 +typedef volatile struct { 
    19407 +       dma64regs_t     tx;             /* dma64 tx channel */ 
    19408 +       dma64regs_t     rx;             /* dma64 rx channel */ 
    19409 +} dma64regp_t; 
    19410 + 
    19411 +typedef volatile struct {              /* diag access */ 
    19412 +       uint32  fifoaddr;               /* diag address */ 
    19413 +       uint32  fifodatalow;            /* low 32bits of data */ 
    19414 +       uint32  fifodatahigh;           /* high 32bits of data */ 
    19415 +       uint32  pad;                    /* reserved */ 
    19416 +} dma64diag_t; 
    19417 + 
    19418 +/* 
    19419 + * DMA Descriptor 
    19420 + * Descriptors are only read by the hardware, never written back. 
    19421 + */ 
    19422 +typedef volatile struct { 
    19423 +       uint32  ctrl1;          /* misc control bits & bufcount */ 
    19424 +       uint32  ctrl2;          /* buffer count and address extension */ 
    19425 +       uint32  addrlow;        /* memory address of the date buffer, bits 31:0 */ 
    19426 +       uint32  addrhigh;       /* memory address of the date buffer, bits 63:32 */ 
    19427 +} dma64dd_t; 
    19428 + 
    19429 +/* 
    19430 + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. 
    19431 + */ 
    19432 +#define        D64MAXRINGSZ    8192 
    19433 +#define        D64RINGALIGN    8192 
    19434 +#define        D64MAXDD        (D64MAXRINGSZ / sizeof (dma64dd_t)) 
    19435 + 
    19436 +/* transmit channel control */ 
    19437 +#define        D64_XC_XE               0x00000001      /* transmit enable */ 
    19438 +#define        D64_XC_SE               0x00000002      /* transmit suspend request */ 
    19439 +#define        D64_XC_LE               0x00000004      /* loopback enable */ 
    19440 +#define        D64_XC_FL               0x00000010      /* flush request */ 
    19441 +#define        D64_XC_AE               0x00030000      /* address extension bits */ 
    19442 +#define        D64_XC_AE_SHIFT         16 
    19443 + 
    19444 +/* transmit descriptor table pointer */ 
    19445 +#define        D64_XP_LD_MASK          0x00000fff      /* last valid descriptor */ 
    19446 + 
    19447 +/* transmit channel status */ 
    19448 +#define        D64_XS0_CD_MASK         0x00001fff      /* current descriptor pointer */ 
    19449 +#define        D64_XS0_XS_MASK         0xf0000000      /* transmit state */ 
    19450 +#define        D64_XS0_XS_SHIFT                28 
    19451 +#define        D64_XS0_XS_DISABLED     0x00000000      /* disabled */ 
    19452 +#define        D64_XS0_XS_ACTIVE       0x10000000      /* active */ 
    19453 +#define        D64_XS0_XS_IDLE         0x20000000      /* idle wait */ 
    19454 +#define        D64_XS0_XS_STOPPED      0x30000000      /* stopped */ 
    19455 +#define        D64_XS0_XS_SUSP         0x40000000      /* suspend pending */ 
    19456 + 
    19457 +#define        D64_XS1_AD_MASK         0x0001ffff      /* active descriptor */ 
    19458 +#define        D64_XS1_XE_MASK         0xf0000000      /* transmit errors */ 
    19459 +#define        D64_XS1_XE_SHIFT                28 
    19460 +#define        D64_XS1_XE_NOERR        0x00000000      /* no error */ 
    19461 +#define        D64_XS1_XE_DPE          0x10000000      /* descriptor protocol error */ 
    19462 +#define        D64_XS1_XE_DFU          0x20000000      /* data fifo underrun */ 
    19463 +#define        D64_XS1_XE_DTE          0x30000000      /* data transfer error */ 
    19464 +#define        D64_XS1_XE_DESRE        0x40000000      /* descriptor read error */ 
    19465 +#define        D64_XS1_XE_COREE        0x50000000      /* core error */ 
    19466 + 
    19467 +/* receive channel control */ 
    19468 +#define        D64_RC_RE               0x00000001      /* receive enable */ 
    19469 +#define        D64_RC_RO_MASK          0x000000fe      /* receive frame offset */ 
    19470 +#define        D64_RC_RO_SHIFT         1 
    19471 +#define        D64_RC_FM               0x00000100      /* direct fifo receive (pio) mode */ 
    19472 +#define        D64_RC_AE               0x00030000      /* address extension bits */ 
    19473 +#define        D64_RC_AE_SHIFT         16 
    19474 + 
    19475 +/* receive descriptor table pointer */ 
    19476 +#define        D64_RP_LD_MASK          0x00000fff      /* last valid descriptor */ 
    19477 + 
    19478 +/* receive channel status */ 
    19479 +#define        D64_RS0_CD_MASK         0x00001fff      /* current descriptor pointer */ 
    19480 +#define        D64_RS0_RS_MASK         0xf0000000      /* receive state */ 
    19481 +#define        D64_RS0_RS_SHIFT                28 
    19482 +#define        D64_RS0_RS_DISABLED     0x00000000      /* disabled */ 
    19483 +#define        D64_RS0_RS_ACTIVE       0x10000000      /* active */ 
    19484 +#define        D64_RS0_RS_IDLE         0x20000000      /* idle wait */ 
    19485 +#define        D64_RS0_RS_STOPPED      0x30000000      /* stopped */ 
    19486 +#define        D64_RS0_RS_SUSP         0x40000000      /* suspend pending */ 
    19487 + 
    19488 +#define        D64_RS1_AD_MASK         0x0001ffff      /* active descriptor */ 
    19489 +#define        D64_RS1_RE_MASK         0xf0000000      /* receive errors */ 
    19490 +#define        D64_RS1_RE_SHIFT                28 
    19491 +#define        D64_RS1_RE_NOERR        0x00000000      /* no error */ 
    19492 +#define        D64_RS1_RE_DPO          0x10000000      /* descriptor protocol error */ 
    19493 +#define        D64_RS1_RE_DFU          0x20000000      /* data fifo overflow */ 
    19494 +#define        D64_RS1_RE_DTE          0x30000000      /* data transfer error */ 
    19495 +#define        D64_RS1_RE_DESRE        0x40000000      /* descriptor read error */ 
    19496 +#define        D64_RS1_RE_COREE        0x50000000      /* core error */ 
    19497 + 
    19498 +/* fifoaddr */ 
    19499 +#define        D64_FA_OFF_MASK         0xffff          /* offset */ 
    19500 +#define        D64_FA_SEL_MASK         0xf0000         /* select */ 
    19501 +#define        D64_FA_SEL_SHIFT        16 
    19502 +#define        D64_FA_SEL_XDD          0x00000         /* transmit dma data */ 
    19503 +#define        D64_FA_SEL_XDP          0x10000         /* transmit dma pointers */ 
    19504 +#define        D64_FA_SEL_RDD          0x40000         /* receive dma data */ 
    19505 +#define        D64_FA_SEL_RDP          0x50000         /* receive dma pointers */ 
    19506 +#define        D64_FA_SEL_XFD          0x80000         /* transmit fifo data */ 
    19507 +#define        D64_FA_SEL_XFP          0x90000         /* transmit fifo pointers */ 
    19508 +#define        D64_FA_SEL_RFD          0xc0000         /* receive fifo data */ 
    19509 +#define        D64_FA_SEL_RFP          0xd0000         /* receive fifo pointers */ 
    19510 +#define        D64_FA_SEL_RSD          0xe0000         /* receive frame status data */ 
    19511 +#define        D64_FA_SEL_RSP          0xf0000         /* receive frame status pointers */ 
    19512 + 
    19513 +/* descriptor control flags 1 */ 
    19514 +#define        D64_CTRL1_EOT           ((uint32)1 << 28)       /* end of descriptor table */ 
    19515 +#define        D64_CTRL1_IOC           ((uint32)1 << 29)       /* interrupt on completion */ 
    19516 +#define        D64_CTRL1_EOF           ((uint32)1 << 30)       /* end of frame */ 
    19517 +#define        D64_CTRL1_SOF           ((uint32)1 << 31)       /* start of frame */ 
    19518 + 
    19519 +/* descriptor control flags 2 */ 
    19520 +#define        D64_CTRL2_BC_MASK       0x00007fff      /* buffer byte count mask */ 
    19521 +#define        D64_CTRL2_AE            0x00030000      /* address extension bits */ 
    19522 +#define        D64_CTRL2_AE_SHIFT      16 
    19523 + 
    19524 +/* control flags in the range [27:20] are core-specific and not defined here */ 
    19525 +#define        D64_CTRL_CORE_MASK      0x0ff00000 
    19526 + 
    19527 + 
    19528 +#endif /* _sbhnddma_h_ */ 
    1952916279diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in 
    1953016280--- linux.old/drivers/parport/Config.in 2006-04-27 18:04:38.000000000 +0200 
Note: See TracChangeset for help on using the changeset viewer.