Changeset 10137


Ignore:
Timestamp:
2008-01-06T20:28:07+01:00 (10 years ago)
Author:
nbd
Message:

update brcm-2.4 to 2.4.35.4, integrate new broadcom system code, update broadcom-wl to a contributed version (v4.150.10.5) - no bcm57xx support yet, will follow shortly

Location:
trunk
Files:
25 added
7 deleted
132 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/include/kernel-version.mk

    r9799 r10137  
    22 
    33ifeq ($(KERNEL),2.4) 
    4   LINUX_VERSION?=2.4.34 
     4  LINUX_VERSION?=2.4.35.4 
    55else 
    66  LINUX_VERSION?=2.6.21.5 
     
    1010ifeq ($(LINUX_VERSION),2.4.34) 
    1111  LINUX_KERNEL_MD5SUM:=f59665540a7f3351ea416a0dad104b55 
     12endif 
     13ifeq ($(LINUX_VERSION),2.4.35.4) 
     14  LINUX_KERNEL_MD5SUM:=34066faff3d8c042df1c7600b08b8070 
    1215endif 
    1316ifeq ($(LINUX_VERSION),2.6.22.4) 
  • trunk/package/broadcom-wl/Makefile

    r10095 r10137  
    1111 
    1212PKG_NAME:=broadcom-wl 
    13 PKG_VERSION:=4.80.53.0 
     13PKG_VERSION:=4.150.10.5 
    1414PKG_RELEASE:=1 
    1515WLC_VERSION:=0.1 
     
    1717PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 
    1818PKG_SOURCE_URL:=http://downloads.openwrt.org/sources 
    19 PKG_MD5SUM:=a7d8dde3ce474c361143b83e1d9890b1 
     19PKG_MD5SUM:=0c6ba9687114c6b598e8019e262d9a60 
     20 
     21WL_WEXT=1 
    2022 
    2123include $(INCLUDE_DIR)/package.mk 
     
    108110$(call Package/broadcom-wl/Default) 
    109111  TITLE:=Proprietary Broadcom wl driver config utility 
    110   DEPENDS+=+brcm-compat-ldso 
     112#  DEPENDS+=+brcm-compat-ldso 
    111113endef 
    112114 
     
    119121$(call Package/broadcom-wl/Default) 
    120122  DEPENDS+= +nvram 
    121   DEPENDS+= +brcm-compat-ldso 
     123#  DEPENDS+= +brcm-compat-ldso 
    122124  TITLE:=Proprietary Broadcom WPA/WPA2 authenticator 
    123125endef 
     
    126128 This package contains the proprietary WPA/WPA2 authenticator (nas) for the  
    127129 proprietary Broadcom wl driver. 
    128 endef 
    129  
    130  
    131 define install_template 
    132         $(INSTALL_DIR) $(1)/lib/modules/$(LINUX_VERSION) 
    133         $(INSTALL_DATA) $(PKG_BUILD_DIR)/driver/wl$(2).o.patch $(1)/lib/modules/$(LINUX_VERSION)/ 
    134 endef 
    135  
    136 define KernelPackage/brcm-wl/install 
    137         $(call install_template,$(1),) 
    138 endef 
    139  
    140 define KernelPackage/brcm-wl_mimo/install 
    141         $(call install_template,$(1),_mimo) 
    142130endef 
    143131 
     
    150138define Build/Prepare 
    151139        $(call Build/Prepare/Default) 
    152         mv $(PKG_BUILD_DIR)/kmod $(PKG_BUILD_DIR)/driver 
    153140        $(CP) src/* $(PKG_BUILD_DIR)/ 
    154141endef 
     
    165152        $(MAKE_KMOD) \ 
    166153                SUBDIRS="$(PKG_BUILD_DIR)/wlcompat" \ 
     154                $(if $(WL_WEXT),WL_WEXT=1) \ 
    167155                modules 
    168156        $(MAKE_KMOD) \ 
    169157                SUBDIRS="$(PKG_BUILD_DIR)/wlcompat" \ 
    170158                DEBUG=1 \ 
     159                $(if $(WL_WEXT),WL_WEXT=1) \ 
    171160                modules 
    172161 
     
    176165                CFLAGS="$(TARGET_CFLAGS)" \ 
    177166                all 
    178         $(NO_TRACE_MAKE) -C compat-ldso -f build.mk PKG_INSTALL_DIR="$(PKG_BUILD_DIR)" BUILD_DIR="$(PKG_BUILD_DIR)" 
    179         $(SED) 's,ld-uClibc.so.0,ld-uClibc.brcm,' \ 
    180                 $(PKG_BUILD_DIR)/wl \ 
    181                 $(PKG_BUILD_DIR)/nas 
     167        $(TARGET_CC) -o $(PKG_BUILD_DIR)/nas $(PKG_BUILD_DIR)/nas_exe.o -L$(STAGING_DIR)/usr/lib -lnvram 
     168        $(TARGET_CC) -o $(PKG_BUILD_DIR)/wl $(PKG_BUILD_DIR)/wl_exe.o 
     169#       $(NO_TRACE_MAKE) -C compat-ldso -f build.mk PKG_INSTALL_DIR="$(PKG_BUILD_DIR)" 
     170#       $(SED) 's,ld-uClibc.so.0,ld-uClibc.brcm,' \ 
     171#               $(PKG_BUILD_DIR)/wl \ 
     172#               $(PKG_BUILD_DIR)/nas 
    182173endef 
    183174 
     
    199190 
    200191define Package/nas/install 
    201         $(INSTALL_DIR) $(1)/usr/lib 
    202         $(INSTALL_BIN) $(PKG_BUILD_DIR)/libbcmcrypto.so $(1)/usr/lib/ 
    203192        $(INSTALL_DIR) $(1)/usr/sbin 
    204193        $(INSTALL_BIN) $(PKG_BUILD_DIR)/nas $(1)/usr/sbin/ 
     
    209198$(eval $(call KernelPackage,brcm-wl)) 
    210199$(eval $(call KernelPackage,brcm-wl-mimo)) 
    211 $(eval $(call BuildPackage,brcm-compat-ldso)) 
     200#$(eval $(call BuildPackage,brcm-compat-ldso)) 
    212201$(eval $(call KernelPackage,wlcompat)) 
    213202$(eval $(call KernelPackage,wlcompat-debug)) 
  • trunk/package/broadcom-wl/files/lib/wifi/broadcom.sh

    r10113 r10137  
    5353                1*) 
    5454                        ap=0 
    55                         mssid=0 
     55                        mssid= 
    5656                        infra=0 
    5757                ;; 
     
    6363                        wet=1 
    6464                        ap=0 
    65                         mssid=0 
     65                        mssid= 
    6666                ;; 
    6767                ::) 
     
    159159                                                        [ -n "$k" ] || continue 
    160160                                                        [ "$defkey" = "$knr" ] && def="=" || def="" 
    161                                                         append vif_pre_up "wepkey $def$knr,$k" "$N" 
     161                                                        append vif_do_up "wepkey $def$knr,$k" "$N" 
    162162                                                done 
    163163                                        ;; 
    164164                                        "");; 
    165                                         *) append vif_pre_up "wepkey =1,$key" "$N";; 
     165                                        *) append vif_do_up "wepkey =1,$key" "$N";; 
    166166                                esac 
    167167                        ;; 
     
    192192                        ;; 
    193193                esac 
    194                 append vif_post_up "wsec $wsec" "$N" 
    195                 append vif_post_up "wpa_auth $auth" "$N" 
    196                 append vif_post_up "wsec_restrict $wsec_r" "$N" 
    197                 append vif_post_up "eap_restrict $eap_r" "$N" 
     194                append vif_do_up "wsec $wsec" "$N" 
     195                append vif_do_up "wpa_auth $auth" "$N" 
     196                append vif_do_up "wsec_restrict $wsec_r" "$N" 
     197                append vif_do_up "eap_restrict $eap_r" "$N" 
    198198                 
    199199                config_get ssid "$vif" ssid 
    200200                append vif_post_up "vlan_mode 0" "$N" 
    201201                append vif_post_up "ssid $ssid" "$N" 
    202                 case "$mode" in 
    203                         sta|adhoc) append vif_do_up "ssid $ssid" "$N";; 
    204                 esac 
     202                append vif_do_up "ssid $ssid" "$N" 
    205203                 
    206204                append vif_post_up "enabled 1" "$N" 
     
    222220                                nas_mode="-S" 
    223221                                [ -z "$bridge" ] || { 
    224                                         append vif_pre_up "supplicant 1" "$N" 
    225                                         append vif_pre_up "passphrase $key" "$N" 
     222                                        append vif_post_up "supplicant 1" "$N" 
     223                                        append vif_post_up "passphrase $key" "$N" 
    226224                                         
    227225                                        use_nas=0 
     
    237235 
    238236ap $ap 
    239 mssid $mssid 
     237${mssid:+mssid $mssid} 
    240238apsta $apsta 
    241239infra $infra 
  • trunk/package/broadcom-wl/src/driver/Makefile

    r9528 r10137  
    2424        perl -ne 's,eth%d,wl%d\x00,g,print' < $< > $@ 
    2525 
    26 wl$(MOD_NAME).o.patch: wl$(MOD_NAME).o 
    27         $(OBJDUMP) -d $< | perl patchtable.pl > $@ 
    28  
    29 modules: wl$(MOD_NAME).o.patch 
     26modules: wl$(MOD_NAME).o 
    3027 
    3128include $(TOPDIR)/Rules.make 
  • trunk/package/broadcom-wl/src/driver/bcmutils.c

    r9528 r10137  
    11/* 
    2  * Misc useful OS-independent routines. 
     2 * Driver O/S-independent utility routines 
    33 * 
    4  * Copyright 2006, Broadcom Corporation 
     4 * Copyright 2007, Broadcom Corporation 
    55 * All Rights Reserved. 
    66 *  
     
    99 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    1010 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    11  * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ 
     11 * $Id$ 
    1212 */ 
    1313 
     
    1515#include <bcmdefs.h> 
    1616#include <stdarg.h> 
     17#include "bcmutils.h" 
    1718#include <osl.h> 
    18 #include "linux_osl.h" 
    19 #include "pktq.h" 
    20 #include <bcmutils.h> 
    2119#include <sbutils.h> 
    2220#include <bcmnvram.h> 
    2321#include <bcmendian.h> 
    2422#include <bcmdevs.h> 
    25 #include "bcmip.h" 
    26  
    27 #define ETHER_TYPE_8021Q       0x8100 
    28 #define ETHER_TYPE_IP          0x0800 
    29 #define VLAN_PRI_SHIFT             13 
    30 #define VLAN_PRI_MASK               7 
    31  
    32  
    33 struct  ether_header { 
    34         uint8   ether_dhost[6]; 
    35         uint8   ether_shost[6]; 
    36         uint16  ether_type; 
    37 } __attribute__((packed)); 
    38  
    39  
    40 struct ethervlan_header { 
    41         uint8   ether_dhost[6]; 
    42         uint8   ether_shost[6]; 
    43         uint16  vlan_type;              /* 0x8100 */ 
    44         uint16  vlan_tag;               /* priority, cfi and vid */ 
    45         uint16  ether_type; 
    46 }; 
     23#include "proto/ethernet.h" 
     24#include "proto/vlan.h" 
     25#include "proto/bcmip.h" 
     26#include "proto/bcmtcp.h" 
     27#include "proto/802.1d.h" 
     28 
     29#ifdef BCMPERFSTATS 
     30#include <bcmperf.h> 
     31#endif 
     32 
     33#if 0 
     34/* nvram vars cache */ 
     35static char *nvram_vars = NULL; 
     36static int vars_len = -1; 
     37#endif 
    4738 
    4839/* copy a pkt buffer chain into a buffer */ 
    4940uint 
    50 pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) 
    51 { 
    52         uint n, ret = 0; 
    53  
    54         if (len < 0) 
    55                 len = 4096;     /* "infinite" */ 
    56  
    57         /* skip 'offset' bytes */ 
    58         for (; p && offset; p = PKTNEXT(osh, p)) { 
    59                 if (offset < (uint)PKTLEN(osh, p)) 
    60                         break; 
    61                 offset -= PKTLEN(osh, p); 
    62         } 
    63  
    64         if (!p) 
    65                 return 0; 
    66  
    67         /* copy the data */ 
    68         for (; p && len; p = PKTNEXT(osh, p)) { 
    69                 n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); 
    70                 bcopy(PKTDATA(osh, p) + offset, buf, n); 
    71                 buf += n; 
    72                 len -= n; 
    73                 ret += n; 
    74                 offset = 0; 
    75         } 
    76  
    77         return ret; 
     41pktcopy (osl_t * osh, void *p, uint offset, int len, uchar * buf) 
     42{ 
     43  uint n, ret = 0; 
     44 
     45  if (len < 0) 
     46    len = 4096;                 /* "infinite" */ 
     47 
     48  /* skip 'offset' bytes */ 
     49  for (; p && offset; p = PKTNEXT (osh, p)) 
     50    { 
     51      if (offset < (uint) PKTLEN (osh, p)) 
     52        break; 
     53      offset -= PKTLEN (osh, p); 
     54    } 
     55 
     56  if (!p) 
     57    return 0; 
     58 
     59  /* copy the data */ 
     60  for (; p && len; p = PKTNEXT (osh, p)) 
     61    { 
     62      n = MIN ((uint) PKTLEN (osh, p) - offset, (uint) len); 
     63      bcopy (PKTDATA (osh, p) + offset, buf, n); 
     64      buf += n; 
     65      len -= n; 
     66      ret += n; 
     67      offset = 0; 
     68    } 
     69 
     70  return ret; 
    7871} 
    7972 
    8073/* return total length of buffer chain */ 
    8174uint 
    82 pkttotlen(osl_t *osh, void *p) 
    83 { 
    84         uint total; 
    85  
    86         total = 0; 
    87         for (; p; p = PKTNEXT(osh, p)) 
    88                 total += PKTLEN(osh, p); 
    89         return (total); 
     75pkttotlen (osl_t * osh, void *p) 
     76{ 
     77  uint total; 
     78 
     79  total = 0; 
     80  for (; p; p = PKTNEXT (osh, p)) 
     81    total += PKTLEN (osh, p); 
     82  return (total); 
    9083} 
    9184 
    9285/* return the last buffer of chained pkt */ 
    9386void * 
    94 pktlast(osl_t *osh, void *p) 
    95 { 
    96         for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) 
    97                 ; 
    98  
    99         return (p); 
     87pktlast (osl_t * osh, void *p) 
     88{ 
     89  for (; PKTNEXT (osh, p); p = PKTNEXT (osh, p)) 
     90    ; 
     91 
     92  return (p); 
    10093} 
    10194 
     
    10396/* 
    10497 * osl multiple-precedence packet queue 
    105  * hi_prec is always >= the number of the highest non-empty queue 
     98 * hi_prec is always >= the number of the highest non-empty precedence 
    10699 */ 
    107100void * 
    108 pktq_penq(struct pktq *pq, int prec, void *p) 
    109 { 
    110         struct pktq_prec *q; 
    111  
    112         ASSERT(prec >= 0 && prec < pq->num_prec); 
    113         ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */ 
    114  
    115         ASSERT(!pktq_full(pq)); 
    116         ASSERT(!pktq_pfull(pq, prec)); 
    117  
    118         q = &pq->q[prec]; 
    119  
    120         if (q->head) 
    121                 PKTSETLINK(q->tail, p); 
    122         else 
    123                 q->head = p; 
    124  
     101pktq_penq (struct pktq *pq, int prec, void *p) 
     102{ 
     103  struct pktq_prec *q; 
     104 
     105  ASSERT (prec >= 0 && prec < pq->num_prec); 
     106  ASSERT (PKTLINK (p) == NULL); /* queueing chains not allowed */ 
     107 
     108  ASSERT (!pktq_full (pq)); 
     109  ASSERT (!pktq_pfull (pq, prec)); 
     110 
     111  q = &pq->q[prec]; 
     112 
     113  if (q->head) 
     114    PKTSETLINK (q->tail, p); 
     115  else 
     116    q->head = p; 
     117 
     118  q->tail = p; 
     119  q->len++; 
     120 
     121  pq->len++; 
     122 
     123  if (pq->hi_prec < prec) 
     124    pq->hi_prec = (uint8) prec; 
     125 
     126  return p; 
     127} 
     128 
     129void * 
     130pktq_penq_head (struct pktq *pq, int prec, void *p) 
     131{ 
     132  struct pktq_prec *q; 
     133 
     134  ASSERT (prec >= 0 && prec < pq->num_prec); 
     135  ASSERT (PKTLINK (p) == NULL); /* queueing chains not allowed */ 
     136 
     137  ASSERT (!pktq_full (pq)); 
     138  ASSERT (!pktq_pfull (pq, prec)); 
     139 
     140  q = &pq->q[prec]; 
     141 
     142  if (q->head == NULL) 
     143    q->tail = p; 
     144 
     145  PKTSETLINK (p, q->head); 
     146  q->head = p; 
     147  q->len++; 
     148 
     149  pq->len++; 
     150 
     151  if (pq->hi_prec < prec) 
     152    pq->hi_prec = (uint8) prec; 
     153 
     154  return p; 
     155} 
     156 
     157void * 
     158pktq_pdeq (struct pktq *pq, int prec) 
     159{ 
     160  struct pktq_prec *q; 
     161  void *p; 
     162 
     163  ASSERT (prec >= 0 && prec < pq->num_prec); 
     164 
     165  q = &pq->q[prec]; 
     166 
     167  if ((p = q->head) == NULL) 
     168    return NULL; 
     169 
     170  if ((q->head = PKTLINK (p)) == NULL) 
     171    q->tail = NULL; 
     172 
     173  q->len--; 
     174 
     175  pq->len--; 
     176 
     177  PKTSETLINK (p, NULL); 
     178 
     179  return p; 
     180} 
     181 
     182void * 
     183pktq_pdeq_tail (struct pktq *pq, int prec) 
     184{ 
     185  struct pktq_prec *q; 
     186  void *p, *prev; 
     187 
     188  ASSERT (prec >= 0 && prec < pq->num_prec); 
     189 
     190  q = &pq->q[prec]; 
     191 
     192  if ((p = q->head) == NULL) 
     193    return NULL; 
     194 
     195  for (prev = NULL; p != q->tail; p = PKTLINK (p)) 
     196    prev = p; 
     197 
     198  if (prev) 
     199    PKTSETLINK (prev, NULL); 
     200  else 
     201    q->head = NULL; 
     202 
     203  q->tail = prev; 
     204  q->len--; 
     205 
     206  pq->len--; 
     207 
     208  return p; 
     209} 
     210 
     211void 
     212pktq_pflush (osl_t * osh, struct pktq *pq, int prec, bool dir) 
     213{ 
     214  struct pktq_prec *q; 
     215  void *p; 
     216 
     217  q = &pq->q[prec]; 
     218  p = q->head; 
     219  while (p) 
     220    { 
     221      q->head = PKTLINK (p); 
     222      PKTSETLINK (p, NULL); 
     223      PKTFREE (osh, p, dir); 
     224      q->len--; 
     225      pq->len--; 
     226      p = q->head; 
     227    } 
     228  ASSERT (q->len == 0); 
     229  q->tail = NULL; 
     230} 
     231 
     232#if 0 
     233bool 
     234pktq_pdel (struct pktq *pq, void *pktbuf, int prec) 
     235{ 
     236  struct pktq_prec *q; 
     237  void *p; 
     238 
     239  ASSERT (prec >= 0 && prec < pq->num_prec); 
     240 
     241  if (!pktbuf) 
     242    return FALSE; 
     243 
     244  q = &pq->q[prec]; 
     245 
     246  if (q->head == pktbuf) 
     247    { 
     248      if ((q->head = PKTLINK (pktbuf)) == NULL) 
     249        q->tail = NULL; 
     250    } 
     251  else 
     252    { 
     253      for (p = q->head; p && PKTLINK (p) != pktbuf; p = PKTLINK (p)) 
     254        ; 
     255      if (p == NULL) 
     256        return FALSE; 
     257 
     258      PKTSETLINK (p, PKTLINK (pktbuf)); 
     259      if (q->tail == pktbuf) 
    125260        q->tail = p; 
    126         q->len++; 
    127  
    128         pq->len++; 
    129  
    130         if (pq->hi_prec < prec) 
    131                 pq->hi_prec = (uint8)prec; 
    132  
    133         return p; 
     261    } 
     262 
     263  q->len--; 
     264  pq->len--; 
     265  PKTSETLINK (pktbuf, NULL); 
     266  return TRUE; 
     267} 
     268#endif 
     269 
     270void 
     271pktq_init (struct pktq *pq, int num_prec, int max_len) 
     272{ 
     273  int prec; 
     274 
     275  ASSERT (num_prec > 0 && num_prec <= PKTQ_MAX_PREC); 
     276 
     277  /* pq is variable size; only zero out what's requested */ 
     278  bzero (pq, 
     279         OFFSETOF (struct pktq, q) + (sizeof (struct pktq_prec) * num_prec)); 
     280 
     281  pq->num_prec = (uint16) num_prec; 
     282 
     283  pq->max = (uint16) max_len; 
     284 
     285  for (prec = 0; prec < num_prec; prec++) 
     286    pq->q[prec].max = pq->max; 
     287} 
     288 
     289int 
     290pktq_setmax (struct pktq *pq, int max_len) 
     291{ 
     292  int prec; 
     293 
     294  if (!max_len) 
     295    return pq->max; 
     296 
     297  pq->max = (uint16) max_len; 
     298  for (prec = 0; prec < pq->num_prec; prec++) 
     299    pq->q[prec].max = pq->max; 
     300 
     301  return pq->max; 
    134302} 
    135303 
    136304void * 
    137 pktq_penq_head(struct pktq *pq, int prec, void *p) 
    138 { 
    139         struct pktq_prec *q; 
    140  
    141         ASSERT(prec >= 0 && prec < pq->num_prec); 
    142         ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */ 
    143  
    144         ASSERT(!pktq_full(pq)); 
    145         ASSERT(!pktq_pfull(pq, prec)); 
    146  
    147         q = &pq->q[prec]; 
    148  
    149         if (q->head == NULL) 
    150                 q->tail = p; 
    151  
    152         PKTSETLINK(p, q->head); 
    153         q->head = p; 
    154         q->len++; 
    155  
    156         pq->len++; 
    157  
    158         if (pq->hi_prec < prec) 
    159                 pq->hi_prec = (uint8)prec; 
    160  
    161         return p; 
     305pktq_deq (struct pktq *pq, int *prec_out) 
     306{ 
     307  struct pktq_prec *q; 
     308  void *p; 
     309  int prec; 
     310 
     311  if (pq->len == 0) 
     312    return NULL; 
     313 
     314  while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
     315    pq->hi_prec--; 
     316 
     317  q = &pq->q[prec]; 
     318 
     319  if ((p = q->head) == NULL) 
     320    return NULL; 
     321 
     322  if ((q->head = PKTLINK (p)) == NULL) 
     323    q->tail = NULL; 
     324 
     325  q->len--; 
     326 
     327  pq->len--; 
     328 
     329  if (prec_out) 
     330    *prec_out = prec; 
     331 
     332  PKTSETLINK (p, NULL); 
     333 
     334  return p; 
    162335} 
    163336 
    164337void * 
    165 pktq_pdeq(struct pktq *pq, int prec) 
    166 { 
    167         struct pktq_prec *q; 
    168         void *p; 
    169  
    170         ASSERT(prec >= 0 && prec < pq->num_prec); 
    171  
    172         q = &pq->q[prec]; 
    173  
    174         if ((p = q->head) == NULL) 
    175                 return NULL; 
    176  
    177         if ((q->head = PKTLINK(p)) == NULL) 
    178                 q->tail = NULL; 
    179  
    180         q->len--; 
    181  
    182         pq->len--; 
    183  
    184         PKTSETLINK(p, NULL); 
    185  
    186         return p; 
    187 } 
    188  
     338pktq_deq_tail (struct pktq *pq, int *prec_out) 
     339{ 
     340  struct pktq_prec *q; 
     341  void *p, *prev; 
     342  int prec; 
     343 
     344  if (pq->len == 0) 
     345    return NULL; 
     346 
     347  for (prec = 0; prec < pq->hi_prec; prec++) 
     348    if (pq->q[prec].head) 
     349      break; 
     350 
     351  q = &pq->q[prec]; 
     352 
     353  if ((p = q->head) == NULL) 
     354    return NULL; 
     355 
     356  for (prev = NULL; p != q->tail; p = PKTLINK (p)) 
     357    prev = p; 
     358 
     359  if (prev) 
     360    PKTSETLINK (prev, NULL); 
     361  else 
     362    q->head = NULL; 
     363 
     364  q->tail = prev; 
     365  q->len--; 
     366 
     367  pq->len--; 
     368 
     369  if (prec_out) 
     370    *prec_out = prec; 
     371 
     372  PKTSETLINK (p, NULL); 
     373 
     374  return p; 
     375} 
     376 
     377#if 0 
    189378void * 
    190 pktq_pdeq_tail(struct pktq *pq, int prec) 
    191 { 
    192         struct pktq_prec *q; 
    193         void *p, *prev; 
    194  
    195         ASSERT(prec >= 0 && prec < pq->num_prec); 
    196  
    197         q = &pq->q[prec]; 
    198  
    199         if ((p = q->head) == NULL) 
    200                 return NULL; 
    201  
    202         for (prev = NULL; p != q->tail; p = PKTLINK(p)) 
    203                 prev = p; 
    204  
    205         if (prev) 
    206                 PKTSETLINK(prev, NULL); 
    207         else 
    208                 q->head = NULL; 
    209  
    210         q->tail = prev; 
    211         q->len--; 
    212  
    213         pq->len--; 
    214  
    215         return p; 
     379pktq_peek (struct pktq *pq, int *prec_out) 
     380{ 
     381  int prec; 
     382 
     383  if (pq->len == 0) 
     384    return NULL; 
     385 
     386  while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
     387    pq->hi_prec--; 
     388 
     389  if (prec_out) 
     390    *prec_out = prec; 
     391 
     392  return (pq->q[prec].head); 
     393} 
     394#endif 
     395 
     396void * 
     397pktq_peek_tail (struct pktq *pq, int *prec_out) 
     398{ 
     399  int prec; 
     400 
     401  if (pq->len == 0) 
     402    return NULL; 
     403 
     404  for (prec = 0; prec < pq->hi_prec; prec++) 
     405    if (pq->q[prec].head) 
     406      break; 
     407 
     408  if (prec_out) 
     409    *prec_out = prec; 
     410 
     411  return (pq->q[prec].tail); 
    216412} 
    217413 
    218414void 
    219 pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) 
    220 { 
    221         struct pktq_prec *q; 
    222         void *p; 
    223  
    224         q = &pq->q[prec]; 
    225         p = q->head; 
    226         while (p) { 
    227                 q->head = PKTLINK(p); 
    228                 PKTSETLINK(p, NULL); 
    229                 PKTFREE(osh, p, dir); 
    230                 q->len--; 
    231                 pq->len--; 
    232                 p = q->head; 
    233         } 
    234         ASSERT(q->len == 0); 
    235         q->tail = NULL; 
    236 } 
    237  
    238 bool 
    239 pktq_pdel(struct pktq *pq, void *pktbuf, int prec) 
    240 { 
    241         struct pktq_prec *q; 
    242         void *p; 
    243  
    244         ASSERT(prec >= 0 && prec < pq->num_prec); 
    245  
    246         if (!pktbuf) 
    247                 return FALSE; 
    248  
    249         q = &pq->q[prec]; 
    250  
    251         if (q->head == pktbuf) { 
    252                 if ((q->head = PKTLINK(pktbuf)) == NULL) 
    253                         q->tail = NULL; 
    254         } else { 
    255                 for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) 
    256                         ; 
    257                 if (p == NULL) 
    258                         return FALSE; 
    259  
    260                 PKTSETLINK(p, PKTLINK(pktbuf)); 
    261                 if (q->tail == pktbuf) 
    262                         q->tail = p; 
    263         } 
    264  
    265         q->len--; 
    266         pq->len--; 
    267         PKTSETLINK(pktbuf, NULL); 
    268         return TRUE; 
    269 } 
    270  
    271 void 
    272 pktq_init(struct pktq *pq, int num_prec, int max_len) 
    273 { 
    274         int prec; 
    275  
    276         ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); 
    277  
    278         bzero(pq, sizeof(*pq)); 
    279  
    280         pq->num_prec = (uint16)num_prec; 
    281  
    282         pq->max = (uint16)max_len; 
    283  
    284         for (prec = 0; prec < num_prec; prec++) 
    285                 pq->q[prec].max = pq->max; 
    286 } 
    287  
    288 void * 
    289 pktq_deq(struct pktq *pq, int *prec_out) 
    290 { 
    291         struct pktq_prec *q; 
    292         void *p; 
    293         int prec; 
    294  
    295         if (pq->len == 0) 
    296                 return NULL; 
    297  
    298         while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    299                 pq->hi_prec--; 
    300  
    301         q = &pq->q[prec]; 
    302  
    303         if ((p = q->head) == NULL) 
    304                 return NULL; 
    305  
    306         if ((q->head = PKTLINK(p)) == NULL) 
    307                 q->tail = NULL; 
    308  
    309         q->len--; 
    310  
    311         pq->len--; 
    312  
    313         if (prec_out) 
    314                 *prec_out = prec; 
    315  
    316         PKTSETLINK(p, NULL); 
    317  
    318         return p; 
    319 } 
    320  
    321 void * 
    322 pktq_deq_tail(struct pktq *pq, int *prec_out) 
    323 { 
    324         struct pktq_prec *q; 
    325         void *p, *prev; 
    326         int prec; 
    327  
    328         if (pq->len == 0) 
    329                 return NULL; 
    330  
    331         for (prec = 0; prec < pq->hi_prec; prec++) 
    332                 if (pq->q[prec].head) 
    333                         break; 
    334  
    335         q = &pq->q[prec]; 
    336  
    337         if ((p = q->head) == NULL) 
    338                 return NULL; 
    339  
    340         for (prev = NULL; p != q->tail; p = PKTLINK(p)) 
    341                 prev = p; 
    342  
    343         if (prev) 
    344                 PKTSETLINK(prev, NULL); 
    345         else 
    346                 q->head = NULL; 
    347  
    348         q->tail = prev; 
    349         q->len--; 
    350  
    351         pq->len--; 
    352  
    353         if (prec_out) 
    354                 *prec_out = prec; 
    355  
    356         PKTSETLINK(p, NULL); 
    357  
    358         return p; 
    359 } 
    360  
    361 void * 
    362 pktq_peek(struct pktq *pq, int *prec_out) 
    363 { 
    364         int prec; 
    365  
    366         if (pq->len == 0) 
    367                 return NULL; 
    368  
    369         while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    370                 pq->hi_prec--; 
    371  
    372         if (prec_out) 
    373                 *prec_out = prec; 
    374  
    375         return (pq->q[prec].head); 
    376 } 
    377  
    378 void * 
    379 pktq_peek_tail(struct pktq *pq, int *prec_out) 
    380 { 
    381         int prec; 
    382  
    383         if (pq->len == 0) 
    384                 return NULL; 
    385  
    386         for (prec = 0; prec < pq->hi_prec; prec++) 
    387                 if (pq->q[prec].head) 
    388                         break; 
    389  
    390         if (prec_out) 
    391                 *prec_out = prec; 
    392  
    393         return (pq->q[prec].tail); 
    394 } 
    395  
    396 void 
    397 pktq_flush(osl_t *osh, struct pktq *pq, bool dir) 
    398 { 
    399         int prec; 
    400         for (prec = 0; prec < pq->num_prec; prec++) 
    401                 pktq_pflush(osh, pq, prec, dir); 
    402         ASSERT(pq->len == 0); 
     415pktq_flush (osl_t * osh, struct pktq *pq, bool dir) 
     416{ 
     417  int prec; 
     418  for (prec = 0; prec < pq->num_prec; prec++) 
     419    pktq_pflush (osh, pq, prec, dir); 
     420  ASSERT (pq->len == 0); 
    403421} 
    404422 
    405423/* Return sum of lengths of a specific set of precedences */ 
    406424int 
    407 pktq_mlen(struct pktq *pq, uint prec_bmp) 
    408 { 
    409         int prec, len; 
    410  
    411         len = 0; 
    412  
    413         for (prec = 0; prec <= pq->hi_prec; prec++) 
    414                 if (prec_bmp & (1 << prec)) 
    415                         len += pq->q[prec].len; 
    416  
    417         return len; 
     425pktq_mlen (struct pktq *pq, uint prec_bmp) 
     426{ 
     427  int prec, len; 
     428 
     429  len = 0; 
     430 
     431  for (prec = 0; prec <= pq->hi_prec; prec++) 
     432    if (prec_bmp & (1 << prec)) 
     433      len += pq->q[prec].len; 
     434 
     435  return len; 
    418436} 
    419437 
    420438/* Priority dequeue from a specific set of precedences */ 
    421439void * 
    422 pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) 
    423 { 
    424         struct pktq_prec *q; 
    425         void *p; 
    426         int prec; 
    427  
    428         if (pq->len == 0) 
    429                 return NULL; 
    430  
    431         while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
    432                 pq->hi_prec--; 
    433  
    434         while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) 
    435                 if (prec-- == 0) 
    436                         return NULL; 
    437  
    438         q = &pq->q[prec]; 
    439  
    440         if ((p = q->head) == NULL) 
    441                 return NULL; 
    442  
    443         if ((q->head = PKTLINK(p)) == NULL) 
    444                 q->tail = NULL; 
    445  
    446         q->len--; 
    447  
    448         if (prec_out) 
    449                 *prec_out = prec; 
    450  
    451         pq->len--; 
    452  
    453         PKTSETLINK(p, NULL); 
    454  
    455         return p; 
    456 } 
    457  
    458 char* 
    459 bcmstrcat(char *dest, const char *src) 
    460 { 
    461         strcpy(&dest[strlen(dest)], src); 
    462         return (dest); 
    463 } 
    464  
    465 char* 
    466 bcm_ether_ntoa(struct ether_addr *ea, char *buf) 
    467 { 
    468         sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", 
    469                 ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, 
    470                 ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); 
    471         return (buf); 
    472 } 
     440pktq_mdeq (struct pktq *pq, uint prec_bmp, int *prec_out) 
     441{ 
     442  struct pktq_prec *q; 
     443  void *p; 
     444  int prec; 
     445 
     446  if (pq->len == 0) 
     447    return NULL; 
     448 
     449  while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 
     450    pq->hi_prec--; 
     451 
     452  while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) 
     453    if (prec-- == 0) 
     454      return NULL; 
     455 
     456  q = &pq->q[prec]; 
     457 
     458  if ((p = q->head) == NULL) 
     459    return NULL; 
     460 
     461  if ((q->head = PKTLINK (p)) == NULL) 
     462    q->tail = NULL; 
     463 
     464  q->len--; 
     465 
     466  if (prec_out) 
     467    *prec_out = prec; 
     468 
     469  pq->len--; 
     470 
     471  PKTSETLINK (p, NULL); 
     472 
     473  return p; 
     474} 
     475 
     476const unsigned char bcm_ctype[] = { 
     477  _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C,       /* 0-7 */ 
     478  _BCM_C, _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C | _BCM_S, 
     479    _BCM_C | _BCM_S, _BCM_C, 
     480  _BCM_C,                       /* 8-15 */ 
     481  _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C,       /* 16-23 */ 
     482  _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C,       /* 24-31 */ 
     483  _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,     /* 32-39 */ 
     484  _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,       /* 40-47 */ 
     485  _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D,       /* 48-55 */ 
     486  _BCM_D, _BCM_D, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,       /* 56-63 */ 
     487  _BCM_P, _BCM_U | _BCM_X, _BCM_U | _BCM_X, _BCM_U | _BCM_X, _BCM_U | _BCM_X, 
     488    _BCM_U | _BCM_X, 
     489  _BCM_U | _BCM_X, _BCM_U,      /* 64-71 */ 
     490  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,       /* 72-79 */ 
     491  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,       /* 80-87 */ 
     492  _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,       /* 88-95 */ 
     493  _BCM_P, _BCM_L | _BCM_X, _BCM_L | _BCM_X, _BCM_L | _BCM_X, _BCM_L | _BCM_X, 
     494    _BCM_L | _BCM_X, 
     495  _BCM_L | _BCM_X, _BCM_L,      /* 96-103 */ 
     496  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,       /* 104-111 */ 
     497  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,       /* 112-119 */ 
     498  _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_C,       /* 120-127 */ 
     499  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* 128-143 */ 
     500  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* 144-159 */ 
     501  _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, 
     502    _BCM_P, _BCM_P, 
     503  _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,       /* 160-175 */ 
     504  _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, 
     505    _BCM_P, _BCM_P, 
     506  _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,       /* 176-191 */ 
     507  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, 
     508    _BCM_U, _BCM_U, 
     509  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,       /* 192-207 */ 
     510  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, 
     511    _BCM_U, _BCM_U, 
     512  _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L,       /* 208-223 */ 
     513  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, 
     514    _BCM_L, _BCM_L, 
     515  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,       /* 224-239 */ 
     516  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, 
     517    _BCM_L, _BCM_L, 
     518  _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L        /* 240-255 */ 
     519}; 
     520 
     521ulong BCMROMFN (bcm_strtoul) (char *cp, char **endp, uint base) 
     522{ 
     523  ulong result, value; 
     524  bool minus; 
     525 
     526  minus = FALSE; 
     527 
     528  while (bcm_isspace (*cp)) 
     529    cp++; 
     530 
     531  if (cp[0] == '+') 
     532    cp++; 
     533  else if (cp[0] == '-') 
     534    { 
     535      minus = TRUE; 
     536      cp++; 
     537    } 
     538 
     539  if (base == 0) 
     540    { 
     541      if (cp[0] == '0') 
     542        { 
     543          if ((cp[1] == 'x') || (cp[1] == 'X')) 
     544            { 
     545              base = 16; 
     546              cp = &cp[2]; 
     547            } 
     548          else 
     549            { 
     550              base = 8; 
     551              cp = &cp[1]; 
     552            } 
     553        } 
     554      else 
     555        base = 10; 
     556    } 
     557  else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) 
     558    { 
     559      cp = &cp[2]; 
     560    } 
     561 
     562  result = 0; 
     563 
     564  while (bcm_isxdigit (*cp) && 
     565         (value = 
     566          bcm_isdigit (*cp) ? *cp - '0' : bcm_toupper (*cp) - 'A' + 10) < 
     567         base) 
     568    { 
     569      result = result * base + value; 
     570      cp++; 
     571    } 
     572 
     573  if (minus) 
     574    result = (ulong) (result * -1); 
     575 
     576  if (endp) 
     577    *endp = (char *) cp; 
     578 
     579  return (result); 
     580} 
     581 
     582#if 0 
     583int BCMROMFN (bcm_atoi) (char *s) 
     584{ 
     585  return (int) bcm_strtoul (s, NULL, 10); 
     586} 
     587 
     588/* return pointer to location of substring 'needle' in 'haystack' */ 
     589char *BCMROMFN (bcmstrstr) (char *haystack, char *needle) 
     590{ 
     591  int len, nlen; 
     592  int i; 
     593 
     594  if ((haystack == NULL) || (needle == NULL)) 
     595    return (haystack); 
     596 
     597  nlen = strlen (needle); 
     598  len = strlen (haystack) - nlen + 1; 
     599 
     600  for (i = 0; i < len; i++) 
     601    if (memcmp (needle, &haystack[i], nlen) == 0) 
     602      return (&haystack[i]); 
     603  return (NULL); 
     604} 
     605 
     606char *BCMROMFN (bcmstrcat) (char *dest, const char *src) 
     607{ 
     608  strcpy (&dest[strlen (dest)], src); 
     609  return (dest); 
     610} 
     611 
     612char *BCMROMFN (bcmstrncat) (char *dest, const char *src, uint size) 
     613{ 
     614  char *endp; 
     615  char *p; 
     616 
     617  p = dest + strlen (dest); 
     618  endp = p + size; 
     619 
     620  while (p != endp && (*p++ = *src++) != '\0') 
     621    ; 
     622 
     623  return (dest); 
     624} 
     625#endif 
    473626 
    474627/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ 
     628int BCMROMFN (bcm_ether_atoe) (char *p, struct ether_addr * ea) 
     629{ 
     630  int i = 0; 
     631 
     632  for (;;) 
     633    { 
     634      ea->octet[i++] = (char) bcm_strtoul (p, &p, 16); 
     635      if (!*p++ || i == 6) 
     636        break; 
     637    } 
     638 
     639  return (i == 6); 
     640} 
     641 
     642#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) 
     643/* registry routine buffer preparation utility functions: 
     644 * parameter order is like strncpy, but returns count 
     645 * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) 
     646 */ 
     647ulong 
     648wchar2ascii (char *abuf, ushort * wbuf, ushort wbuflen, ulong abuflen) 
     649{ 
     650  ulong copyct = 1; 
     651  ushort i; 
     652 
     653  if (abuflen == 0) 
     654    return 0; 
     655 
     656  /* wbuflen is in bytes */ 
     657  wbuflen /= sizeof (ushort); 
     658 
     659  for (i = 0; i < wbuflen; ++i) 
     660    { 
     661      if (--abuflen == 0) 
     662        break; 
     663      *abuf++ = (char) *wbuf++; 
     664      ++copyct; 
     665    } 
     666  *abuf = '\0'; 
     667 
     668  return copyct; 
     669} 
     670#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ 
     671 
     672#if 0 
     673char * 
     674bcm_ether_ntoa (struct ether_addr *ea, char *buf) 
     675{ 
     676  snprintf (buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x", 
     677            ea->octet[0] & 0xff, ea->octet[1] & 0xff, ea->octet[2] & 0xff, 
     678            ea->octet[3] & 0xff, ea->octet[4] & 0xff, ea->octet[5] & 0xff); 
     679  return (buf); 
     680} 
     681 
     682char * 
     683bcm_ip_ntoa (struct ipv4_addr *ia, char *buf) 
     684{ 
     685  snprintf (buf, 16, "%d.%d.%d.%d", 
     686            ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); 
     687  return (buf); 
     688} 
     689void 
     690bcm_mdelay (uint ms) 
     691{ 
     692  uint i; 
     693 
     694  for (i = 0; i < ms; i++) 
     695    { 
     696      OSL_DELAY (1000); 
     697    } 
     698} 
     699#endif 
     700 
     701#if 0 
     702 
     703/* 
     704 * Search the name=value vars for a specific one and return its value. 
     705 * Returns NULL if not found. 
     706 */ 
     707char * 
     708getvar (char *vars, const char *name) 
     709{ 
     710#ifdef  _MINOSL_ 
     711  return NULL; 
     712#else 
     713  char *s; 
     714  int len; 
     715 
     716  if (!name) 
     717    return NULL; 
     718 
     719  len = strlen (name); 
     720  if (len == 0) 
     721    return NULL; 
     722 
     723  /* first look in vars[] */ 
     724  for (s = vars; s && *s;) 
     725    { 
     726      /* CSTYLED */ 
     727      if ((bcmp (s, name, len) == 0) && (s[len] == '=')) 
     728        return (&s[len + 1]); 
     729 
     730      while (*s++) 
     731        ; 
     732    } 
     733 
     734  /* then query nvram */ 
     735  return (nvram_get (name)); 
     736#endif /* _MINOSL_ */ 
     737} 
     738 
     739/* 
     740 * Search the vars for a specific one and return its value as 
     741 * an integer. Returns 0 if not found. 
     742 */ 
    475743int 
    476 bcm_ether_atoe(char *p, struct ether_addr *ea) 
    477 { 
    478         int i = 0; 
    479  
    480         for (;;) { 
    481                 ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); 
    482                 if (!*p++ || i == 6) 
    483                         break; 
     744getintvar (char *vars, const char *name) 
     745{ 
     746#ifdef  _MINOSL_ 
     747  return 0; 
     748#else 
     749  char *val; 
     750 
     751  if ((val = getvar (vars, name)) == NULL) 
     752    return (0); 
     753 
     754  return (bcm_strtoul (val, NULL, 0)); 
     755#endif /* _MINOSL_ */ 
     756} 
     757 
     758 
     759/* Search for token in comma separated token-string */ 
     760static int 
     761findmatch (char *string, char *name) 
     762{ 
     763  uint len; 
     764  char *c; 
     765 
     766  len = strlen (name); 
     767  /* CSTYLED */ 
     768  while ((c = strchr (string, ',')) != NULL) 
     769    { 
     770      if (len == (uint) (c - string) && !strncmp (string, name, len)) 
     771        return 1; 
     772      string = c + 1; 
     773    } 
     774 
     775  return (!strcmp (string, name)); 
     776} 
     777 
     778/* Return gpio pin number assigned to the named pin 
     779 * 
     780 * Variable should be in format: 
     781 * 
     782 *      gpio<N>=pin_name,pin_name 
     783 * 
     784 * This format allows multiple features to share the gpio with mutual 
     785 * understanding. 
     786 * 
     787 * 'def_pin' is returned if a specific gpio is not defined for the requested functionality 
     788 * and if def_pin is not used by others. 
     789 */ 
     790uint 
     791getgpiopin (char *vars, char *pin_name, uint def_pin) 
     792{ 
     793  char name[] = "gpioXXXX"; 
     794  char *val; 
     795  uint pin; 
     796 
     797  /* Go thru all possibilities till a match in pin name */ 
     798  for (pin = 0; pin < GPIO_NUMPINS; pin++) 
     799    { 
     800      snprintf (name, sizeof (name), "gpio%d", pin); 
     801      val = getvar (vars, name); 
     802      if (val && findmatch (val, pin_name)) 
     803        return pin; 
     804    } 
     805 
     806  if (def_pin != GPIO_PIN_NOTDEFINED) 
     807    { 
     808      /* make sure the default pin is not used by someone else */ 
     809      snprintf (name, sizeof (name), "gpio%d", def_pin); 
     810      if (getvar (vars, name)) 
     811        { 
     812          def_pin = GPIO_PIN_NOTDEFINED; 
    484813        } 
    485  
    486         return (i == 6); 
    487 } 
    488  
    489 /* Takes an Ethernet frame and sets out-of-bound PKTPRIO 
    490  * Also updates the inplace vlan tag if requested 
     814    } 
     815 
     816  return def_pin; 
     817} 
     818#endif 
     819 
     820#ifdef BCMPERFSTATS 
     821 
     822#define LOGSIZE 256             /* should be power of 2 to avoid div below */ 
     823static struct 
     824{ 
     825  uint cycles; 
     826  char *fmt; 
     827  uint a1; 
     828  uint a2; 
     829} logtab[LOGSIZE]; 
     830 
     831/* last entry logged  */ 
     832static uint logi = 0; 
     833/* next entry to read */ 
     834static uint readi = 0; 
     835 
     836void 
     837bcm_perf_enable () 
     838{ 
     839  BCMPERF_ENABLE_INSTRCOUNT (); 
     840  BCMPERF_ENABLE_ICACHE_MISS (); 
     841  BCMPERF_ENABLE_ICACHE_HIT (); 
     842} 
     843 
     844void 
     845bcmlog (char *fmt, uint a1, uint a2) 
     846{ 
     847  static uint last = 0; 
     848  uint cycles, i; 
     849  OSL_GETCYCLES (cycles); 
     850 
     851  i = logi; 
     852 
     853  logtab[i].cycles = cycles - last; 
     854  logtab[i].fmt = fmt; 
     855  logtab[i].a1 = a1; 
     856  logtab[i].a2 = a2; 
     857 
     858  logi = (i + 1) % LOGSIZE; 
     859  last = cycles; 
     860} 
     861 
     862 
     863void 
     864bcmstats (char *fmt) 
     865{ 
     866  static uint last = 0; 
     867  static uint32 ic_miss = 0; 
     868  static uint32 instr_count = 0; 
     869  uint32 ic_miss_cur; 
     870  uint32 instr_count_cur; 
     871  uint cycles, i; 
     872 
     873  OSL_GETCYCLES (cycles); 
     874  BCMPERF_GETICACHE_MISS (ic_miss_cur); 
     875  BCMPERF_GETINSTRCOUNT (instr_count_cur); 
     876 
     877  i = logi; 
     878 
     879  logtab[i].cycles = cycles - last; 
     880  logtab[i].a1 = ic_miss_cur - ic_miss; 
     881  logtab[i].a2 = instr_count_cur - instr_count; 
     882  logtab[i].fmt = fmt; 
     883 
     884  logi = (i + 1) % LOGSIZE; 
     885 
     886  last = cycles; 
     887  instr_count = instr_count_cur; 
     888  ic_miss = ic_miss_cur; 
     889} 
     890 
     891 
     892void 
     893bcmdumplog (char *buf, int size) 
     894{ 
     895  char *limit, *line; 
     896  int j = 0; 
     897  int num; 
     898 
     899  limit = buf + size - 80; 
     900  *buf = '\0'; 
     901 
     902  num = logi - readi; 
     903 
     904  if (num < 0) 
     905    num += LOGSIZE; 
     906 
     907  /* print in chronological order */ 
     908 
     909  for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++) 
     910    { 
     911      if (logtab[readi].fmt == NULL) 
     912        continue; 
     913      line = buf; 
     914      buf += sprintf (buf, "%d\t", logtab[readi].cycles); 
     915      buf += 
     916        sprintf (buf, logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2); 
     917      buf += sprintf (buf, "\n"); 
     918    } 
     919 
     920} 
     921 
     922 
     923/* 
     924 * Dump one log entry at a time. 
     925 * Return index of next entry or -1 when no more . 
    491926 */ 
     927int 
     928bcmdumplogent (char *buf, uint i) 
     929{ 
     930  bool hit; 
     931 
     932  /* 
     933   * If buf is NULL, return the starting index, 
     934   * interpreting i as the indicator of last 'i' entries to dump. 
     935   */ 
     936  if (buf == NULL) 
     937    { 
     938      i = ((i > 0) && (i < (LOGSIZE - 1))) ? i : (LOGSIZE - 1); 
     939      return ((logi - i) % LOGSIZE); 
     940    } 
     941 
     942  *buf = '\0'; 
     943 
     944  ASSERT (i < LOGSIZE); 
     945 
     946  if (i == logi) 
     947    return (-1); 
     948 
     949  hit = FALSE; 
     950  for (; (i != logi) && !hit; i = (i + 1) % LOGSIZE) 
     951    { 
     952      if (logtab[i].fmt == NULL) 
     953        continue; 
     954      buf += sprintf (buf, "%d: %d\t", i, logtab[i].cycles); 
     955      buf += sprintf (buf, logtab[i].fmt, logtab[i].a1, logtab[i].a2); 
     956      buf += sprintf (buf, "\n"); 
     957      hit = TRUE; 
     958    } 
     959 
     960  return (i); 
     961} 
     962 
     963#endif /* BCMPERFSTATS */ 
     964 
     965#ifdef BCMDBG 
     966/* pretty hex print a pkt buffer chain */ 
    492967void 
    493 pktsetprio(void *pkt, bool update_vtag) 
    494 { 
    495         struct ether_header *eh; 
    496         struct ethervlan_header *evh; 
    497         uint8 *pktdata; 
    498         int priority = 0; 
    499  
    500         pktdata = (uint8 *) PKTDATA(NULL, pkt); 
    501         ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); 
    502  
    503         eh = (struct ether_header *) pktdata; 
    504  
    505         if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { 
    506                 uint16 vlan_tag; 
    507                 int vlan_prio, dscp_prio = 0; 
    508  
    509                 evh = (struct ethervlan_header *)eh; 
    510  
    511                 vlan_tag = ntoh16(evh->vlan_tag); 
    512                 vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; 
    513  
    514                 if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { 
    515                         uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); 
    516                         uint8 tos_tc = IP_TOS(ip_body); 
    517                         dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); 
     968prpkt (const char *msg, osl_t * osh, void *p0) 
     969{ 
     970  void *p; 
     971 
     972  if (msg && (msg[0] != '\0')) 
     973    printf ("%s:\n", msg); 
     974 
     975  for (p = p0; p; p = PKTNEXT (osh, p)) 
     976    prhex (NULL, PKTDATA (osh, p), PKTLEN (osh, p)); 
     977} 
     978#endif /* BCMDBG */ 
     979 
     980/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. 
     981 * Also updates the inplace vlan tag if requested. 
     982 * For debugging, it returns an indication of what it did. 
     983 */ 
     984uint 
     985pktsetprio (void *pkt, bool update_vtag) 
     986{ 
     987  struct ether_header *eh; 
     988  struct ethervlan_header *evh; 
     989  uint8 *pktdata; 
     990  int priority = 0; 
     991  int rc = 0; 
     992 
     993  pktdata = (uint8 *) PKTDATA (NULL, pkt); 
     994  ASSERT (ISALIGNED ((uintptr) pktdata, sizeof (uint16))); 
     995 
     996  eh = (struct ether_header *) pktdata; 
     997 
     998  if (ntoh16 (eh->ether_type) == ETHER_TYPE_8021Q) 
     999    { 
     1000      uint16 vlan_tag; 
     1001      int vlan_prio, dscp_prio = 0; 
     1002 
     1003      evh = (struct ethervlan_header *) eh; 
     1004 
     1005      vlan_tag = ntoh16 (evh->vlan_tag); 
     1006      vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; 
     1007 
     1008      if (ntoh16 (evh->ether_type) == ETHER_TYPE_IP) 
     1009        { 
     1010          uint8 *ip_body = pktdata + sizeof (struct ethervlan_header); 
     1011          uint8 tos_tc = IP_TOS (ip_body); 
     1012          dscp_prio = (int) (tos_tc >> IPV4_TOS_PREC_SHIFT); 
     1013          if ((IP_VER (ip_body) == IP_VER_4) 
     1014              && (IPV4_PROT (ip_body) == IP_PROT_TCP)) 
     1015            { 
     1016              int ip_len; 
     1017              int src_port; 
     1018              bool src_port_exc; 
     1019              uint8 *tcp_hdr; 
     1020 
     1021              ip_len = IPV4_PAYLOAD_LEN (ip_body); 
     1022              tcp_hdr = IPV4_NO_OPTIONS_PAYLOAD (ip_body); 
     1023              src_port = TCP_SRC_PORT (tcp_hdr); 
     1024              src_port_exc = (src_port == 10110) || (src_port == 10120) || 
     1025                (src_port == 10130) || (src_port == 10140); 
     1026 
     1027              if ((ip_len == 40) && src_port_exc && TCP_IS_ACK (tcp_hdr)) 
     1028                { 
     1029                  dscp_prio = 7; 
    5181030                } 
    519  
    520                 /* DSCP priority gets precedence over 802.1P (vlan tag) */ 
    521                 priority = (dscp_prio != 0) ? dscp_prio : vlan_prio; 
    522  
    523                 /*  
    524                  * If the DSCP priority is not the same as the VLAN priority, 
    525                  * then overwrite the priority field in the vlan tag, with the 
    526                  * DSCP priority value. This is required for Linux APs because 
    527                  * the VLAN driver on Linux, overwrites the skb->priority field 
    528                  * with the priority value in the vlan tag 
    529                  */ 
    530                 if (update_vtag && (priority != vlan_prio)) { 
    531                         vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); 
    532                         vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; 
    533                         evh->vlan_tag = hton16(vlan_tag); 
    534                 } 
    535         } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { 
    536                 uint8 *ip_body = pktdata + sizeof(struct ether_header); 
    537                 uint8 tos_tc = IP_TOS(ip_body); 
    538                 priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); 
     1031            } 
    5391032        } 
    5401033 
    541         ASSERT(priority >= 0 && priority <= MAXPRIO); 
    542         PKTSETPRIO(pkt, priority); 
     1034      /* DSCP priority gets precedence over 802.1P (vlan tag) */ 
     1035      if (dscp_prio != 0) 
     1036        { 
     1037          priority = dscp_prio; 
     1038          rc |= PKTPRIO_VDSCP; 
     1039        } 
     1040      else 
     1041        { 
     1042          priority = vlan_prio; 
     1043          rc |= PKTPRIO_VLAN; 
     1044        } 
     1045      /*  
     1046       * If the DSCP priority is not the same as the VLAN priority, 
     1047       * then overwrite the priority field in the vlan tag, with the 
     1048       * DSCP priority value. This is required for Linux APs because 
     1049       * the VLAN driver on Linux, overwrites the skb->priority field 
     1050       * with the priority value in the vlan tag 
     1051       */ 
     1052      if (update_vtag && (priority != vlan_prio)) 
     1053        { 
     1054          vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); 
     1055          vlan_tag |= (uint16) priority << VLAN_PRI_SHIFT; 
     1056          evh->vlan_tag = hton16 (vlan_tag); 
     1057          rc |= PKTPRIO_UPD; 
     1058        } 
     1059    } 
     1060  else if (ntoh16 (eh->ether_type) == ETHER_TYPE_IP) 
     1061    { 
     1062      uint8 *ip_body = pktdata + sizeof (struct ether_header); 
     1063      uint8 tos_tc = IP_TOS (ip_body); 
     1064      priority = (int) (tos_tc >> IPV4_TOS_PREC_SHIFT); 
     1065      rc |= PKTPRIO_DSCP; 
     1066      if ((IP_VER (ip_body) == IP_VER_4) 
     1067          && (IPV4_PROT (ip_body) == IP_PROT_TCP)) 
     1068        { 
     1069          int ip_len; 
     1070          int src_port; 
     1071          bool src_port_exc; 
     1072          uint8 *tcp_hdr; 
     1073 
     1074          ip_len = IPV4_PAYLOAD_LEN (ip_body); 
     1075          tcp_hdr = IPV4_NO_OPTIONS_PAYLOAD (ip_body); 
     1076          src_port = TCP_SRC_PORT (tcp_hdr); 
     1077          src_port_exc = (src_port == 10110) || (src_port == 10120) || 
     1078            (src_port == 10130) || (src_port == 10140); 
     1079 
     1080          if ((ip_len == 40) && src_port_exc && TCP_IS_ACK (tcp_hdr)) 
     1081            { 
     1082              priority = 7; 
     1083            } 
     1084        } 
     1085    } 
     1086 
     1087  ASSERT (priority >= 0 && priority <= MAXPRIO); 
     1088  PKTSETPRIO (pkt, priority); 
     1089  return (rc | priority); 
    5431090} 
    5441091 
     
    5471094static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; 
    5481095 
    549 /* Convert the Error codes into related Error strings  */ 
     1096/* Convert the error codes into related error strings  */ 
    5501097const char * 
    551 bcmerrorstr(int bcmerror) 
    552 { 
    553         int abs_bcmerror; 
    554  
    555         abs_bcmerror = ABS(bcmerror); 
    556  
    557         /* check if someone added a bcmerror code but forgot to add errorstring */ 
    558         ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); 
    559         if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { 
    560                 sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); 
    561                 return bcm_undeferrstr; 
     1098bcmerrorstr (int bcmerror) 
     1099{ 
     1100  /* check if someone added a bcmerror code but forgot to add errorstring */ 
     1101  ASSERT (ABS (BCME_LAST) == (ARRAYSIZE (bcmerrorstrtable) - 1)); 
     1102 
     1103  if (bcmerror > 0 || bcmerror < BCME_LAST) 
     1104    { 
     1105      snprintf (bcm_undeferrstr, BCME_STRLEN, "Undefined error %d", bcmerror); 
     1106      return bcm_undeferrstr; 
     1107    } 
     1108 
     1109  ASSERT (strlen (bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); 
     1110 
     1111  return bcmerrorstrtable[-bcmerror]; 
     1112} 
     1113 
     1114#if 0 
     1115static void BCMINITFN (bcm_nvram_refresh) (char *flash) 
     1116{ 
     1117  int i; 
     1118  int ret = 0; 
     1119 
     1120  ASSERT (flash); 
     1121 
     1122  /* default "empty" vars cache */ 
     1123  bzero (flash, 2); 
     1124 
     1125  if ((ret = nvram_getall (flash, NVRAM_SPACE))) 
     1126    return; 
     1127 
     1128  /* determine nvram length */ 
     1129  for (i = 0; i < NVRAM_SPACE; i++) 
     1130    { 
     1131      if (flash[i] == '\0' && flash[i + 1] == '\0') 
     1132        break; 
     1133    } 
     1134 
     1135  if (i > 1) 
     1136    vars_len = i + 2; 
     1137  else 
     1138    vars_len = 0; 
     1139} 
     1140#endif 
     1141 
     1142#ifdef BCMDBG_PKT               /* pkt logging for debugging */ 
     1143/* Add a packet to the pktlist */ 
     1144void 
     1145pktlist_add (pktlist_info_t * pktlist, void *pkt) 
     1146{ 
     1147  uint i; 
     1148  ASSERT (pktlist->count < PKTLIST_SIZE); 
     1149 
     1150  /* Verify the packet is not already part of the list */ 
     1151  for (i = 0; i < pktlist->count; i++) 
     1152    { 
     1153      if (pktlist->list[i] == pkt) 
     1154        ASSERT (0); 
     1155    } 
     1156  pktlist->list[pktlist->count] = pkt; 
     1157  pktlist->count++; 
     1158  return; 
     1159} 
     1160 
     1161/* Remove a packet from the pktlist */ 
     1162void 
     1163pktlist_remove (pktlist_info_t * pktlist, void *pkt) 
     1164{ 
     1165  uint i; 
     1166  uint num = pktlist->count; 
     1167 
     1168  /* find the index where pkt exists */ 
     1169  for (i = 0; i < num; i++) 
     1170    { 
     1171      /* check for the existence of pkt in the list */ 
     1172      if (pktlist->list[i] == pkt) 
     1173        { 
     1174          /* replace with the last element */ 
     1175          pktlist->list[i] = pktlist->list[num - 1]; 
     1176          pktlist->count--; 
     1177          return; 
    5621178        } 
    563  
    564         ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); 
    565  
    566         return bcmerrorstrtable[abs_bcmerror]; 
    567 } 
    568  
     1179    } 
     1180  ASSERT (0); 
     1181} 
     1182 
     1183/* Dump the pktlist (and the contents of each packet if 'data' 
     1184 * is set). 'buf' should be large enough 
     1185 */ 
     1186 
     1187char * 
     1188pktlist_dump (pktlist_info_t * pktlist, char *buf) 
     1189{ 
     1190  char *obuf; 
     1191  uint i; 
     1192 
     1193  obuf = buf; 
     1194 
     1195  buf += sprintf (buf, "Packet list dump:\n"); 
     1196 
     1197  for (i = 0; i < (pktlist->count); i++) 
     1198    { 
     1199      buf += sprintf (buf, "0x%p\t", pktlist->list[i]); 
     1200 
     1201#ifdef NOTDEF                   /* Remove this ifdef to print pkttag and pktdata */ 
     1202      if (PKTTAG (pktlist->list[i])) 
     1203        { 
     1204          /* Print pkttag */ 
     1205          buf += sprintf (buf, "Pkttag(in hex): "); 
     1206          buf += 
     1207            bcm_format_hex (buf, PKTTAG (pktlist->list[i]), OSL_PKTTAG_SZ); 
     1208        } 
     1209      buf += sprintf (buf, "Pktdata(in hex): "); 
     1210      buf += bcm_format_hex (buf, PKTDATA (NULL, pktlist->list[i]), 
     1211                             PKTLEN (NULL, pktlist->list[i])); 
     1212#endif /* NOTDEF */ 
     1213 
     1214      buf += sprintf (buf, "\n"); 
     1215    } 
     1216  return obuf; 
     1217} 
     1218#endif /* BCMDBG_PKT */ 
     1219 
     1220#if 0 
     1221/* iovar table lookup */ 
     1222const bcm_iovar_t * 
     1223bcm_iovar_lookup (const bcm_iovar_t * table, const char *name) 
     1224{ 
     1225  const bcm_iovar_t *vi; 
     1226  const char *lookup_name; 
     1227 
     1228  /* skip any ':' delimited option prefixes */ 
     1229  lookup_name = strrchr (name, ':'); 
     1230  if (lookup_name != NULL) 
     1231    lookup_name++; 
     1232  else 
     1233    lookup_name = name; 
     1234 
     1235  ASSERT (table); 
     1236 
     1237  for (vi = table; vi->name; vi++) 
     1238    { 
     1239      if (!strcmp (vi->name, lookup_name)) 
     1240        return vi; 
     1241    } 
     1242  /* ran to end of table */ 
     1243 
     1244  return NULL;                  /* var name not found */ 
     1245} 
     1246#endif 
    5691247 
    5701248int 
    571 bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) 
    572 { 
    573         int bcmerror = 0; 
    574  
    575         /* length check on io buf */ 
    576         switch (vi->type) { 
    577         case IOVT_BOOL: 
    578         case IOVT_INT8: 
    579         case IOVT_INT16: 
    580         case IOVT_INT32: 
    581         case IOVT_UINT8: 
    582         case IOVT_UINT16: 
    583         case IOVT_UINT32: 
    584                 /* all integers are int32 sized args at the ioctl interface */ 
    585                 if (len < (int)sizeof(int)) { 
    586                         bcmerror = BCME_BUFTOOSHORT; 
    587                 } 
    588                 break; 
    589  
    590         case IOVT_BUFFER: 
    591                 /* buffer must meet minimum length requirement */ 
    592                 if (len < vi->minlen) { 
    593                         bcmerror = BCME_BUFTOOSHORT; 
    594                 } 
    595                 break; 
    596  
    597         case IOVT_VOID: 
    598                 if (!set) { 
    599                         /* Cannot return nil... */ 
    600                         bcmerror = BCME_UNSUPPORTED; 
    601                 } else if (len) { 
    602                         /* Set is an action w/o parameters */ 
    603                         bcmerror = BCME_BUFTOOLONG; 
    604                 } 
    605                 break; 
    606  
    607         default: 
    608                 /* unknown type for length check in iovar info */ 
    609                 ASSERT(0); 
    610                 bcmerror = BCME_UNSUPPORTED; 
     1249bcm_iovar_lencheck (const bcm_iovar_t * vi, void *arg, int len, bool set) 
     1250{ 
     1251  int bcmerror = 0; 
     1252 
     1253  /* length check on io buf */ 
     1254  switch (vi->type) 
     1255    { 
     1256    case IOVT_BOOL: 
     1257    case IOVT_INT8: 
     1258    case IOVT_INT16: 
     1259    case IOVT_INT32: 
     1260    case IOVT_UINT8: 
     1261    case IOVT_UINT16: 
     1262    case IOVT_UINT32: 
     1263      /* all integers are int32 sized args at the ioctl interface */ 
     1264      if (len < (int) sizeof (int)) 
     1265        { 
     1266          bcmerror = BCME_BUFTOOSHORT; 
    6111267        } 
    612  
    613         return bcmerror; 
     1268      break; 
     1269 
     1270    case IOVT_BUFFER: 
     1271      /* buffer must meet minimum length requirement */ 
     1272      if (len < vi->minlen) 
     1273        { 
     1274          bcmerror = BCME_BUFTOOSHORT; 
     1275        } 
     1276      break; 
     1277 
     1278    case IOVT_VOID: 
     1279      if (!set) 
     1280        { 
     1281          /* Cannot return nil... */ 
     1282          bcmerror = BCME_UNSUPPORTED; 
     1283        } 
     1284      else if (len) 
     1285        { 
     1286          /* Set is an action w/o parameters */ 
     1287          bcmerror = BCME_BUFTOOLONG; 
     1288        } 
     1289      break; 
     1290 
     1291    default: 
     1292      /* unknown type for length check in iovar info */ 
     1293      ASSERT (0); 
     1294      bcmerror = BCME_UNSUPPORTED; 
     1295    } 
     1296 
     1297  return bcmerror; 
    6141298} 
    6151299 
    6161300#define CRC_INNER_LOOP(n, c, x) \ 
    617                     (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] 
    618  
    619 static uint32 crc32_table[256] = { 
    620     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 
    621     0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
    622     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 
    623     0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
    624     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 
    625     0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
    626     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 
    627     0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
    628     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 
    629     0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
    630     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 
    631     0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
    632     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 
    633     0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
    634     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 
    635     0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
    636     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 
    637     0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
    638     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 
    639     0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
    640     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 
    641     0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
    642     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 
    643     0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
    644     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 
    645     0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
    646     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 
    647     0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
    648     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 
    649     0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
    650     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 
    651     0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
    652     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 
    653     0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
    654     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 
    655     0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
    656     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 
    657     0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
    658     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 
    659     0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
    660     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 
    661     0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
    662     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 
    663     0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
    664     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 
    665     0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
    666     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 
    667     0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
    668     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 
    669     0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
    670     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 
    671     0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
    672     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 
    673     0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
    674     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 
    675     0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
    676     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 
    677     0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
    678     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 
    679     0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
    680     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 
    681     0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
    682     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 
    683     0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 
     1301        (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] 
     1302 
     1303#if 0 
     1304/******************************************************************************* 
     1305 * crc8 
     1306 * 
     1307 * Computes a crc8 over the input data using the polynomial: 
     1308 * 
     1309 *       x^8 + x^7 +x^6 + x^4 + x^2 + 1 
     1310 * 
     1311 * The caller provides the initial value (either CRC8_INIT_VALUE 
     1312 * or the previous returned value) to allow for processing of 
     1313 * discontiguous blocks of data.  When generating the CRC the 
     1314 * caller is responsible for complementing the final return value 
     1315 * and inserting it into the byte stream.  When checking, a final 
     1316 * return value of CRC8_GOOD_VALUE indicates a valid CRC. 
     1317 * 
     1318 * Reference: Dallas Semiconductor Application Note 27 
     1319 *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", 
     1320 *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., 
     1321 *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt 
     1322 * 
     1323 * **************************************************************************** 
     1324 */ 
     1325 
     1326static const uint8 crc8_table[256] = { 
     1327  0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, 
     1328  0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, 
     1329  0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, 
     1330  0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, 
     1331  0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, 
     1332  0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, 
     1333  0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, 
     1334  0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, 
     1335  0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, 
     1336  0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, 
     1337  0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, 
     1338  0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, 
     1339  0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, 
     1340  0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, 
     1341  0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, 
     1342  0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, 
     1343  0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, 
     1344  0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, 
     1345  0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, 
     1346  0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, 
     1347  0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, 
     1348  0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, 
     1349  0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, 
     1350  0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, 
     1351  0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, 
     1352  0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, 
     1353  0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, 
     1354  0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, 
     1355  0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, 
     1356  0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, 
     1357  0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, 
     1358  0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F 
    6841359}; 
    6851360 
    686 uint32 
    687 hndcrc32( 
    688     uint8 *pdata,  /* pointer to array of data to process */ 
    689     uint   nbytes, /* number of input data bytes to process */ 
    690     uint32 crc     /* either CRC32_INIT_VALUE or previous return value */ 
    691 ) 
    692 { 
    693         uint8 *pend; 
     1361uint8 BCMROMFN (hndcrc8) (uint8 * pdata,        /* pointer to array of data to process */ 
     1362                          uint nbytes,  /* number of input data bytes to process */ 
     1363                          uint8 crc     /* either CRC8_INIT_VALUE or previous return value */ 
     1364  ) 
     1365{ 
     1366  /* hard code the crc loop instead of using CRC_INNER_LOOP macro 
     1367   * to avoid the undefined and unnecessary (uint8 >> 8) operation. 
     1368   */ 
     1369  while (nbytes-- > 0) 
     1370    crc = crc8_table[(crc ^ *pdata++) & 0xff]; 
     1371 
     1372  return crc; 
     1373} 
     1374 
     1375/******************************************************************************* 
     1376 * crc16 
     1377 * 
     1378 * Computes a crc16 over the input data using the polynomial: 
     1379 * 
     1380 *       x^16 + x^12 +x^5 + 1 
     1381 * 
     1382 * The caller provides the initial value (either CRC16_INIT_VALUE 
     1383 * or the previous returned value) to allow for processing of 
     1384 * discontiguous blocks of data.  When generating the CRC the 
     1385 * caller is responsible for complementing the final return value 
     1386 * and inserting it into the byte stream.  When checking, a final 
     1387 * return value of CRC16_GOOD_VALUE indicates a valid CRC. 
     1388 * 
     1389 * Reference: Dallas Semiconductor Application Note 27 
     1390 *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", 
     1391 *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., 
     1392 *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt 
     1393 * 
     1394 * **************************************************************************** 
     1395 */ 
     1396static const uint16 crc16_table[256] = { 
     1397  0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 
     1398  0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 
     1399  0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, 
     1400  0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, 
     1401  0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, 
     1402  0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, 
     1403  0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, 
     1404  0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, 
     1405  0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, 
     1406  0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, 
     1407  0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, 
     1408  0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, 
     1409  0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, 
     1410  0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, 
     1411  0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, 
     1412  0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, 
     1413  0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, 
     1414  0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, 
     1415  0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, 
     1416  0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, 
     1417  0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, 
     1418  0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, 
     1419  0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, 
     1420  0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, 
     1421  0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, 
     1422  0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, 
     1423  0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, 
     1424  0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, 
     1425  0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, 
     1426  0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 
     1427  0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, 
     1428  0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 
     1429}; 
     1430 
     1431uint16 BCMROMFN (hndcrc16) (uint8 * pdata,      /* pointer to array of data to process */ 
     1432                            uint nbytes,        /* number of input data bytes to process */ 
     1433                            uint16 crc  /* either CRC16_INIT_VALUE or previous return value */ 
     1434  ) 
     1435{ 
     1436  while (nbytes-- > 0) 
     1437    CRC_INNER_LOOP (16, crc, *pdata++); 
     1438  return crc; 
     1439} 
     1440#endif 
     1441 
     1442static const uint32 crc32_table[256] = { 
     1443  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 
     1444  0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
     1445  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 
     1446  0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
     1447  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 
     1448  0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
     1449  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 
     1450  0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
     1451  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 
     1452  0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
     1453  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 
     1454  0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
     1455  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 
     1456  0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
     1457  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 
     1458  0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
     1459  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 
     1460  0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
     1461  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 
     1462  0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
     1463  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 
     1464  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
     1465  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 
     1466  0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
     1467  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 
     1468  0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
     1469  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 
     1470  0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
     1471  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 
     1472  0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
     1473  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 
     1474  0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
     1475  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 
     1476  0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
     1477  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 
     1478  0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
     1479  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 
     1480  0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
     1481  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 
     1482  0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
     1483  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 
     1484  0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
     1485  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 
     1486  0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
     1487  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 
     1488  0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
     1489  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 
     1490  0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
     1491  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 
     1492  0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
     1493  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 
     1494  0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
     1495  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 
     1496  0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
     1497  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 
     1498  0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
     1499  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 
     1500  0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
     1501  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 
     1502  0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
     1503  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 
     1504  0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
     1505  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 
     1506  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 
     1507}; 
     1508 
     1509uint32 BCMROMFN (hndcrc32) (uint8 * pdata,      /* pointer to array of data to process */ 
     1510                            uint nbytes,        /* number of input data bytes to process */ 
     1511                            uint32 crc  /* either CRC32_INIT_VALUE or previous return value */ 
     1512  ) 
     1513{ 
     1514  uint8 *pend; 
    6941515#ifdef __mips__ 
    695         uint8 tmp[4]; 
    696         ulong *tptr = (ulong *)tmp; 
    697  
    698         /* in case the beginning of the buffer isn't aligned */ 
    699         pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); 
    700         nbytes -= (pend - pdata); 
    701         while (pdata < pend) 
    702                 CRC_INNER_LOOP(32, crc, *pdata++); 
    703  
    704         /* handle bulk of data as 32-bit words */ 
    705         pend = pdata + (nbytes & 0xfffffffc); 
    706         while (pdata < pend) { 
    707                 *tptr = *(ulong *)pdata; 
    708                 pdata += sizeof(ulong *); 
    709                 CRC_INNER_LOOP(32, crc, tmp[0]); 
    710                 CRC_INNER_LOOP(32, crc, tmp[1]); 
    711                 CRC_INNER_LOOP(32, crc, tmp[2]); 
    712                 CRC_INNER_LOOP(32, crc, tmp[3]); 
     1516  uint8 tmp[4]; 
     1517  ulong *tptr = (ulong *) tmp; 
     1518 
     1519  /* in case the beginning of the buffer isn't aligned */ 
     1520  pend = (uint8 *) ((uint) (pdata + 3) & 0xfffffffc); 
     1521  nbytes -= (pend - pdata); 
     1522  while (pdata < pend) 
     1523    CRC_INNER_LOOP (32, crc, *pdata++); 
     1524 
     1525  /* handle bulk of data as 32-bit words */ 
     1526  pend = pdata + (nbytes & 0xfffffffc); 
     1527  while (pdata < pend) 
     1528    { 
     1529      *tptr = *(ulong *) pdata; 
     1530      pdata += sizeof (ulong *); 
     1531      CRC_INNER_LOOP (32, crc, tmp[0]); 
     1532      CRC_INNER_LOOP (32, crc, tmp[1]); 
     1533      CRC_INNER_LOOP (32, crc, tmp[2]); 
     1534      CRC_INNER_LOOP (32, crc, tmp[3]); 
     1535    } 
     1536 
     1537  /* 1-3 bytes at end of buffer */ 
     1538  pend = pdata + (nbytes & 0x03); 
     1539  while (pdata < pend) 
     1540    CRC_INNER_LOOP (32, crc, *pdata++); 
     1541#else 
     1542  pend = pdata + nbytes; 
     1543  while (pdata < pend) 
     1544    CRC_INNER_LOOP (32, crc, *pdata++); 
     1545#endif /* __mips__ */ 
     1546 
     1547  return crc; 
     1548} 
     1549 
     1550#ifdef notdef 
     1551#define CLEN    1499            /*  CRC Length */ 
     1552#define CBUFSIZ         (CLEN+4) 
     1553#define CNBUFS          5       /* # of bufs */ 
     1554 
     1555void 
     1556testcrc32 (void) 
     1557{ 
     1558  uint j, k, l; 
     1559  uint8 *buf; 
     1560  uint len[CNBUFS]; 
     1561  uint32 crcr; 
     1562  uint32 crc32tv[CNBUFS] = 
     1563    { 0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110 }; 
     1564 
     1565  ASSERT ((buf = MALLOC (CBUFSIZ * CNBUFS)) != NULL); 
     1566 
     1567  /* step through all possible alignments */ 
     1568  for (l = 0; l <= 4; l++) 
     1569    { 
     1570      for (j = 0; j < CNBUFS; j++) 
     1571        { 
     1572          len[j] = CLEN; 
     1573          for (k = 0; k < len[j]; k++) 
     1574            *(buf + j * CBUFSIZ + (k + l)) = (j + k) & 0xff; 
    7131575        } 
    7141576 
    715         /* 1-3 bytes at end of buffer */ 
    716         pend = pdata + (nbytes & 0x03); 
    717         while (pdata < pend) 
    718                 CRC_INNER_LOOP(32, crc, *pdata++); 
    719 #else 
    720         pend = pdata + nbytes; 
    721         while (pdata < pend) 
    722                 CRC_INNER_LOOP(32, crc, *pdata++); 
    723 #endif /* __mips__ */ 
    724  
    725         return crc; 
    726 } 
    727  
     1577      for (j = 0; j < CNBUFS; j++) 
     1578        { 
     1579          crcr = crc32 (buf + j * CBUFSIZ + l, len[j], CRC32_INIT_VALUE); 
     1580          ASSERT (crcr == crc32tv[j]); 
     1581        } 
     1582    } 
     1583 
     1584  MFREE (buf, CBUFSIZ * CNBUFS); 
     1585  return; 
     1586} 
     1587#endif /* notdef */ 
    7281588 
    7291589/* 
     
    7331593 * NULL is returned. 
    7341594 * *buflen is not modified if the TLV elt parameter is invalid, or is decremented 
    735  * by the TLV paramter's length if it is valid. 
     1595 * by the TLV parameter's length if it is valid. 
    7361596 */ 
    737 bcm_tlv_t * 
    738 bcm_next_tlv(bcm_tlv_t *elt, int *buflen) 
    739 { 
    740         int len; 
    741  
    742         /* validate current elt */ 
    743         if (!bcm_valid_tlv(elt, *buflen)) 
    744                 return NULL; 
    745  
    746         /* advance to next elt */ 
    747         len = elt->len; 
    748         elt = (bcm_tlv_t*)(elt->data + len); 
    749         *buflen -= (2 + len); 
    750  
    751         /* validate next elt */ 
    752         if (!bcm_valid_tlv(elt, *buflen)) 
    753                 return NULL; 
    754  
    755         return elt; 
     1597bcm_tlv_t *BCMROMFN (bcm_next_tlv) (bcm_tlv_t * elt, int *buflen) 
     1598{ 
     1599  int len; 
     1600 
     1601  /* validate current elt */ 
     1602  if (!bcm_valid_tlv (elt, *buflen)) 
     1603    return NULL; 
     1604 
     1605  /* advance to next elt */ 
     1606  len = elt->len; 
     1607  elt = (bcm_tlv_t *) (elt->data + len); 
     1608  *buflen -= (2 + len); 
     1609 
     1610  /* validate next elt */ 
     1611  if (!bcm_valid_tlv (elt, *buflen)) 
     1612    return NULL; 
     1613 
     1614  return elt; 
    7561615} 
    7571616 
     
    7611620 * matches tag 
    7621621 */ 
    763 bcm_tlv_t * 
    764 bcm_parse_tlvs(void *buf, int buflen, uint key) 
    765 { 
    766         bcm_tlv_t *elt; 
    767         int totlen; 
    768  
    769         elt = (bcm_tlv_t*)buf; 
    770         totlen = buflen; 
    771  
    772         /* find tagged parameter */ 
    773         while (totlen >= 2) { 
    774                 int len = elt->len; 
    775  
    776                 /* validate remaining totlen */ 
    777                 if ((elt->id == key) && (totlen >= (len + 2))) 
    778                         return (elt); 
    779  
    780                 elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); 
    781                 totlen -= (len + 2); 
    782         } 
    783  
    784         return NULL; 
    785 } 
    786  
     1622bcm_tlv_t *BCMROMFN (bcm_parse_tlvs) (void *buf, int buflen, uint key) 
     1623{ 
     1624  bcm_tlv_t *elt; 
     1625  int totlen; 
     1626 
     1627  elt = (bcm_tlv_t *) buf; 
     1628  totlen = buflen; 
     1629 
     1630  /* find tagged parameter */ 
     1631  while (totlen >= 2) 
     1632    { 
     1633      int len = elt->len; 
     1634 
     1635      /* validate remaining totlen */ 
     1636      if ((elt->id == key) && (totlen >= (len + 2))) 
     1637        return (elt); 
     1638 
     1639      elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2)); 
     1640      totlen -= (len + 2); 
     1641    } 
     1642 
     1643  return NULL; 
     1644} 
     1645 
     1646#if 0 
    7871647/* 
    7881648 * Traverse a string of 1-byte tag/1-byte length/variable-length value 
     
    7911651 * than the target key. 
    7921652 */ 
    793 bcm_tlv_t * 
    794 bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) 
    795 { 
    796         bcm_tlv_t *elt; 
    797         int totlen; 
    798  
    799         elt = (bcm_tlv_t*)buf; 
    800         totlen = buflen; 
    801  
    802         /* find tagged parameter */ 
    803         while (totlen >= 2) { 
    804                 uint id = elt->id; 
    805                 int len = elt->len; 
    806  
    807                 /* Punt if we start seeing IDs > than target key */ 
    808                 if (id > key) 
    809                         return (NULL); 
    810  
    811                 /* validate remaining totlen */ 
    812                 if ((id == key) && (totlen >= (len + 2))) 
    813                         return (elt); 
    814  
    815                 elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); 
    816                 totlen -= (len + 2); 
     1653bcm_tlv_t *BCMROMFN (bcm_parse_ordered_tlvs) (void *buf, int buflen, uint key) 
     1654{ 
     1655  bcm_tlv_t *elt; 
     1656  int totlen; 
     1657 
     1658  elt = (bcm_tlv_t *) buf; 
     1659  totlen = buflen; 
     1660 
     1661  /* find tagged parameter */ 
     1662  while (totlen >= 2) 
     1663    { 
     1664      uint id = elt->id; 
     1665      int len = elt->len; 
     1666 
     1667      /* Punt if we start seeing IDs > than target key */ 
     1668      if (id > key) 
     1669        return (NULL); 
     1670 
     1671      /* validate remaining totlen */ 
     1672      if ((id == key) && (totlen >= (len + 2))) 
     1673        return (elt); 
     1674 
     1675      elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2)); 
     1676      totlen -= (len + 2); 
     1677    } 
     1678  return NULL; 
     1679} 
     1680 
     1681#ifdef BCMDBG 
     1682int 
     1683bcm_format_flags (const bcm_bit_desc_t * bd, uint32 flags, char *buf, int len) 
     1684{ 
     1685  int i; 
     1686  char *p = buf; 
     1687  char hexstr[16]; 
     1688  int slen = 0; 
     1689  uint32 bit; 
     1690  const char *name; 
     1691 
     1692  if (len < 2 || !buf) 
     1693    return 0; 
     1694 
     1695  buf[0] = '\0'; 
     1696  len -= 1; 
     1697 
     1698  for (i = 0; flags != 0; i++) 
     1699    { 
     1700      bit = bd[i].bit; 
     1701      name = bd[i].name; 
     1702      if (bit == 0 && flags) 
     1703        { 
     1704          /* print any unnamed bits */ 
     1705          sprintf (hexstr, "0x%X", flags); 
     1706          name = hexstr; 
     1707          flags = 0;            /* exit loop */ 
    8171708        } 
    818         return NULL; 
     1709      else if ((flags & bit) == 0) 
     1710        continue; 
     1711      slen += strlen (name); 
     1712      if (len < slen) 
     1713        break; 
     1714      if (p != buf) 
     1715        p += sprintf (p, " ");  /* btwn flag space */ 
     1716      strcat (p, name); 
     1717      p += strlen (name); 
     1718      flags &= ~bit; 
     1719      len -= slen; 
     1720      slen = 1;                 /* account for btwn flag space */ 
     1721    } 
     1722 
     1723  /* indicate the str was too short */ 
     1724  if (flags != 0) 
     1725    { 
     1726      if (len == 0) 
     1727        p--;                    /* overwrite last char */ 
     1728      p += sprintf (p, ">"); 
     1729    } 
     1730 
     1731  return (int) (p - buf); 
     1732} 
     1733 
     1734void 
     1735deadbeef (void *p, uint len) 
     1736{ 
     1737  static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef }; 
     1738 
     1739  while (len-- > 0) 
     1740    { 
     1741      *(uint8 *) p = meat[((uintptr) p) & 3]; 
     1742      p = (uint8 *) p + 1; 
     1743    } 
     1744} 
     1745 
     1746/* pretty hex print a contiguous buffer */ 
     1747void 
     1748prhex (const char *msg, uchar * buf, uint nbytes) 
     1749{ 
     1750  char line[128], *p; 
     1751  uint i; 
     1752 
     1753  if (msg && (msg[0] != '\0')) 
     1754    printf ("%s:\n", msg); 
     1755 
     1756  p = line; 
     1757  for (i = 0; i < nbytes; i++) 
     1758    { 
     1759      if (i % 16 == 0) 
     1760        { 
     1761          p += sprintf (p, "  %04d: ", i);      /* line prefix */ 
     1762        } 
     1763      p += sprintf (p, "%02x ", buf[i]); 
     1764      if (i % 16 == 15) 
     1765        { 
     1766          printf ("%s\n", line);        /* flush line */ 
     1767          p = line; 
     1768        } 
     1769    } 
     1770 
     1771  /* flush last partial line */ 
     1772  if (p != line) 
     1773    printf ("%s\n", line); 
     1774} 
     1775 
     1776/* print bytes formatted as hex to a string. return the resulting string length */ 
     1777int 
     1778bcm_format_hex (char *str, const void *bytes, int len) 
     1779{ 
     1780  int i; 
     1781  char *p = str; 
     1782  const uint8 *src = (const uint8 *) bytes; 
     1783 
     1784  for (i = 0; i < len; i++) 
     1785    { 
     1786      p += sprintf (p, "%02X", *src); 
     1787      src++; 
     1788    } 
     1789  return (int) (p - str); 
     1790} 
     1791 
     1792#endif /* BCMDBG */ 
     1793 
     1794/* Produce a human-readable string for boardrev */ 
     1795char * 
     1796bcm_brev_str (uint16 brev, char *buf) 
     1797{ 
     1798  if (brev < 0x100) 
     1799    snprintf (buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); 
     1800  else 
     1801    snprintf (buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', 
     1802              brev & 0xfff); 
     1803 
     1804  return (buf); 
     1805} 
     1806 
     1807#define BUFSIZE_TODUMP_ATONCE 512       /* Buffer size */ 
     1808 
     1809/* dump large strings to console */ 
     1810void 
     1811printfbig (char *buf) 
     1812{ 
     1813  uint len, max_len; 
     1814  char c; 
     1815 
     1816  len = strlen (buf); 
     1817 
     1818  max_len = BUFSIZE_TODUMP_ATONCE; 
     1819 
     1820  while (len > max_len) 
     1821    { 
     1822      c = buf[max_len]; 
     1823      buf[max_len] = '\0'; 
     1824      printf ("%s", buf); 
     1825      buf[max_len] = c; 
     1826 
     1827      buf += max_len; 
     1828      len -= max_len; 
     1829    } 
     1830  /* print the remaining string */ 
     1831  printf ("%s\n", buf); 
     1832  return; 
     1833} 
     1834 
     1835/* routine to dump fields in a fileddesc structure */ 
     1836uint 
     1837bcmdumpfields (readreg_rtn read_rtn, void *arg0, void *arg1, 
     1838               struct fielddesc * fielddesc_array, char *buf, uint32 bufsize) 
     1839{ 
     1840  uint filled_len; 
     1841  int len; 
     1842  struct fielddesc *cur_ptr; 
     1843 
     1844  filled_len = 0; 
     1845  cur_ptr = fielddesc_array; 
     1846 
     1847  while (bufsize > 1) 
     1848    { 
     1849      if (cur_ptr->nameandfmt == NULL) 
     1850        break; 
     1851      len = snprintf (buf, bufsize, cur_ptr->nameandfmt, 
     1852                      read_rtn (arg0, arg1, cur_ptr->offset)); 
     1853      /* check for snprintf overflow or error */ 
     1854      if (len < 0 || (uint32) len >= bufsize) 
     1855        len = bufsize - 1; 
     1856      buf += len; 
     1857      bufsize -= len; 
     1858      filled_len += len; 
     1859      cur_ptr++; 
     1860    } 
     1861  return filled_len; 
     1862} 
     1863#endif 
     1864 
     1865uint 
     1866bcm_mkiovar (char *name, char *data, uint datalen, char *buf, uint buflen) 
     1867{ 
     1868  uint len; 
     1869 
     1870  len = strlen (name) + 1; 
     1871 
     1872  if ((len + datalen) > buflen) 
     1873    return 0; 
     1874 
     1875  strncpy (buf, name, buflen); 
     1876 
     1877  /* append data onto the end of the name string */ 
     1878  memcpy (&buf[len], data, datalen); 
     1879  len += datalen; 
     1880 
     1881  return len; 
     1882} 
     1883 
     1884/* Quarter dBm units to mW 
     1885 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 
     1886 * Table is offset so the last entry is largest mW value that fits in 
     1887 * a uint16. 
     1888 */ 
     1889 
     1890#define QDBM_OFFSET 153         /* Offset for first entry */ 
     1891#define QDBM_TABLE_LEN 40       /* Table size */ 
     1892 
     1893/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. 
     1894 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 
     1895 */ 
     1896#define QDBM_TABLE_LOW_BOUND 6493       /* Low bound */ 
     1897 
     1898/* Largest mW value that will round down to the last table entry, 
     1899 * QDBM_OFFSET + QDBM_TABLE_LEN-1. 
     1900 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. 
     1901 */ 
     1902#define QDBM_TABLE_HIGH_BOUND 64938     /* High bound */ 
     1903 
     1904static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { 
     1905/* qdBm:        +0      +1      +2      +3      +4      +5      +6      +7 */ 
     1906/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, 
     1907/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, 
     1908/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, 
     1909/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, 
     1910/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 
     1911}; 
     1912 
     1913uint16 BCMROMFN (bcm_qdbm_to_mw) (uint8 qdbm) 
     1914{ 
     1915  uint factor = 1; 
     1916  int idx = qdbm - QDBM_OFFSET; 
     1917 
     1918  if (idx > QDBM_TABLE_LEN) 
     1919    { 
     1920      /* clamp to max uint16 mW value */ 
     1921      return 0xFFFF; 
     1922    } 
     1923 
     1924  /* scale the qdBm index up to the range of the table 0-40 
     1925   * where an offset of 40 qdBm equals a factor of 10 mW. 
     1926   */ 
     1927  while (idx < 0) 
     1928    { 
     1929      idx += 40; 
     1930      factor *= 10; 
     1931    } 
     1932 
     1933  /* return the mW value scaled down to the correct factor of 10, 
     1934   * adding in factor/2 to get proper rounding. 
     1935   */ 
     1936  return ((nqdBm_to_mW_map[idx] + factor / 2) / factor); 
     1937} 
     1938 
     1939uint8 BCMROMFN (bcm_mw_to_qdbm) (uint16 mw) 
     1940{ 
     1941  uint8 qdbm; 
     1942  int offset; 
     1943  uint mw_uint = mw; 
     1944  uint boundary; 
     1945 
     1946  /* handle boundary case */ 
     1947  if (mw_uint <= 1) 
     1948    return 0; 
     1949 
     1950  offset = QDBM_OFFSET; 
     1951 
     1952  /* move mw into the range of the table */ 
     1953  while (mw_uint < QDBM_TABLE_LOW_BOUND) 
     1954    { 
     1955      mw_uint *= 10; 
     1956      offset -= 40; 
     1957    } 
     1958 
     1959  for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) 
     1960    { 
     1961      boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] - 
     1962                                          nqdBm_to_mW_map[qdbm]) / 2; 
     1963      if (mw_uint < boundary) 
     1964        break; 
     1965    } 
     1966 
     1967  qdbm += (uint8) offset; 
     1968 
     1969  return (qdbm); 
     1970} 
     1971 
     1972 
     1973uint BCMROMFN (bcm_bitcount) (uint8 * bitmap, uint length) 
     1974{ 
     1975  uint bitcount = 0, i; 
     1976  uint8 tmp; 
     1977  for (i = 0; i < length; i++) 
     1978    { 
     1979      tmp = bitmap[i]; 
     1980      while (tmp) 
     1981        { 
     1982          bitcount++; 
     1983          tmp &= (tmp - 1); 
     1984        } 
     1985    } 
     1986  return bitcount; 
    8191987} 
    8201988 
     
    8221990/* Initialization of bcmstrbuf structure */ 
    8231991void 
    824 bcm_binit(struct bcmstrbuf *b, char *buf, uint size) 
    825 { 
    826         b->origsize = b->size = size; 
    827         b->origbuf = b->buf = buf; 
     1992bcm_binit (struct bcmstrbuf *b, char *buf, uint size) 
     1993{ 
     1994  b->origsize = b->size = size; 
     1995  b->origbuf = b->buf = buf; 
    8281996} 
    8291997 
    8301998/* Buffer sprintf wrapper to guard against buffer overflow */ 
    8311999int 
    832 bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) 
    833 { 
    834         va_list ap; 
    835         int r; 
    836  
    837         va_start(ap, fmt); 
    838         r = vsnprintf(b->buf, b->size, fmt, ap); 
    839  
    840         /* Non Ansi C99 compliant returns -1, 
    841          * Ansi compliant return r >= b->size, 
    842          * bcmstdlib returns 0, handle all 
    843          */ 
    844         if ((r == -1) || (r >= (int)b->size) || (r == 0)) 
    845         { 
    846                 b->size = 0; 
    847         } 
    848         else 
    849         { 
    850                 b->size -= r; 
    851                 b->buf += r; 
    852         } 
    853  
    854         va_end(ap); 
    855  
    856         return r; 
    857 } 
    858  
    859 uint 
    860 bcm_bitcount(uint8 *bitmap, uint length) 
    861 {    
    862         uint bitcount = 0, i; 
    863         uint8 tmp; 
    864         for (i = 0; i < length; i++) { 
    865                 tmp = bitmap[i]; 
    866                 while (tmp) { 
    867                         bitcount++; 
    868                         tmp &= (tmp - 1); 
    869                 } 
    870         } 
    871         return bitcount; 
    872 } 
    873  
     2000bcm_bprintf (struct bcmstrbuf *b, const char *fmt, ...) 
     2001{ 
     2002  va_list ap; 
     2003  int r; 
     2004 
     2005  va_start (ap, fmt); 
     2006  r = vsnprintf (b->buf, b->size, fmt, ap); 
     2007 
     2008  /* Non Ansi C99 compliant returns -1, 
     2009   * Ansi compliant return r >= b->size, 
     2010   * bcmstdlib returns 0, handle all 
     2011   */ 
     2012  if ((r == -1) || (r >= (int) b->size) || (r == 0)) 
     2013    { 
     2014      b->size = 0; 
     2015    } 
     2016  else 
     2017    { 
     2018      b->size -= r; 
     2019      b->buf += r; 
     2020    } 
     2021 
     2022  va_end (ap); 
     2023 
     2024  return r; 
     2025} 
     2026 
     2027char * 
     2028bcm_ether_ntoa (struct ether_addr *ea, char *buf) 
     2029{ 
     2030        snprintf (buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x", 
     2031                ea->octet[0] & 0xff, ea->octet[1] & 0xff, ea->octet[2] & 0xff, 
     2032                ea->octet[3] & 0xff, ea->octet[4] & 0xff, ea->octet[5] & 0xff); 
     2033        return (buf); 
     2034} 
     2035 
  • trunk/package/broadcom-wl/src/driver/bcmutils.h

    r10136 r10137  
    22 * Misc useful os-independent macros and functions. 
    33 * 
    4  * Copyright 2006, Broadcom Corporation 
     4 * Copyright 2007, Broadcom Corporation 
    55 * All Rights Reserved. 
    66 *  
     
    99 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    1010 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    11  * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ 
     11 * $Id$ 
    1212 */ 
    1313 
    1414#ifndef _bcmutils_h_ 
    1515#define _bcmutils_h_ 
    16  
    17 /* ** driver-only section ** */ 
    18 #ifdef BCMDRIVER 
    19  
     16#include "linux_osl.h" 
     17 
     18/* ctype replacement */ 
    2019#define _BCM_U  0x01    /* upper */ 
    2120#define _BCM_L  0x02    /* lower */ 
     
    2726#define _BCM_SP 0x80    /* hard space (0x20) */ 
    2827 
    29 #define GPIO_PIN_NOTDEFINED     0x20    /* Pin not defined */ 
    30  
    31 extern unsigned char bcm_ctype[]; 
    32 #define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) 
     28extern const unsigned char bcm_ctype[]; 
     29#define bcm_ismask(x)   (bcm_ctype[(int)(unsigned char)(x)]) 
    3330 
    3431#define bcm_isalnum(c)  ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) 
     
    4340#define bcm_isupper(c)  ((bcm_ismask(c)&(_BCM_U)) != 0) 
    4441#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) 
    45  
    46 /* 
    47  * Spin at most 'us' microseconds while 'exp' is true. 
    48  * Caller should explicitly test 'exp' when this completes 
    49  * and take appropriate error action if 'exp' is still true. 
    50  */ 
    51 #define SPINWAIT(exp, us) { \ 
    52         uint countdown = (us) + 9; \ 
    53         while ((exp) && (countdown >= 10)) {\ 
    54                 OSL_DELAY(10); \ 
    55                 countdown -= 10; \ 
    56         } \ 
    57 } 
    58  
    59 struct  ether_addr { 
    60         uint8 octet[6]; 
    61 } __attribute__((packed)); 
     42#define bcm_tolower(c)  (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) 
     43#define bcm_toupper(c)  (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) 
     44 
     45/* Buffer structure for collecting string-formatted data  
     46* using bcm_bprintf() API. 
     47* Use bcm_binit() to initialize before use 
     48*/ 
     49 
     50struct bcmstrbuf { 
     51        char *buf;      /* pointer to current position in origbuf */ 
     52        unsigned int size;      /* current (residual) size in bytes */ 
     53        char *origbuf;  /* unmodified pointer to orignal buffer */ 
     54        unsigned int origsize;  /* unmodified orignal buffer size in bytes */ 
     55}; 
     56 
     57/* ** driver-only section ** */ 
     58#include <osl.h> 
     59 
     60#define GPIO_PIN_NOTDEFINED     0x20    /* Pin not defined */ 
     61 
     62 
     63/* osl multi-precedence packet queue */ 
     64#ifndef PKTQ_LEN_DEFAULT 
     65#define PKTQ_LEN_DEFAULT        128     /* Max 128 packets */ 
     66#endif 
     67#ifndef PKTQ_MAX_PREC 
     68#define PKTQ_MAX_PREC           16      /* Maximum precedence levels */ 
     69#endif 
     70 
     71typedef struct pktq_prec { 
     72        void *head;     /* first packet to dequeue */ 
     73        void *tail;     /* last packet to dequeue */ 
     74        uint16 len;     /* number of queued packets */ 
     75        uint16 max;     /* maximum number of queued packets */ 
     76} pktq_prec_t; 
     77 
     78 
     79/* multi-priority pkt queue */ 
     80struct pktq { 
     81        uint16 num_prec;        /* number of precedences in use */ 
     82        uint16 hi_prec;         /* rapid dequeue hint (>= highest non-empty prec) */ 
     83        uint16 max;             /* total max packets */ 
     84        uint16 len;             /* total number of packets */ 
     85        /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ 
     86        struct pktq_prec q[PKTQ_MAX_PREC]; 
     87}; 
     88 
     89/* simple, non-priority pkt queue */ 
     90struct spktq { 
     91        uint16 num_prec;        /* number of precedences in use (always 1) */ 
     92        uint16 hi_prec;         /* rapid dequeue hint (>= highest non-empty prec) */ 
     93        uint16 max;             /* total max packets */ 
     94        uint16 len;             /* total number of packets */ 
     95        /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ 
     96        struct pktq_prec q[1]; 
     97}; 
     98 
     99#define PKTQ_PREC_ITER(pq, prec)        for (prec = (pq)->num_prec - 1; prec >= 0; prec--) 
     100 
     101/* forward definition of ether_addr structure used by some function prototypes */ 
     102struct ether_addr; 
     103 
     104/* operations on a specific precedence in packet queue */ 
     105 
     106#define pktq_psetmax(pq, prec, _max)    ((pq)->q[prec].max = (_max)) 
     107#define pktq_plen(pq, prec)             ((pq)->q[prec].len) 
     108#define pktq_pavail(pq, prec)           ((pq)->q[prec].max - (pq)->q[prec].len) 
     109#define pktq_pfull(pq, prec)            ((pq)->q[prec].len >= (pq)->q[prec].max) 
     110#define pktq_pempty(pq, prec)           ((pq)->q[prec].len == 0) 
     111 
     112#define pktq_ppeek(pq, prec)            ((pq)->q[prec].head) 
     113#define pktq_ppeek_tail(pq, prec)       ((pq)->q[prec].tail) 
     114 
     115extern void *pktq_penq(struct pktq *pq, int prec, void *p); 
     116extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); 
     117extern void *pktq_pdeq(struct pktq *pq, int prec); 
     118extern void *pktq_pdeq_tail(struct pktq *pq, int prec); 
     119/* Empty the queue at particular precedence level */ 
     120extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); 
     121/* Remove a specified packet from its queue */ 
     122extern bool pktq_pdel(struct pktq *pq, void *p, int prec); 
     123 
     124/* operations on a set of precedences in packet queue */ 
     125 
     126extern int pktq_mlen(struct pktq *pq, uint prec_bmp); 
     127extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); 
     128 
     129/* operations on packet queue as a whole */ 
     130 
     131#define pktq_len(pq)                    ((int)(pq)->len) 
     132#define pktq_max(pq)                    ((int)(pq)->max) 
     133#define pktq_avail(pq)                  ((int)((pq)->max - (pq)->len)) 
     134#define pktq_full(pq)                   ((pq)->len >= (pq)->max) 
     135#define pktq_empty(pq)                  ((pq)->len == 0) 
     136 
     137/* operations for single precedence queues */ 
     138#define pktenq(pq, p)           pktq_penq(((struct pktq *)pq), 0, (p)) 
     139#define pktenq_head(pq, p)      pktq_penq_head(((struct pktq *)pq), 0, (p)) 
     140#define pktdeq(pq)              pktq_pdeq(((struct pktq *)pq), 0) 
     141#define pktdeq_tail(pq)         pktq_pdeq_tail(((struct pktq *)pq), 0) 
     142#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) 
     143 
     144extern void pktq_init(struct pktq *pq, int num_prec, int max_len); 
     145/* prec_out may be NULL if caller is not interested in return value */ 
     146extern void *pktq_deq(struct pktq *pq, int *prec_out); 
     147extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); 
     148extern void *pktq_peek(struct pktq *pq, int *prec_out); 
     149extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); 
     150extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */ 
     151extern int pktq_setmax(struct pktq *pq, int max_len); 
     152 
     153/* externs */ 
     154/* packet */ 
     155extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); 
     156extern uint pkttotlen(osl_t *osh, void *p); 
     157extern void *pktlast(osl_t *osh, void *p); 
     158 
     159/* Get priority from a packet and pass it back in scb (or equiv) */ 
     160extern uint pktsetprio(void *pkt, bool update_vtag); 
     161#define PKTPRIO_VDSCP   0x100           /* DSCP prio found after VLAN tag */ 
     162#define PKTPRIO_VLAN    0x200           /* VLAN prio found */ 
     163#define PKTPRIO_UPD     0x400           /* DSCP used to update VLAN prio */ 
     164#define PKTPRIO_DSCP    0x800           /* DSCP prio found */ 
    62165 
    63166/* string */ 
    64 extern uchar bcm_toupper(uchar c); 
    65 extern ulong bcm_strtoul(char *cp, char **endp, uint base); 
    66 extern char *bcmstrstr(char *haystack, char *needle); 
    67 extern char *bcmstrcat(char *dest, const char *src); 
     167extern int BCMROMFN(bcm_atoi)(char *s); 
     168extern ulong BCMROMFN(bcm_strtoul)(char *cp, char **endp, uint base); 
     169extern char *BCMROMFN(bcmstrstr)(char *haystack, char *needle); 
     170extern char *BCMROMFN(bcmstrcat)(char *dest, const char *src); 
     171extern char *BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size); 
    68172extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); 
    69173/* ethernet address */ 
    70174extern char *bcm_ether_ntoa(struct ether_addr *ea, char *buf); 
     175extern int BCMROMFN(bcm_ether_atoe)(char *p, struct ether_addr *ea); 
     176 
     177/* ip address */ 
     178struct ipv4_addr; 
     179extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); 
     180 
     181/* delay */ 
     182extern void bcm_mdelay(uint ms); 
    71183/* variable access */ 
    72 extern char *getvar(char *vars, char *name); 
    73 extern int getintvar(char *vars, char *name); 
     184extern char *getvar(char *vars, const char *name); 
     185extern int getintvar(char *vars, const char *name); 
    74186extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); 
     187#ifdef BCMDBG 
     188extern void prpkt(const char *msg, osl_t *osh, void *p0); 
     189#endif /* BCMDBG */ 
    75190#ifdef BCMPERFSTATS 
    76191extern void bcm_perf_enable(void); 
     
    118233/* flags are per-driver based on driver attributes */ 
    119234 
     235extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); 
     236extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); 
     237 
    120238/* Base type definitions */ 
    121239#define IOVT_VOID       0       /* no value (implictly set only) */ 
     
    128246#define IOVT_UINT32     7       /* unsigned int 32 bits */ 
    129247#define IOVT_BUFFER     8       /* buffer is size-checked as per minlen */ 
    130  
    131 extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); 
    132 extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); 
    133  
    134 #endif  /* #ifdef BCMDRIVER */ 
     248#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) 
     249 
     250/* Initializer for IOV type strings */ 
     251#define BCM_IOV_TYPE_INIT { \ 
     252        "void", \ 
     253        "bool", \ 
     254        "int8", \ 
     255        "uint8", \ 
     256        "int16", \ 
     257        "uint16", \ 
     258        "int32", \ 
     259        "uint32", \ 
     260        "buffer", \ 
     261        "" } 
     262 
     263#define BCM_IOVT_IS_INT(type) (\ 
     264        (type == IOVT_BOOL) || \ 
     265        (type == IOVT_INT8) || \ 
     266        (type == IOVT_UINT8) || \ 
     267        (type == IOVT_INT16) || \ 
     268        (type == IOVT_UINT16) || \ 
     269        (type == IOVT_INT32) || \ 
     270        (type == IOVT_UINT32)) 
    135271 
    136272/* ** driver/apps-shared section ** */ 
     
    185321#define BCME_SDIO_ERROR                 -35     /* SDIO Bus Error */ 
    186322#define BCME_DONGLE_DOWN                -36     /* Dongle Not Accessible */ 
    187 #define BCME_LAST                       BCME_DONGLE_DOWN 
     323#define BCME_VERSION                    -37 /* Incorrect version */ 
     324#define BCME_LAST                       BCME_VERSION 
    188325 
    189326/* These are collection of BCME Error strings */ 
     
    225362        "Not WME Association",          \ 
    226363        "SDIO Bus Error",               \ 
    227         "Dongle Not Accessible"         \ 
     364        "Dongle Not Accessible",        \ 
     365        "Incorrect version"     \ 
    228366} 
    229367 
     
    245383#define ISPOWEROF2(x)           ((((x)-1)&(x)) == 0) 
    246384#define VALID_MASK(mask)        !((mask) & ((mask) + 1)) 
     385#ifndef OFFSETOF 
    247386#define OFFSETOF(type, member)  ((uint)(uintptr)&((type *)0)->member) 
     387#endif /* OFFSETOF */ 
     388#ifndef ARRAYSIZE 
    248389#define ARRAYSIZE(a)            (sizeof(a)/sizeof(a[0])) 
     390#endif 
    249391 
    250392/* bit map related macros */ 
     
    255397#define setbit(a, i)    (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) 
    256398#define clrbit(a, i)    (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) 
    257 #define isset(a, i)     (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) 
    258 #define isclr(a, i)     ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) 
     399#define isset(a, i)     (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) 
     400#define isclr(a, i)     ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) 
    259401#endif /* setbit */ 
    260402 
     
    297439typedef struct bcm_bit_desc { 
    298440        uint32  bit; 
    299         char*   name; 
     441        const char* name; 
    300442} bcm_bit_desc_t; 
    301443 
     
    343485} 
    344486 
    345 #else 
     487#else /* IL_BIGENDIAN */ 
    346488 
    347489static INLINE uint32 
     
    377519/* externs */ 
    378520/* crc */ 
    379 extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); 
    380 extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); 
    381 extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); 
     521extern uint8 BCMROMFN(hndcrc8)(uint8 *p, uint nbytes, uint8 crc); 
     522extern uint16 BCMROMFN(hndcrc16)(uint8 *p, uint nbytes, uint16 crc); 
     523extern uint32 BCMROMFN(hndcrc32)(uint8 *p, uint nbytes, uint32 crc); 
    382524/* format/print */ 
     525#ifdef BCMDBG 
     526extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); 
     527extern int bcm_format_hex(char *str, const void *bytes, int len); 
     528extern void deadbeef(void *p, uint len); 
     529extern void prhex(const char *msg, uchar *buf, uint len); 
     530#endif /* BCMDBG */ 
     531extern char *bcm_brev_str(uint16 brev, char *buf); 
    383532extern void printfbig(char *buf); 
    384533 
    385534/* IE parsing */ 
    386 extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); 
    387 extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); 
    388 extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); 
     535extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen); 
     536extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); 
     537extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key); 
    389538 
    390539/* bcmerror */ 
     
    393542/* multi-bool data type: set of bools, mbool is true if any is set */ 
    394543typedef uint32 mbool; 
    395 #define mboolset(mb, bit)               (mb |= bit)             /* set one bool */ 
    396 #define mboolclr(mb, bit)               (mb &= ~bit)            /* clear one bool */ 
    397 #define mboolisset(mb, bit)             ((mb & bit) != 0)       /* TRUE if one bool is set */ 
     544#define mboolset(mb, bit)               ((mb) |= (bit))         /* set one bool */ 
     545#define mboolclr(mb, bit)               ((mb) &= ~(bit))        /* clear one bool */ 
     546#define mboolisset(mb, bit)             (((mb) & (bit)) != 0)   /* TRUE if one bool is set */ 
    398547#define mboolmaskset(mb, mask, val)     ((mb) = (((mb) & ~(mask)) | (val))) 
    399548 
    400549/* power conversion */ 
    401 extern uint16 bcm_qdbm_to_mw(uint8 qdbm); 
    402 extern uint8 bcm_mw_to_qdbm(uint16 mw); 
     550extern uint16 BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm); 
     551extern uint8 BCMROMFN(bcm_mw_to_qdbm)(uint16 mw); 
    403552 
    404553/* generic datastruct to help dump routines */ 
    405554struct fielddesc { 
    406         char    *nameandfmt; 
     555        const char *nameandfmt; 
    407556        uint32  offset; 
    408557        uint32  len; 
    409558}; 
    410559 
    411 /* Buffer structure for collecting string-formatted data  
    412 * using bcm_bprintf() API. 
    413 * Use bcm_binit() to initialize before use 
    414 */ 
    415 struct bcmstrbuf 
    416 { 
    417         char *buf;      /* pointer to current position in origbuf */ 
    418         uint size;      /* current (residual) size in bytes */ 
    419         char *origbuf;  /* unmodified pointer to orignal buffer */ 
    420         uint origsize;  /* unmodified orignal buffer size in bytes */ 
    421 }; 
    422  
    423560extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); 
    424561extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); 
     
    429566 
    430567extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); 
    431 extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); 
     568extern uint BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint bytelength); 
     569 
     570#ifdef BCMDBG_PKT      /* pkt logging for debugging */ 
     571#define PKTLIST_SIZE 1000 
     572typedef struct { 
     573        void *list[PKTLIST_SIZE]; /* List of pointers to packets */ 
     574        uint count; /* Total count of the packets */ 
     575} pktlist_info_t; 
     576 
     577extern void pktlist_add(pktlist_info_t *pktlist, void *p); 
     578extern void pktlist_remove(pktlist_info_t *pktlist, void *p); 
     579extern char* pktlist_dump(pktlist_info_t *pktlist, char *buf); 
     580#endif  /* BCMDBG_PKT */ 
    432581 
    433582#endif  /* _bcmutils_h_ */ 
  • trunk/package/broadcom-wl/src/driver/hnddma.c

    r9528 r10137  
    33 * This supports the following chips: BCM42xx, 44xx, 47xx . 
    44 * 
    5  * Copyright 2006, Broadcom Corporation 
     5 * Copyright 2007, Broadcom Corporation 
    66 * All Rights Reserved. 
    77 *  
     
    1111 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
    1212 * 
    13  * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $ 
     13 * $Id$ 
    1414 */ 
    1515 
     
    2020#include <bcmendian.h> 
    2121#include <sbconfig.h> 
    22 #include <bcmutils.h> 
     22#include "bcmutils.h" 
    2323#include <bcmdevs.h> 
    2424#include <sbutils.h> 
     
    2828 
    2929/* debug/trace */ 
     30#ifdef BCMDBG 
     31#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args 
     32#define DMA_TRACE(args) if (!(*di->msg_level & 2)); else printf args 
     33#else 
    3034#define DMA_ERROR(args) 
    3135#define DMA_TRACE(args) 
     36#endif 
    3237 
    3338/* default dma message level (if input msg_level pointer is null in dma_attach()) */ 
    34 static uint dma_msg_level = 
    35         0; 
    36  
    37 #define MAXNAMEL        8               /* 8 char names */ 
     39static uint dma_msg_level = 0; 
     40 
     41#define MAXNAMEL        8       /* 8 char names */ 
    3842 
    3943#define DI_INFO(dmah)   (dma_info_t *)dmah 
     44typedef struct osl_dmainfo osldma_t; 
    4045 
    4146/* dma engine software state */ 
    42 typedef struct dma_info { 
    43         struct hnddma_pub hnddma;       /* exported structure, don't use hnddma_t, 
    44                                          * which could be const 
    45                                          */ 
    46         uint            *msg_level;     /* message level pointer */ 
    47         char            name[MAXNAMEL]; /* callers name for diag msgs */ 
    48  
    49         void            *osh;           /* os handle */ 
    50         sb_t            *sbh;           /* sb handle */ 
    51  
    52         bool            dma64;          /* dma64 enabled */ 
    53         bool            addrext;        /* this dma engine supports DmaExtendedAddrChanges */ 
    54  
    55         dma32regs_t     *d32txregs;     /* 32 bits dma tx engine registers */ 
    56         dma32regs_t     *d32rxregs;     /* 32 bits dma rx engine registers */ 
    57         dma64regs_t     *d64txregs;     /* 64 bits dma tx engine registers */ 
    58         dma64regs_t     *d64rxregs;     /* 64 bits dma rx engine registers */ 
    59  
    60         uint32          dma64align;     /* either 8k or 4k depends on number of dd */ 
    61         dma32dd_t       *txd32;         /* pointer to dma32 tx descriptor ring */ 
    62         dma64dd_t       *txd64;         /* pointer to dma64 tx descriptor ring */ 
    63         uint            ntxd;           /* # tx descriptors tunable */ 
    64         uint            txin;           /* index of next descriptor to reclaim */ 
    65         uint            txout;          /* index of next descriptor to post */ 
    66         void            **txp;          /* pointer to parallel array of pointers to packets */ 
    67         osldma_t        *tx_dmah;       /* DMA TX descriptor ring handle */ 
    68         osldma_t        **txp_dmah;     /* DMA TX packet data handle */ 
    69         ulong           txdpa;          /* physical address of descriptor ring */ 
    70         uint            txdalign;       /* #bytes added to alloc'd mem to align txd */ 
    71         uint            txdalloc;       /* #bytes allocated for the ring */ 
    72  
    73         dma32dd_t       *rxd32;         /* pointer to dma32 rx descriptor ring */ 
    74         dma64dd_t       *rxd64;         /* pointer to dma64 rx descriptor ring */ 
    75         uint            nrxd;           /* # rx descriptors tunable */ 
    76         uint            rxin;           /* index of next descriptor to reclaim */ 
    77         uint            rxout;          /* index of next descriptor to post */ 
    78         void            **rxp;          /* pointer to parallel array of pointers to packets */ 
    79         osldma_t        *rx_dmah;       /* DMA RX descriptor ring handle */ 
    80         osldma_t        **rxp_dmah;     /* DMA RX packet data handle */ 
    81         ulong           rxdpa;          /* physical address of descriptor ring */ 
    82         uint            rxdalign;       /* #bytes added to alloc'd mem to align rxd */ 
    83         uint            rxdalloc;       /* #bytes allocated for the ring */ 
    84  
    85         /* tunables */ 
    86         uint            rxbufsize;      /* rx buffer size in bytes, 
    87                                            not including the extra headroom 
    88                                         */ 
    89         uint            nrxpost;        /* # rx buffers to keep posted */ 
    90         uint            rxoffset;       /* rxcontrol offset */ 
    91         uint            ddoffsetlow;    /* add to get dma address of descriptor ring, low 32 bits */ 
    92         uint            ddoffsethigh;   /*   high 32 bits */ 
    93         uint            dataoffsetlow;  /* add to get dma address of data buffer, low 32 bits */ 
    94         uint            dataoffsethigh; /*   high 32 bits */ 
     47typedef struct dma_info 
     48{ 
     49  struct hnddma_pub hnddma;     /* exported structure, don't use hnddma_t, 
     50                                 * which could be const 
     51                                 */ 
     52  uint *msg_level;              /* message level pointer */ 
     53  char name[MAXNAMEL];          /* callers name for diag msgs */ 
     54 
     55  void *osh;                    /* os handle */ 
     56  sb_t *sbh;                    /* sb handle */ 
     57 
     58  bool dma64;                   /* dma64 enabled */ 
     59  bool addrext;                 /* this dma engine supports DmaExtendedAddrChanges */ 
     60 
     61  dma32regs_t *d32txregs;       /* 32 bits dma tx engine registers */ 
     62  dma32regs_t *d32rxregs;       /* 32 bits dma rx engine registers */ 
     63  dma64regs_t *d64txregs;       /* 64 bits dma tx engine registers */ 
     64  dma64regs_t *d64rxregs;       /* 64 bits dma rx engine registers */ 
     65 
     66  uint32 dma64align;            /* either 8k or 4k depends on number of dd */ 
     67  dma32dd_t *txd32;             /* pointer to dma32 tx descriptor ring */ 
     68  dma64dd_t *txd64;             /* pointer to dma64 tx descriptor ring */ 
     69  uint ntxd;                    /* # tx descriptors tunable */ 
     70  uint txin;                    /* index of next descriptor to reclaim */ 
     71  uint txout;                   /* index of next descriptor to post */ 
     72  void **txp;                   /* pointer to parallel array of pointers to packets */ 
     73  osldma_t *tx_dmah;            /* DMA TX descriptor ring handle */ 
     74  osldma_t **txp_dmah;          /* DMA TX packet data handle */ 
     75  ulong txdpa;                  /* physical address of descriptor ring */ 
     76  uint txdalign;                /* #bytes added to alloc'd mem to align txd */ 
     77  uint txdalloc;                /* #bytes allocated for the ring */ 
     78 
     79  dma32dd_t *rxd32;             /* pointer to dma32 rx descriptor ring */ 
     80  dma64dd_t *rxd64;             /* pointer to dma64 rx descriptor ring */ 
     81  uint nrxd;                    /* # rx descriptors tunable */ 
     82  uint rxin;                    /* index of next descriptor to reclaim */ 
     83  uint rxout;                   /* index of next descriptor to post */ 
     84  void **rxp;                   /* pointer to parallel array of pointers to packets */ 
     85  osldma_t *rx_dmah;            /* DMA RX descriptor ring handle */ 
     86  osldma_t **rxp_dmah;          /* DMA RX packet data handle */ 
     87  ulong rxdpa;                  /* physical address of descriptor ring */ 
     88  uint rxdalign;                /* #bytes added to alloc'd mem to align rxd */ 
     89  uint rxdalloc;                /* #bytes allocated for the ring */ 
     90 
     91  /* tunables */ 
     92  uint rxbufsize;               /* rx buffer size in bytes, 
     93                                   not including the extra headroom 
     94                                 */ 
     95  uint nrxpost;                 /* # rx buffers to keep posted */ 
     96  uint rxoffset;                /* rxcontrol offset */ 
     97  uint ddoffsetlow;             /* add to get dma address of descriptor ring, low 32 bits */ 
     98  uint ddoffsethigh;            /*   high 32 bits */ 
     99  uint dataoffsetlow;           /* add to get dma address of data buffer, low 32 bits */ 
     100  uint dataoffsethigh;          /*   high 32 bits */ 
    95101} dma_info_t; 
    96102 
     
    118124 
    119125#define PCI32ADDR_HIGH          0xc0000000      /* address[31:30] */ 
    120 #define PCI32ADDR_HIGH_SHIFT    30              /* address[31:30] */ 
     126#define PCI32ADDR_HIGH_SHIFT    30      /* address[31:30] */ 
    121127 
    122128 
    123129/* common prototypes */ 
    124 static bool _dma_isaddrext(dma_info_t *di); 
    125 static bool _dma_alloc(dma_info_t *di, uint direction); 
    126 static void _dma_detach(dma_info_t *di); 
    127 static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa); 
    128 static void _dma_rxinit(dma_info_t *di); 
    129 static void *_dma_rx(dma_info_t *di); 
    130 static void _dma_rxfill(dma_info_t *di); 
    131 static void _dma_rxreclaim(dma_info_t *di); 
    132 static void _dma_rxenable(dma_info_t *di); 
    133 static void * _dma_getnextrxp(dma_info_t *di, bool forceall); 
    134  
    135 static void _dma_txblock(dma_info_t *di); 
    136 static void _dma_txunblock(dma_info_t *di); 
    137 static uint _dma_txactive(dma_info_t *di); 
    138  
    139 static void* _dma_peeknexttxp(dma_info_t *di); 
    140 static uintptr _dma_getvar(dma_info_t *di, const char *name); 
    141 static void _dma_counterreset(dma_info_t *di); 
    142 static void _dma_fifoloopbackenable(dma_info_t *di); 
     130static bool _dma_isaddrext (dma_info_t * di); 
     131static bool _dma_alloc (dma_info_t * di, uint direction); 
     132static void _dma_detach (dma_info_t * di); 
     133static void _dma_ddtable_init (dma_info_t * di, uint direction, ulong pa); 
     134static void _dma_rxinit (dma_info_t * di); 
     135static void *_dma_rx (dma_info_t * di); 
     136static void _dma_rxfill (dma_info_t * di); 
     137static void _dma_rxreclaim (dma_info_t * di); 
     138static void _dma_rxenable (dma_info_t * di); 
     139static void *_dma_getnextrxp (dma_info_t * di, bool forceall); 
     140 
     141static void _dma_txblock (dma_info_t * di); 
     142static void _dma_txunblock (dma_info_t * di); 
     143static uint _dma_txactive (dma_info_t * di); 
     144 
     145static void *_dma_peeknexttxp (dma_info_t * di); 
     146static uintptr _dma_getvar (dma_info_t * di, const char *name); 
     147static void _dma_counterreset (dma_info_t * di); 
     148static void _dma_fifoloopbackenable (dma_info_t * di); 
    143149 
    144150/* ** 32 bit DMA prototypes */ 
    145 static bool dma32_alloc(dma_info_t *di, uint direction); 
    146 static bool dma32_txreset(dma_info_t *di); 
    147 static bool dma32_rxreset(dma_info_t *di); 
    148 static bool dma32_txsuspendedidle(dma_info_t *di); 
    149 static int  dma32_txfast(dma_info_t *di, void *p0, bool commit); 
    150 static void *dma32_getnexttxp(dma_info_t *di, bool forceall); 
    151 static void *dma32_getnextrxp(dma_info_t *di, bool forceall); 
    152 static void dma32_txrotate(dma_info_t *di); 
    153 static bool dma32_rxidle(dma_info_t *di); 
    154 static void dma32_txinit(dma_info_t *di); 
    155 static bool dma32_txenabled(dma_info_t *di); 
    156 static void dma32_txsuspend(dma_info_t *di); 
    157 static void dma32_txresume(dma_info_t *di); 
    158 static bool dma32_txsuspended(dma_info_t *di); 
    159 static void dma32_txreclaim(dma_info_t *di, bool forceall); 
    160 static bool dma32_txstopped(dma_info_t *di); 
    161 static bool dma32_rxstopped(dma_info_t *di); 
    162 static bool dma32_rxenabled(dma_info_t *di); 
    163 static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); 
     151static bool dma32_alloc (dma_info_t * di, uint direction); 
     152static bool dma32_txreset (dma_info_t * di); 
     153static bool dma32_rxreset (dma_info_t * di); 
     154static bool dma32_txsuspendedidle (dma_info_t * di); 
     155static int dma32_txfast (dma_info_t * di, void *p0, bool commit); 
     156static void *dma32_getnexttxp (dma_info_t * di, bool forceall); 
     157static void *dma32_getnextrxp (dma_info_t * di, bool forceall); 
     158static void dma32_txrotate (dma_info_t * di); 
     159static bool dma32_rxidle (dma_info_t * di); 
     160static void dma32_txinit (dma_info_t * di); 
     161static bool dma32_txenabled (dma_info_t * di); 
     162static void dma32_txsuspend (dma_info_t * di); 
     163static void dma32_txresume (dma_info_t * di); 
     164static bool dma32_txsuspended (dma_info_t * di); 
     165static void dma32_txreclaim (dma_info_t * di, bool forceall); 
     166static bool dma32_txstopped (dma_info_t * di); 
     167static bool dma32_rxstopped (dma_info_t * di); 
     168static bool dma32_rxenabled (dma_info_t * di); 
     169static bool _dma32_addrext (osl_t * osh, dma32regs_t * dma32regs); 
    164170 
    165171/* ** 64 bit DMA prototypes and stubs */ 
    166172#ifdef BCMDMA64 
    167 static bool dma64_alloc(dma_info_t *di, uint direction); 
    168 static bool dma64_txreset(dma_info_t *di); 
    169 static bool dma64_rxreset(dma_info_t *di); 
    170 static bool dma64_txsuspendedidle(dma_info_t *di); 
    171 static int  dma64_txfast(dma_info_t *di, void *p0, bool commit); 
    172 static void *dma64_getnexttxp(dma_info_t *di, bool forceall); 
    173 static void *dma64_getnextrxp(dma_info_t *di, bool forceall); 
    174 static void dma64_txrotate(dma_info_t *di); 
    175  
    176 static bool dma64_rxidle(dma_info_t *di); 
    177 static void dma64_txinit(dma_info_t *di); 
    178 static bool dma64_txenabled(dma_info_t *di); 
    179 static void dma64_txsuspend(dma_info_t *di); 
    180 static void dma64_txresume(dma_info_t *di); 
    181 static bool dma64_txsuspended(dma_info_t *di); 
    182 static void dma64_txreclaim(dma_info_t *di, bool forceall); 
    183 static bool dma64_txstopped(dma_info_t *di); 
    184 static bool dma64_rxstopped(dma_info_t *di); 
    185 static bool dma64_rxenabled(dma_info_t *di); 
    186 static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs); 
     173static bool dma64_alloc (dma_info_t * di, uint direction); 
     174static bool dma64_txreset (dma_info_t * di); 
     175static bool dma64_rxreset (dma_info_t * di); 
     176static bool dma64_txsuspendedidle (dma_info_t * di); 
     177static int dma64_txfast (dma_info_t * di, void *p0, bool commit); 
     178static void *dma64_getnexttxp (dma_info_t * di, bool forceall); 
     179static void *dma64_getnextrxp (dma_info_t * di, bool forceall); 
     180static void dma64_txrotate (dma_info_t * di); 
     181 
     182static bool dma64_rxidle (dma_info_t * di); 
     183static void dma64_txinit (dma_info_t * di); 
     184static bool dma64_txenabled (dma_info_t * di); 
     185static void dma64_txsuspend (dma_info_t * di); 
     186static void dma64_txresume (dma_info_t * di); 
     187static bool dma64_txsuspended (dma_info_t * di); 
     188static void dma64_txreclaim (dma_info_t * di, bool forceall); 
     189static bool dma64_txstopped (dma_info_t * di); 
     190static bool dma64_rxstopped (dma_info_t * di); 
     191static bool dma64_rxenabled (dma_info_t * di); 
     192static bool _dma64_addrext (osl_t * osh, dma64regs_t * dma64regs); 
    187193 
    188194#else 
    189 static bool dma64_alloc(dma_info_t *di, uint direction) { return FALSE; } 
    190 static bool dma64_txreset(dma_info_t *di) { return FALSE; } 
    191 static bool dma64_rxreset(dma_info_t *di) { return FALSE; } 
    192 static bool dma64_txsuspendedidle(dma_info_t *di) { return FALSE;} 
    193 static int  dma64_txfast(dma_info_t *di, void *p0, bool commit) { return 0; } 
    194 static void *dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } 
    195 static void *dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } 
    196 static void dma64_txrotate(dma_info_t *di) { return; } 
    197  
    198 static bool dma64_rxidle(dma_info_t *di) { return FALSE; } 
    199 static void dma64_txinit(dma_info_t *di) { return; } 
    200 static bool dma64_txenabled(dma_info_t *di) { return FALSE; } 
    201 static void dma64_txsuspend(dma_info_t *di) { return; } 
    202 static void dma64_txresume(dma_info_t *di) { return; } 
    203 static bool dma64_txsuspended(dma_info_t *di) {return FALSE; } 
    204 static void dma64_txreclaim(dma_info_t *di, bool forceall) { return; } 
    205 static bool dma64_txstopped(dma_info_t *di) { return FALSE; } 
    206 static bool dma64_rxstopped(dma_info_t *di) { return FALSE; } 
    207 static bool dma64_rxenabled(dma_info_t *di) { return FALSE; } 
    208 static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs) { return FALSE; } 
    209  
    210 #endif  /* BCMDMA64 */ 
    211  
     195static bool 
     196dma64_alloc (dma_info_t * di, uint direction) 
     197{ 
     198  return FALSE; 
     199} 
     200static bool 
     201dma64_txreset (dma_info_t * di) 
     202{ 
     203  return FALSE; 
     204} 
     205static bool 
     206dma64_rxreset (dma_info_t * di) 
     207{ 
     208  return FALSE; 
     209} 
     210static bool 
     211dma64_txsuspendedidle (dma_info_t * di) 
     212{ 
     213  return FALSE; 
     214} 
     215static int 
     216dma64_txfast (dma_info_t * di, void *p0, bool commit) 
     217{ 
     218  return 0; 
     219} 
     220static void * 
     221dma64_getnexttxp (dma_info_t * di, bool forceall) 
     222{ 
     223  return NULL; 
     224} 
     225static void * 
     226dma64_getnextrxp (dma_info_t * di, bool forceall) 
     227{ 
     228  return NULL; 
     229} 
     230static void 
     231dma64_txrotate (dma_info_t * di) 
     232{ 
     233  return; 
     234} 
     235 
     236static bool 
     237dma64_rxidle (dma_info_t * di) 
     238{ 
     239  return FALSE; 
     240} 
     241static void 
     242dma64_txinit (dma_info_t * di) 
     243{ 
     244  return; 
     245} 
     246static bool 
     247dma64_txenabled (dma_info_t * di) 
     248{ 
     249  return FALSE; 
     250} 
     251static void 
     252dma64_txsuspend (dma_info_t * di) 
     253{ 
     254  return; 
     255} 
     256static void 
     257dma64_txresume (dma_info_t * di) 
     258{ 
     259  return; 
     260} 
     261static bool 
     262dma64_txsuspended (dma_info_t * di) 
     263{ 
     264  return FALSE; 
     265} 
     266static void 
     267dma64_txreclaim (dma_info_t * di, bool forceall) 
     268{ 
     269  return; 
     270} 
     271static bool 
     272dma64_txstopped (dma_info_t * di) 
     273{ 
     274  return FALSE; 
     275} 
     276static bool 
     277dma64_rxstopped (dma_info_t * di) 
     278{ 
     279  return FALSE; 
     280} 
     281static bool 
     282dma64_rxenabled (dma_info_t * di) 
     283{ 
     284  return FALSE; 
     285} 
     286static bool 
     287_dma64_addrext (osl_t * osh, dma64regs_t * dma64regs) 
     288{ 
     289  return FALSE; 
     290} 
     291 
     292#endif /* BCMDMA64 */ 
     293 
     294#ifdef BCMDBG 
     295static void dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b, 
     296                            dma32dd_t * ring, uint start, uint end, 
     297                            uint max_num); 
     298static void dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring); 
     299static void dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b, 
     300                          bool dumpring); 
     301static void dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b, 
     302                          bool dumpring); 
     303 
     304static void dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b, 
     305                            dma64dd_t * ring, uint start, uint end, 
     306                            uint max_num); 
     307static void dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring); 
     308static void dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b, 
     309                          bool dumpring); 
     310static void dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b, 
     311                          bool dumpring); 
     312#endif 
    212313 
    213314 
    214315static di_fcn_t dma64proc = { 
    215         (di_detach_t)_dma_detach, 
    216         (di_txinit_t)dma64_txinit, 
    217         (di_txreset_t)dma64_txreset, 
    218         (di_txenabled_t)dma64_txenabled, 
    219         (di_txsuspend_t)dma64_txsuspend, 
    220         (di_txresume_t)dma64_txresume, 
    221         (di_txsuspended_t)dma64_txsuspended, 
    222         (di_txsuspendedidle_t)dma64_txsuspendedidle, 
    223         (di_txfast_t)dma64_txfast, 
    224         (di_txstopped_t)dma64_txstopped, 
    225         (di_txreclaim_t)dma64_txreclaim, 
    226         (di_getnexttxp_t)dma64_getnexttxp, 
    227         (di_peeknexttxp_t)_dma_peeknexttxp, 
    228         (di_txblock_t)_dma_txblock, 
    229         (di_txunblock_t)_dma_txunblock, 
    230         (di_txactive_t)_dma_txactive, 
    231         (di_txrotate_t)dma64_txrotate, 
    232  
    233         (di_rxinit_t)_dma_rxinit, 
    234         (di_rxreset_t)dma64_rxreset, 
    235         (di_rxidle_t)dma64_rxidle, 
    236         (di_rxstopped_t)dma64_rxstopped, 
    237         (di_rxenable_t)_dma_rxenable, 
    238         (di_rxenabled_t)dma64_rxenabled, 
    239         (di_rx_t)_dma_rx, 
    240         (di_rxfill_t)_dma_rxfill, 
    241         (di_rxreclaim_t)_dma_rxreclaim, 
    242         (di_getnextrxp_t)_dma_getnextrxp, 
    243  
    244         (di_fifoloopbackenable_t)_dma_fifoloopbackenable, 
    245         (di_getvar_t)_dma_getvar, 
    246         (di_counterreset_t)_dma_counterreset, 
    247  
    248         NULL, 
    249         NULL, 
    250         NULL, 
    251         34 
     316  (di_detach_t) _dma_detach, 
     317  (di_txinit_t) dma64_txinit, 
     318  (di_txreset_t) dma64_txreset, 
     319  (di_txenabled_t) dma64_txenabled, 
     320  (di_txsuspend_t) dma64_txsuspend, 
     321  (di_txresume_t) dma64_txresume, 
     322  (di_txsuspended_t) dma64_txsuspended, 
     323  (di_txsuspendedidle_t) dma64_txsuspendedidle, 
     324  (di_txfast_t) dma64_txfast, 
     325  (di_txstopped_t) dma64_txstopped, 
     326  (di_txreclaim_t) dma64_txreclaim, 
     327  (di_getnexttxp_t) dma64_getnexttxp, 
     328  (di_peeknexttxp_t) _dma_peeknexttxp, 
     329  (di_txblock_t) _dma_txblock, 
     330  (di_txunblock_t) _dma_txunblock, 
     331  (di_txactive_t) _dma_txactive, 
     332  (di_txrotate_t) dma64_txrotate, 
     333 
     334  (di_rxinit_t) _dma_rxinit, 
     335  (di_rxreset_t) dma64_rxreset, 
     336  (di_rxidle_t) dma64_rxidle, 
     337  (di_rxstopped_t) dma64_rxstopped, 
     338  (di_rxenable_t) _dma_rxenable, 
     339  (di_rxenabled_t) dma64_rxenabled, 
     340  (di_rx_t) _dma_rx, 
     341  (di_rxfill_t) _dma_rxfill, 
     342  (di_rxreclaim_t) _dma_rxreclaim, 
     343  (di_getnextrxp_t) _dma_getnextrxp, 
     344 
     345  (di_fifoloopbackenable_t) _dma_fifoloopbackenable, 
     346  (di_getvar_t) _dma_getvar, 
     347  (di_counterreset_t) _dma_counterreset, 
     348 
     349#ifdef BCMDBG 
     350  (di_dump_t) dma64_dump, 
     351  (di_dumptx_t) dma64_dumptx, 
     352  (di_dumprx_t) dma64_dumprx, 
     353#else 
     354  NULL, 
     355  NULL, 
     356  NULL, 
     357#endif 
     358  34 
    252359}; 
    253360 
    254361static di_fcn_t dma32proc = { 
    255         (di_detach_t)_dma_detach, 
    256         (di_txinit_t)dma32_txinit, 
    257         (di_txreset_t)dma32_txreset, 
    258         (di_txenabled_t)dma32_txenabled, 
    259         (di_txsuspend_t)dma32_txsuspend, 
    260         (di_txresume_t)dma32_txresume, 
    261         (di_txsuspended_t)dma32_txsuspended, 
    262         (di_txsuspendedidle_t)dma32_txsuspendedidle, 
    263         (di_txfast_t)dma32_txfast, 
    264         (di_txstopped_t)dma32_txstopped, 
    265         (di_txreclaim_t)dma32_txreclaim, 
    266         (di_getnexttxp_t)dma32_getnexttxp, 
    267         (di_peeknexttxp_t)_dma_peeknexttxp, 
    268         (di_txblock_t)_dma_txblock, 
    269         (di_txunblock_t)_dma_txunblock, 
    270         (di_txactive_t)_dma_txactive, 
    271         (di_txrotate_t)dma32_txrotate, 
    272  
    273         (di_rxinit_t)_dma_rxinit, 
    274         (di_rxreset_t)dma32_rxreset, 
    275         (di_rxidle_t)dma32_rxidle, 
    276         (di_rxstopped_t)dma32_rxstopped, 
    277         (di_rxenable_t)_dma_rxenable, 
    278         (di_rxenabled_t)dma32_rxenabled, 
    279         (di_rx_t)_dma_rx, 
    280         (di_rxfill_t)_dma_rxfill, 
    281         (di_rxreclaim_t)_dma_rxreclaim, 
    282         (di_getnextrxp_t)_dma_getnextrxp, 
    283  
    284         (di_fifoloopbackenable_t)_dma_fifoloopbackenable, 
    285         (di_getvar_t)_dma_getvar, 
    286         (di_counterreset_t)_dma_counterreset, 
    287  
    288         NULL, 
    289         NULL, 
    290         NULL, 
    291         34 
     362  (di_detach_t) _dma_detach, 
     363  (di_txinit_t) dma32_txinit, 
     364  (di_txreset_t) dma32_txreset, 
     365  (di_txenabled_t) dma32_txenabled, 
     366  (di_txsuspend_t) dma32_txsuspend, 
     367  (di_txresume_t) dma32_txresume, 
     368  (di_txsuspended_t) dma32_txsuspended, 
     369  (di_txsuspendedidle_t) dma32_txsuspendedidle, 
     370  (di_txfast_t) dma32_txfast, 
     371  (di_txstopped_t) dma32_txstopped, 
     372  (di_txreclaim_t) dma32_txreclaim, 
     373  (di_getnexttxp_t) dma32_getnexttxp, 
     374  (di_peeknexttxp_t) _dma_peeknexttxp, 
     375  (di_txblock_t) _dma_txblock, 
     376  (di_txunblock_t) _dma_txunblock, 
     377  (di_txactive_t) _dma_txactive, 
     378  (di_txrotate_t) dma32_txrotate, 
     379 
     380  (di_rxinit_t) _dma_rxinit, 
     381  (di_rxreset_t) dma32_rxreset, 
     382  (di_rxidle_t) dma32_rxidle, 
     383  (di_rxstopped_t) dma32_rxstopped, 
     384  (di_rxenable_t) _dma_rxenable, 
     385  (di_rxenabled_t) dma32_rxenabled, 
     386  (di_rx_t) _dma_rx, 
     387  (di_rxfill_t) _dma_rxfill, 
     388  (di_rxreclaim_t) _dma_rxreclaim, 
     389  (di_getnextrxp_t) _dma_getnextrxp, 
     390 
     391  (di_fifoloopbackenable_t) _dma_fifoloopbackenable, 
     392  (di_getvar_t) _dma_getvar, 
     393  (di_counterreset_t) _dma_counterreset, 
     394 
     395#ifdef BCMDBG 
     396  (di_dump_t) dma32_dump, 
     397  (di_dumptx_t) dma32_dumptx, 
     398  (di_dumprx_t) dma32_dumprx, 
     399#else 
     400  NULL, 
     401  NULL, 
     402  NULL, 
     403#endif 
     404  34 
    292405}; 
    293406 
    294407hnddma_t * 
    295 dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, 
    296            uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) 
    297 { 
    298         dma_info_t *di; 
    299         uint size; 
    300  
    301         /* allocate private info structure */ 
    302         if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { 
    303                 return (NULL); 
     408dma_attach (osl_t * osh, char *name, sb_t * sbh, void *dmaregstx, 
     409            void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, 
     410            uint nrxpost, uint rxoffset, uint * msg_level) 
     411{ 
     412  dma_info_t *di; 
     413  uint size; 
     414 
     415  /* allocate private info structure */ 
     416  if ((di = MALLOC (osh, sizeof (dma_info_t))) == NULL) 
     417    { 
     418#ifdef BCMDBG 
     419      printf ("dma_attach: out of memory, malloced %d bytes\n", 
     420              MALLOCED (osh)); 
     421#endif 
     422      return (NULL); 
     423    } 
     424  bzero ((char *) di, sizeof (dma_info_t)); 
     425 
     426  di->msg_level = msg_level ? msg_level : &dma_msg_level; 
     427 
     428  /* old chips w/o sb is no longer supported */ 
     429  ASSERT (sbh != NULL); 
     430 
     431  di->dma64 = ((sb_coreflagshi (sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); 
     432 
     433#ifndef BCMDMA64 
     434  if (di->dma64) 
     435    { 
     436      DMA_ERROR (("dma_attach: driver doesn't have the capability to support " 
     437                  "64 bits DMA\n")); 
     438      goto fail; 
     439    } 
     440#endif 
     441 
     442  /* check arguments */ 
     443  ASSERT (ISPOWEROF2 (ntxd)); 
     444  ASSERT (ISPOWEROF2 (nrxd)); 
     445  if (nrxd == 0) 
     446    ASSERT (dmaregsrx == NULL); 
     447  if (ntxd == 0) 
     448    ASSERT (dmaregstx == NULL); 
     449 
     450 
     451  /* init dma reg pointer */ 
     452  if (di->dma64) 
     453    { 
     454      ASSERT (ntxd <= D64MAXDD); 
     455      ASSERT (nrxd <= D64MAXDD); 
     456      di->d64txregs = (dma64regs_t *) dmaregstx; 
     457      di->d64rxregs = (dma64regs_t *) dmaregsrx; 
     458 
     459      di->dma64align = D64RINGALIGN; 
     460      if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) 
     461        { 
     462          /* for smaller dd table, HW relax the alignment requirement */ 
     463          di->dma64align = D64RINGALIGN / 2; 
    304464        } 
    305         bzero((char *)di, sizeof(dma_info_t)); 
    306  
    307         di->msg_level = msg_level ? msg_level : &dma_msg_level; 
    308  
    309         /* old chips w/o sb is no longer supported */ 
    310         ASSERT(sbh != NULL); 
    311          
    312         di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); 
    313  
    314 #ifndef BCMDMA64 
    315         if (di->dma64) { 
    316                 DMA_ERROR(("dma_attach: driver doesn't have the capability to support " 
    317                            "64 bits DMA\n")); 
    318                 goto fail; 
     465    } 
     466  else 
     467    { 
     468      ASSERT (ntxd <= D32MAXDD); 
     469      ASSERT (nrxd <= D32MAXDD); 
     470      di->d32txregs = (dma32regs_t *) dmaregstx; 
     471      di->d32rxregs = (dma32regs_t *) dmaregsrx; 
     472    } 
     473 
     474  DMA_TRACE (("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " "rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, dmaregstx, dmaregsrx)); 
     475 
     476  /* make a private copy of our callers name */ 
     477  strncpy (di->name, name, MAXNAMEL); 
     478  di->name[MAXNAMEL - 1] = '\0'; 
     479 
     480  di->osh = osh; 
     481  di->sbh = sbh; 
     482 
     483  /* save tunables */ 
     484  di->ntxd = ntxd; 
     485  di->nrxd = nrxd; 
     486 
     487  /* the actual dma size doesn't include the extra headroom */ 
     488  if (rxbufsize > BCMEXTRAHDROOM) 
     489    di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; 
     490  else 
     491    di->rxbufsize = rxbufsize; 
     492 
     493  di->nrxpost = nrxpost; 
     494  di->rxoffset = rxoffset; 
     495 
     496  /* 
     497   * figure out the DMA physical address offset for dd and data 
     498   *   for old chips w/o sb, use zero 
     499   *   for new chips w sb, 
     500   *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset 
     501   *     Other bus: use zero 
     502   *     SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor 
     503   */ 
     504  di->ddoffsetlow = 0; 
     505  di->dataoffsetlow = 0; 
     506  /* for pci bus, add offset */ 
     507  if (sbh->bustype == PCI_BUS) 
     508    { 
     509      if ((sbh->buscoretype == SB_PCIE) && di->dma64) 
     510        { 
     511          /* pcie with DMA64 */ 
     512          di->ddoffsetlow = 0; 
     513          di->ddoffsethigh = SB_PCIE_DMA_H32; 
    319514        } 
     515      else 
     516        { 
     517          /* pci(DMA32/DMA64) or pcie with DMA32 */ 
     518          di->ddoffsetlow = SB_PCI_DMA; 
     519          di->ddoffsethigh = 0; 
     520        } 
     521      di->dataoffsetlow = di->ddoffsetlow; 
     522      di->dataoffsethigh = di->ddoffsethigh; 
     523    } 
     524 
     525#if defined(__mips__) && defined(IL_BIGENDIAN) 
     526  di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; 
    320527#endif 
    321528 
    322         /* check arguments */ 
    323         ASSERT(ISPOWEROF2(ntxd)); 
    324         ASSERT(ISPOWEROF2(nrxd)); 
    325         if (nrxd == 0) 
    326                 ASSERT(dmaregsrx == NULL); 
    327         if (ntxd == 0) 
    328                 ASSERT(dmaregstx == NULL); 
    329  
    330  
    331         /* init dma reg pointer */ 
    332         if (di->dma64) { 
    333                 ASSERT(ntxd <= D64MAXDD); 
    334                 ASSERT(nrxd <= D64MAXDD); 
    335                 di->d64txregs = (dma64regs_t *)dmaregstx; 
    336                 di->d64rxregs = (dma64regs_t *)dmaregsrx; 
    337  
    338                 di->dma64align = D64RINGALIGN; 
    339                 if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { 
    340                         /* for smaller dd table, HW relax the alignment requirement */ 
    341                         di->dma64align = D64RINGALIGN / 2; 
    342                 } 
    343         } else { 
    344                 ASSERT(ntxd <= D32MAXDD); 
    345                 ASSERT(nrxd <= D32MAXDD); 
    346                 di->d32txregs = (dma32regs_t *)dmaregstx; 
    347                 di->d32rxregs = (dma32regs_t *)dmaregsrx; 
     529  di->addrext = _dma_isaddrext (di); 
     530 
     531  /* allocate tx packet pointer vector */ 
     532  if (ntxd) 
     533    { 
     534      size = ntxd * sizeof (void *); 
     535      if ((di->txp = MALLOC (osh, size)) == NULL) 
     536        { 
     537          DMA_ERROR (("%s: dma_attach: out of tx memory, malloced %d bytes\n", 
     538                      di->name, MALLOCED (osh))); 
     539          goto fail; 
    348540        } 
    349  
    350         DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " 
    351                    "rxoffset %d dmaregstx %p dmaregsrx %p\n", 
    352                    name, (di->dma64 ? "DMA64" : "DMA32"), osh, ntxd, nrxd, rxbufsize, 
    353                    nrxpost, rxoffset, dmaregstx, dmaregsrx)); 
    354  
    355         /* make a private copy of our callers name */ 
    356         strncpy(di->name, name, MAXNAMEL); 
    357         di->name[MAXNAMEL-1] = '\0'; 
    358  
    359         di->osh = osh; 
    360         di->sbh = sbh; 
    361  
    362         /* save tunables */ 
    363         di->ntxd = ntxd; 
    364         di->nrxd = nrxd; 
    365  
    366         /* the actual dma size doesn't include the extra headroom */ 
    367         if (rxbufsize > BCMEXTRAHDROOM) 
    368                 di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; 
    369         else 
    370                 di->rxbufsize = rxbufsize; 
    371  
    372         di->nrxpost = nrxpost; 
    373         di->rxoffset = rxoffset; 
    374  
    375         /* 
    376          * figure out the DMA physical address offset for dd and data 
    377          *   for old chips w/o sb, use zero 
    378          *   for new chips w sb, 
    379          *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset 
    380          *     Other bus: use zero 
    381          *     SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor 
    382          */ 
    383         di->ddoffsetlow = 0; 
    384         di->dataoffsetlow = 0; 
    385         /* for pci bus, add offset */ 
    386         if (sbh->bustype == PCI_BUS) { 
    387                 if ((sbh->buscoretype == SB_PCIE) && di->dma64) { 
    388                         /* pcie with DMA64 */ 
    389                         di->ddoffsetlow = 0; 
    390                         di->ddoffsethigh = SB_PCIE_DMA_H32; 
    391                 } else { 
    392                         /* pci(DMA32/DMA64) or pcie with DMA32 */ 
    393                         di->ddoffsetlow = SB_PCI_DMA; 
    394                         di->ddoffsethigh = 0; 
    395                 } 
    396                 di->dataoffsetlow =  di->ddoffsetlow; 
    397                 di->dataoffsethigh =  di->ddoffsethigh; 
     541      bzero ((char *) di->txp, size); 
     542    } 
     543 
     544  /* allocate rx packet pointer vector */ 
     545  if (nrxd) 
     546    { 
     547      size = nrxd * sizeof (void *); 
     548      if ((di->rxp = MALLOC (osh, size)) == NULL) 
     549        { 
     550          DMA_ERROR (("%s: dma_attach: out of rx memory, malloced %d bytes\n", 
     551                      di->name, MALLOCED (osh))); 
     552          goto fail; 
    398553        } 
    399  
    400 #if defined(__mips__) && defined(IL_BIGENDIAN) 
    401         di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; 
    402 #endif 
    403  
    404         di->addrext = _dma_isaddrext(di); 
    405  
    406         /* allocate tx packet pointer vector */ 
    407         if (ntxd) { 
    408                 size = ntxd * sizeof(void *); 
    409                 if ((di->txp = MALLOC(osh, size)) == NULL) { 
    410                         DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", 
    411                                    di->name, MALLOCED(osh))); 
    412                         goto fail; 
    413                 } 
    414                 bzero((char *)di->txp, size); 
    415         } 
    416  
    417         /* allocate rx packet pointer vector */ 
    418         if (nrxd) { 
    419                 size = nrxd * sizeof(void *); 
    420                 if ((di->rxp = MALLOC(osh, size)) == NULL) { 
    421                         DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", 
    422                                    di->name, MALLOCED(osh))); 
    423                         goto fail; 
    424                 } 
    425                 bzero((char *)di->rxp, size); 
    426         } 
    427  
    428         /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ 
    429         if (ntxd) { 
    430                 if (!_dma_alloc(di, DMA_TX)) 
    431                         goto fail; 
    432         } 
    433  
    434         /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ 
    435         if (nrxd) { 
    436                 if (!_dma_alloc(di, DMA_RX)) 
    437                         goto fail; 
    438         } 
    439  
    440         if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { 
    441                 DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", 
    442                            di->name, di->txdpa)); 
    443                 goto fail; 
    444         } 
    445         if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { 
    446                 DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", 
    447                            di->name, di->rxdpa)); 
    448                 goto fail; 
    449         } 
    450  
    451         DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " 
    452                    "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, 
    453                    di->dataoffsethigh, di->addrext)); 
    454  
    455         /* allocate tx packet pointer vector and DMA mapping vectors */ 
    456         if (ntxd) { 
    457  
    458                 size = ntxd * sizeof(osldma_t **); 
    459                 if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) 
    460                         goto fail; 
    461                 bzero((char*)di->txp_dmah, size); 
    462         }else 
    463                 di->txp_dmah = NULL; 
    464  
    465         /* allocate rx packet pointer vector and DMA mapping vectors */ 
    466         if (nrxd) { 
    467  
    468                 size = nrxd * sizeof(osldma_t **); 
    469                 if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) 
    470                         goto fail; 
    471                 bzero((char*)di->rxp_dmah, size); 
    472  
    473         } else 
    474                 di->rxp_dmah = NULL; 
    475  
    476         /* initialize opsvec of function pointers */ 
    477         di->hnddma.di_fn = DMA64_ENAB(di) ? dma64proc : dma32proc; 
    478  
    479         return ((hnddma_t *)di); 
     554      bzero ((char *) di->rxp, size); 
     555    } 
     556 
     557  /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ 
     558  if (ntxd) 
     559    { 
     560      if (!_dma_alloc (di, DMA_TX)) 
     561        goto fail; 
     562    } 
     563 
     564  /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ 
     565  if (nrxd) 
     566    { 
     567      if (!_dma_alloc (di, DMA_RX)) 
     568        goto fail; 
     569    } 
     570 
     571  if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) 
     572      && !di->addrext) 
     573    { 
     574      DMA_ERROR (("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", 
     575                  di->name, di->txdpa)); 
     576      goto fail; 
     577    } 
     578  if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) 
     579      && !di->addrext) 
     580    { 
     581      DMA_ERROR (("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", 
     582                  di->name, di->rxdpa)); 
     583      goto fail; 
     584    } 
     585 
     586  DMA_TRACE (("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext)); 
     587 
     588  /* allocate tx packet pointer vector and DMA mapping vectors */ 
     589  if (ntxd) 
     590    { 
     591 
     592      size = ntxd * sizeof (osldma_t **); 
     593      if ((di->txp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL) 
     594        goto fail; 
     595      bzero ((char *) di->txp_dmah, size); 
     596    } 
     597  else 
     598    di->txp_dmah = NULL; 
     599 
     600  /* allocate rx packet pointer vector and DMA mapping vectors */ 
     601  if (nrxd) 
     602    { 
     603 
     604      size = nrxd * sizeof (osldma_t **); 
     605      if ((di->rxp_dmah = (osldma_t **) MALLOC (osh, size)) == NULL) 
     606        goto fail; 
     607      bzero ((char *) di->rxp_dmah, size); 
     608 
     609    } 
     610  else 
     611    di->rxp_dmah = NULL; 
     612 
     613  /* initialize opsvec of function pointers */ 
     614  di->hnddma.di_fn = DMA64_ENAB (di) ? dma64proc : dma32proc; 
     615 
     616  return ((hnddma_t *) di); 
    480617 
    481618fail: 
    482         _dma_detach(di); 
    483         return (NULL); 
     619  _dma_detach (di); 
     620  return (NULL); 
    484621} 
    485622 
    486623/* init the tx or rx descriptor */ 
    487624static INLINE void 
    488 dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags, 
    489              uint32 bufcount) 
    490 { 
    491         /* dma32 uses 32 bits control to fit both flags and bufcounter */ 
    492         *flags = *flags | (bufcount & CTRL_BC_MASK); 
    493  
    494         if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    495                 W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); 
    496                 W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); 
    497         } else { 
    498                 /* address extension */ 
    499                 uint32 ae; 
    500                 ASSERT(di->addrext); 
    501                 ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    502                 pa &= ~PCI32ADDR_HIGH; 
    503  
    504                 *flags |= (ae << CTRL_AE_SHIFT); 
    505                 W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); 
    506                 W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); 
     625dma32_dd_upd (dma_info_t * di, dma32dd_t * ddring, ulong pa, uint outidx, 
     626              uint32 * flags, uint32 bufcount) 
     627{ 
     628  /* dma32 uses 32 bits control to fit both flags and bufcounter */ 
     629  *flags = *flags | (bufcount & CTRL_BC_MASK); 
     630 
     631  if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) 
     632    { 
     633      W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow)); 
     634      W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags)); 
     635    } 
     636  else 
     637    { 
     638      /* address extension */ 
     639      uint32 ae; 
     640      ASSERT (di->addrext); 
     641      ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
     642      pa &= ~PCI32ADDR_HIGH; 
     643 
     644      *flags |= (ae << CTRL_AE_SHIFT); 
     645      W_SM (&ddring[outidx].addr, BUS_SWAP32 (pa + di->dataoffsetlow)); 
     646      W_SM (&ddring[outidx].ctrl, BUS_SWAP32 (*flags)); 
     647    } 
     648} 
     649 
     650static INLINE void 
     651dma64_dd_upd (dma_info_t * di, dma64dd_t * ddring, ulong pa, uint outidx, 
     652              uint32 * flags, uint32 bufcount) 
     653{ 
     654  uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; 
     655 
     656  /* PCI bus with big(>1G) physical address, use address extension */ 
     657  if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) 
     658    { 
     659      W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow)); 
     660      W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh)); 
     661      W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags)); 
     662      W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2)); 
     663    } 
     664  else 
     665    { 
     666      /* address extension */ 
     667      uint32 ae; 
     668      ASSERT (di->addrext); 
     669 
     670      ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
     671      pa &= ~PCI32ADDR_HIGH; 
     672 
     673      ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; 
     674      W_SM (&ddring[outidx].addrlow, BUS_SWAP32 (pa + di->dataoffsetlow)); 
     675      W_SM (&ddring[outidx].addrhigh, BUS_SWAP32 (0 + di->dataoffsethigh)); 
     676      W_SM (&ddring[outidx].ctrl1, BUS_SWAP32 (*flags)); 
     677      W_SM (&ddring[outidx].ctrl2, BUS_SWAP32 (ctrl2)); 
     678    } 
     679} 
     680 
     681static bool 
     682_dma32_addrext (osl_t * osh, dma32regs_t * dma32regs) 
     683{ 
     684  uint32 w; 
     685 
     686  OR_REG (osh, &dma32regs->control, XC_AE); 
     687  w = R_REG (osh, &dma32regs->control); 
     688  AND_REG (osh, &dma32regs->control, ~XC_AE); 
     689  return ((w & XC_AE) == XC_AE); 
     690} 
     691 
     692static bool 
     693_dma_alloc (dma_info_t * di, uint direction) 
     694{ 
     695  if (DMA64_ENAB (di)) 
     696    { 
     697      return dma64_alloc (di, direction); 
     698    } 
     699  else 
     700    { 
     701      return dma32_alloc (di, direction); 
     702    } 
     703} 
     704 
     705/* !! may be called with core in reset */ 
     706static void 
     707_dma_detach (dma_info_t * di) 
     708{ 
     709  if (di == NULL) 
     710    return; 
     711 
     712  DMA_TRACE (("%s: dma_detach\n", di->name)); 
     713 
     714  /* shouldn't be here if descriptors are unreclaimed */ 
     715  ASSERT (di->txin == di->txout); 
     716  ASSERT (di->rxin == di->rxout); 
     717 
     718  /* free dma descriptor rings */ 
     719  if (DMA64_ENAB (di)) 
     720    { 
     721      if (di->txd64) 
     722        DMA_FREE_CONSISTENT (di->osh, 
     723                             ((int8 *) (uintptr) di->txd64 - di->txdalign), 
     724                             di->txdalloc, (di->txdpa - di->txdalign), 
     725                             &di->tx_dmah); 
     726      if (di->rxd64) 
     727        DMA_FREE_CONSISTENT (di->osh, 
     728                             ((int8 *) (uintptr) di->rxd64 - di->rxdalign), 
     729                             di->rxdalloc, (di->rxdpa - di->rxdalign), 
     730                             &di->rx_dmah); 
     731    } 
     732  else 
     733    { 
     734      if (di->txd32) 
     735        DMA_FREE_CONSISTENT (di->osh, 
     736                             ((int8 *) (uintptr) di->txd32 - di->txdalign), 
     737                             di->txdalloc, (di->txdpa - di->txdalign), 
     738                             &di->tx_dmah); 
     739      if (di->rxd32) 
     740        DMA_FREE_CONSISTENT (di->osh, 
     741                             ((int8 *) (uintptr) di->rxd32 - di->rxdalign), 
     742                             di->rxdalloc, (di->rxdpa - di->rxdalign), 
     743                             &di->rx_dmah); 
     744    } 
     745 
     746  /* free packet pointer vectors */ 
     747  if (di->txp) 
     748    MFREE (di->osh, (void *) di->txp, (di->ntxd * sizeof (void *))); 
     749  if (di->rxp) 
     750    MFREE (di->osh, (void *) di->rxp, (di->nrxd * sizeof (void *))); 
     751 
     752  /* free tx packet DMA handles */ 
     753  if (di->txp_dmah) 
     754    MFREE (di->osh, (void *) di->txp_dmah, di->ntxd * sizeof (osldma_t **)); 
     755 
     756  /* free rx packet DMA handles */ 
     757  if (di->rxp_dmah) 
     758    MFREE (di->osh, (void *) di->rxp_dmah, di->nrxd * sizeof (osldma_t **)); 
     759 
     760  /* free our private info structure */ 
     761  MFREE (di->osh, (void *) di, sizeof (dma_info_t)); 
     762 
     763} 
     764 
     765/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ 
     766static bool 
     767_dma_isaddrext (dma_info_t * di) 
     768{ 
     769  if (DMA64_ENAB (di)) 
     770    { 
     771      /* DMA64 supports full 32 bits or 64 bits. AE is always valid */ 
     772 
     773      /* not all tx or rx channel are available */ 
     774      if (di->d64txregs != NULL) 
     775        { 
     776          if (!_dma64_addrext (di->osh, di->d64txregs)) 
     777            { 
     778              DMA_ERROR (("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name)); 
     779              ASSERT (0); 
     780            } 
     781          return TRUE; 
    507782        } 
    508 } 
    509  
    510 static INLINE void 
    511 dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, 
    512              uint32 bufcount) 
    513 { 
    514         uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; 
    515  
    516         /* PCI bus with big(>1G) physical address, use address extension */ 
    517         if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    518                 W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow)); 
    519                 W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh)); 
    520                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); 
    521                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); 
    522         } else { 
    523                 /* address extension */ 
    524                 uint32 ae; 
    525                 ASSERT(di->addrext); 
    526  
    527                 ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    528                 pa &= ~PCI32ADDR_HIGH; 
    529  
    530                 ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; 
    531                 W_SM(&ddring[outidx].addrlow, BUS_SWAP32(pa + di->dataoffsetlow)); 
    532                 W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh)); 
    533                 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); 
    534                 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); 
     783      else if (di->d64rxregs != NULL) 
     784        { 
     785          if (!_dma64_addrext (di->osh, di->d64rxregs)) 
     786            { 
     787              DMA_ERROR (("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name)); 
     788              ASSERT (0); 
     789            } 
     790          return TRUE; 
    535791        } 
    536 } 
    537  
    538 static bool 
    539 _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) 
    540 { 
    541         uint32 w; 
    542  
    543         OR_REG(osh, &dma32regs->control, XC_AE); 
    544         w = R_REG(osh, &dma32regs->control); 
    545         AND_REG(osh, &dma32regs->control, ~XC_AE); 
    546         return ((w & XC_AE) == XC_AE); 
    547 } 
    548  
    549 static bool 
    550 _dma_alloc(dma_info_t *di, uint direction) 
    551 { 
    552         if (DMA64_ENAB(di)) { 
    553                 return dma64_alloc(di, direction); 
    554         } else { 
    555                 return dma32_alloc(di, direction); 
     792      return FALSE; 
     793    } 
     794  else if (di->d32txregs) 
     795    return (_dma32_addrext (di->osh, di->d32txregs)); 
     796  else if (di->d32rxregs) 
     797    return (_dma32_addrext (di->osh, di->d32rxregs)); 
     798  return FALSE; 
     799} 
     800 
     801/* initialize descriptor table base address */ 
     802static void 
     803_dma_ddtable_init (dma_info_t * di, uint direction, ulong pa) 
     804{ 
     805  if (DMA64_ENAB (di)) 
     806    { 
     807 
     808      if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) 
     809        { 
     810          if (direction == DMA_TX) 
     811            { 
     812              W_REG (di->osh, &di->d64txregs->addrlow, 
     813                     (pa + di->ddoffsetlow)); 
     814              W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); 
     815            } 
     816          else 
     817            { 
     818              W_REG (di->osh, &di->d64rxregs->addrlow, 
     819                     (pa + di->ddoffsetlow)); 
     820              W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); 
     821            } 
    556822        } 
    557 } 
    558  
    559 /* !! may be called with core in reset */ 
    560 static void 
    561 _dma_detach(dma_info_t *di) 
    562 { 
    563         if (di == NULL) 
    564                 return; 
    565  
    566         DMA_TRACE(("%s: dma_detach\n", di->name)); 
    567  
    568         /* shouldn't be here if descriptors are unreclaimed */ 
    569         ASSERT(di->txin == di->txout); 
    570         ASSERT(di->rxin == di->rxout); 
    571  
    572         /* free dma descriptor rings */ 
    573         if (DMA64_ENAB(di)) { 
    574                 if (di->txd64) 
    575                         DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd64 - di->txdalign), 
    576                                             di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); 
    577                 if (di->rxd64) 
    578                         DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd64 - di->rxdalign), 
    579                                             di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); 
    580         } else { 
    581                 if (di->txd32) 
    582                         DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->txd32 - di->txdalign), 
    583                                             di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); 
    584                 if (di->rxd32) 
    585                         DMA_FREE_CONSISTENT(di->osh, ((int8*)(uintptr)di->rxd32 - di->rxdalign), 
    586                                             di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); 
     823      else 
     824        { 
     825          /* DMA64 32bits address extension */ 
     826          uint32 ae; 
     827          ASSERT (di->addrext); 
     828 
     829          /* shift the high bit(s) from pa to ae */ 
     830          ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
     831          pa &= ~PCI32ADDR_HIGH; 
     832 
     833          if (direction == DMA_TX) 
     834            { 
     835              W_REG (di->osh, &di->d64txregs->addrlow, 
     836                     (pa + di->ddoffsetlow)); 
     837              W_REG (di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); 
     838              SET_REG (di->osh, &di->d64txregs->control, D64_XC_AE, 
     839                       (ae << D64_XC_AE_SHIFT)); 
     840            } 
     841          else 
     842            { 
     843              W_REG (di->osh, &di->d64rxregs->addrlow, 
     844                     (pa + di->ddoffsetlow)); 
     845              W_REG (di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); 
     846              SET_REG (di->osh, &di->d64rxregs->control, D64_RC_AE, 
     847                       (ae << D64_RC_AE_SHIFT)); 
     848            } 
    587849        } 
    588850 
    589         /* free packet pointer vectors */ 
    590         if (di->txp) 
    591                 MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); 
    592         if (di->rxp) 
    593                 MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); 
    594  
    595         /* free tx packet DMA handles */ 
    596         if (di->txp_dmah) 
    597                 MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **)); 
    598  
    599         /* free rx packet DMA handles */ 
    600         if (di->rxp_dmah) 
    601                 MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **)); 
    602  
    603         /* free our private info structure */ 
    604         MFREE(di->osh, (void *)di, sizeof(dma_info_t)); 
    605  
    606 } 
    607  
    608 /* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ 
    609 static bool 
    610 _dma_isaddrext(dma_info_t *di) 
    611 { 
    612         if (DMA64_ENAB(di)) { 
    613                 /* DMA64 supports full 32 bits or 64 bits. AE is always valid */ 
    614  
    615                 /* not all tx or rx channel are available */ 
    616                 if (di->d64txregs != NULL) { 
    617                         if (!_dma64_addrext(di->osh, di->d64txregs)) { 
    618                                 DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", 
    619                                         di->name)); 
    620                                 ASSERT(0); 
    621                         } 
    622                         return TRUE; 
    623                 } else if (di->d64rxregs != NULL) { 
    624                         if (!_dma64_addrext(di->osh, di->d64rxregs)) { 
    625                                 DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", 
    626                                         di->name)); 
    627                                 ASSERT(0); 
    628                         } 
    629                         return TRUE; 
    630                 } 
    631                 return FALSE; 
    632         } else if (di->d32txregs) 
    633                 return (_dma32_addrext(di->osh, di->d32txregs)); 
    634         else if (di->d32rxregs) 
    635                 return (_dma32_addrext(di->osh, di->d32rxregs)); 
    636         return FALSE; 
    637 } 
    638  
    639 /* initialize descriptor table base address */ 
    640 static void 
    641 _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) 
    642 { 
    643         if (DMA64_ENAB(di)) { 
    644  
    645                 if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    646                         if (direction == DMA_TX) { 
    647                                 W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow)); 
    648                                 W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); 
    649                         } else { 
    650                                 W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow)); 
    651                                 W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); 
    652                         } 
    653                 } else { 
    654                         /* DMA64 32bits address extension */ 
    655                         uint32 ae; 
    656                         ASSERT(di->addrext); 
    657  
    658                         /* shift the high bit(s) from pa to ae */ 
    659                         ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    660                         pa &= ~PCI32ADDR_HIGH; 
    661  
    662                         if (direction == DMA_TX) { 
    663                                 W_REG(di->osh, &di->d64txregs->addrlow, (pa + di->ddoffsetlow)); 
    664                                 W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); 
    665                                 SET_REG(di->osh, &di->d64txregs->control, D64_XC_AE, 
    666                                         (ae << D64_XC_AE_SHIFT)); 
    667                         } else { 
    668                                 W_REG(di->osh, &di->d64rxregs->addrlow, (pa + di->ddoffsetlow)); 
    669                                 W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); 
    670                                 SET_REG(di->osh, &di->d64rxregs->control, D64_RC_AE, 
    671                                         (ae << D64_RC_AE_SHIFT)); 
    672                         } 
    673                 } 
    674  
    675         } else { 
    676                 if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { 
    677                         if (direction == DMA_TX) 
    678                                 W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
    679                         else 
    680                                 W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
    681                 } else { 
    682                         /* dma32 address extension */ 
    683                         uint32 ae; 
    684                         ASSERT(di->addrext); 
    685  
    686                         /* shift the high bit(s) from pa to ae */ 
    687                         ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
    688                         pa &= ~PCI32ADDR_HIGH; 
    689  
    690                         if (direction == DMA_TX) { 
    691                                 W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
    692                                 SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <<XC_AE_SHIFT); 
    693                         } else { 
    694                                 W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
    695                                 SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <<RC_AE_SHIFT); 
    696                         } 
    697                 } 
     851    } 
     852  else 
     853    { 
     854      if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) 
     855        { 
     856          if (direction == DMA_TX) 
     857            W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
     858          else 
     859            W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
    698860        } 
    699 } 
    700  
    701 static void 
    702 _dma_fifoloopbackenable(dma_info_t *di) 
    703 { 
    704         DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); 
    705         if (DMA64_ENAB(di)) 
    706                 OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); 
    707         else 
    708                 OR_REG(di->osh, &di->d32txregs->control, XC_LE); 
    709 } 
    710  
    711 static void 
    712 _dma_rxinit(dma_info_t *di) 
    713 { 
    714         DMA_TRACE(("%s: dma_rxinit\n", di->name)); 
    715  
    716         if (di->nrxd == 0) 
    717                 return; 
    718  
    719         di->rxin = di->rxout = 0; 
    720  
    721         /* clear rx descriptor ring */ 
    722         if (DMA64_ENAB(di)) { 
    723                 BZERO_SM((void *)(uintptr)di->rxd64, (di->nrxd * sizeof(dma64dd_t))); 
    724                 _dma_rxenable(di); 
    725                 _dma_ddtable_init(di, DMA_RX, di->rxdpa); 
    726         } else { 
    727                 BZERO_SM((void *)(uintptr)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); 
    728                 _dma_rxenable(di); 
    729                 _dma_ddtable_init(di, DMA_RX, di->rxdpa); 
     861      else 
     862        { 
     863          /* dma32 address extension */ 
     864          uint32 ae; 
     865          ASSERT (di->addrext); 
     866 
     867          /* shift the high bit(s) from pa to ae */ 
     868          ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; 
     869          pa &= ~PCI32ADDR_HIGH; 
     870 
     871          if (direction == DMA_TX) 
     872            { 
     873              W_REG (di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); 
     874              SET_REG (di->osh, &di->d32txregs->control, XC_AE, 
     875                       ae << XC_AE_SHIFT); 
     876            } 
     877          else 
     878            { 
     879              W_REG (di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); 
     880              SET_REG (di->osh, &di->d32rxregs->control, RC_AE, 
     881                       ae << RC_AE_SHIFT); 
     882            } 
    730883        } 
    731 } 
    732  
    733 static void 
    734 _dma_rxenable(dma_info_t *di) 
    735 { 
    736         DMA_TRACE(("%s: dma_rxenable\n", di->name)); 
    737  
    738         if (DMA64_ENAB(di)) 
    739                 W_REG(di->osh, &di->d64rxregs->control, 
    740                       ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); 
    741         else 
    742                 W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); 
     884    } 
     885} 
     886 
     887static void 
     888_dma_fifoloopbackenable (dma_info_t * di) 
     889{ 
     890  DMA_TRACE (("%s: dma_fifoloopbackenable\n", di->name)); 
     891  if (DMA64_ENAB (di)) 
     892    OR_REG (di->osh, &di->d64txregs->control, D64_XC_LE); 
     893  else 
     894    OR_REG (di->osh, &di->d32txregs->control, XC_LE); 
     895} 
     896 
     897static void 
     898_dma_rxinit (dma_info_t * di) 
     899{ 
     900  DMA_TRACE (("%s: dma_rxinit\n", di->name)); 
     901 
     902  if (di->nrxd == 0) 
     903    return; 
     904 
     905  di->rxin = di->rxout = 0; 
     906 
     907  /* clear rx descriptor ring */ 
     908  if (DMA64_ENAB (di)) 
     909    BZERO_SM ((void *) (uintptr) di->rxd64, (di->nrxd * sizeof (dma64dd_t))); 
     910  else 
     911    BZERO_SM ((void *) (uintptr) di->rxd32, (di->nrxd * sizeof (dma32dd_t))); 
     912 
     913  _dma_rxenable (di); 
     914  _dma_ddtable_init (di, DMA_RX, di->rxdpa); 
     915} 
     916 
     917static void 
     918_dma_rxenable (dma_info_t * di) 
     919{ 
     920  DMA_TRACE (("%s: dma_rxenable\n", di->name)); 
     921 
     922  if (DMA64_ENAB (di)) 
     923    W_REG (di->osh, &di->d64rxregs->control, 
     924           ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); 
     925  else 
     926    W_REG (di->osh, &di->d32rxregs->control, 
     927           ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); 
    743928} 
    744929 
     
    747932 */ 
    748933static void * 
    749 _dma_rx(dma_info_t *di) 
    750 { 
    751         void *p; 
    752         uint len; 
    753         int skiplen = 0; 
    754  
    755         while ((p = _dma_getnextrxp(di, FALSE))) { 
    756                 /* skip giant packets which span multiple rx descriptors */ 
    757                 if (skiplen > 0) { 
    758                         skiplen -= di->rxbufsize; 
    759                         if (skiplen < 0) 
    760                                 skiplen = 0; 
    761                         PKTFREE(di->osh, p, FALSE); 
    762                         continue; 
    763                 } 
    764  
    765                 len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); 
    766                 DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); 
    767  
    768                 /* bad frame length check */ 
    769                 if (len > (di->rxbufsize - di->rxoffset)) { 
    770                         DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); 
    771                         if (len > 0) 
    772                                 skiplen = len - (di->rxbufsize - di->rxoffset); 
    773                         PKTFREE(di->osh, p, FALSE); 
    774                         di->hnddma.rxgiants++; 
    775                         continue; 
    776                 } 
    777  
    778                 /* set actual length */ 
    779                 PKTSETLEN(di->osh, p, (di->rxoffset + len)); 
    780  
    781                 break; 
     934_dma_rx (dma_info_t * di) 
     935{ 
     936  void *p; 
     937  uint len; 
     938  int skiplen = 0; 
     939 
     940  while ((p = _dma_getnextrxp (di, FALSE))) 
     941    { 
     942      /* skip giant packets which span multiple rx descriptors */ 
     943      if (skiplen > 0) 
     944        { 
     945          skiplen -= di->rxbufsize; 
     946          if (skiplen < 0) 
     947            skiplen = 0; 
     948          PKTFREE (di->osh, p, FALSE); 
     949          continue; 
    782950        } 
    783951 
    784         return (p); 
     952      len = ltoh16 (*(uint16 *) (PKTDATA (di->osh, p))); 
     953      DMA_TRACE (("%s: dma_rx len %d\n", di->name, len)); 
     954 
     955      /* bad frame length check */ 
     956      if (len > (di->rxbufsize - di->rxoffset)) 
     957        { 
     958          DMA_ERROR (("%s: dma_rx: bad frame length (%d)\n", di->name, len)); 
     959          if (len > 0) 
     960            skiplen = len - (di->rxbufsize - di->rxoffset); 
     961          PKTFREE (di->osh, p, FALSE); 
     962          di->hnddma.rxgiants++; 
     963          continue; 
     964        } 
     965 
     966      /* set actual length */ 
     967      PKTSETLEN (di->osh, p, (di->rxoffset + len)); 
     968 
     969      break; 
     970    } 
     971 
     972  return (p); 
    785973} 
    786974 
    787975/* post receive buffers */ 
    788976static void 
    789 _dma_rxfill(dma_info_t *di) 
    790 { 
    791         void *p; 
    792         uint rxin, rxout; 
    793         uint32 flags = 0; 
    794         uint n; 
    795         uint i; 
    796         uint32 pa; 
    797         uint extra_offset = 0; 
    798  
    799         /* 
    800          * Determine how many receive buffers we're lacking 
    801          * from the full complement, allocate, initialize, 
    802          * and post them, then update the chip rx lastdscr. 
    803          */ 
    804  
    805         rxin = di->rxin; 
    806         rxout = di->rxout; 
    807  
    808         n = di->nrxpost - NRXDACTIVE(rxin, rxout); 
    809  
    810         DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); 
    811  
    812         if (di->rxbufsize > BCMEXTRAHDROOM) 
    813                 extra_offset = BCMEXTRAHDROOM; 
    814  
    815         for (i = 0; i < n; i++) { 
    816                 /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the 
    817                    size to be allocated 
    818                 */ 
    819                 if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset, 
    820                                 FALSE)) == NULL) { 
    821                         DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); 
    822                         di->hnddma.rxnobuf++; 
    823                         break; 
    824                 } 
    825                 /* reserve an extra headroom, if applicable */ 
    826                 if (extra_offset) 
    827                         PKTPULL(di->osh, p, extra_offset); 
    828  
    829                 /* Do a cached write instead of uncached write since DMA_MAP 
    830                  * will flush the cache. 
    831                  */ 
    832                 *(uint32*)(PKTDATA(di->osh, p)) = 0; 
    833  
    834                 pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), 
    835                                       di->rxbufsize, DMA_RX, p); 
    836  
    837                 ASSERT(ISALIGNED(pa, 4)); 
    838  
    839                 /* save the free packet pointer */ 
    840                 ASSERT(di->rxp[rxout] == NULL); 
    841                 di->rxp[rxout] = p; 
    842  
    843                 /* reset flags for each descriptor */ 
    844                 flags = 0; 
    845                 if (DMA64_ENAB(di)) { 
    846                         if (rxout == (di->nrxd - 1)) 
    847                                 flags = D64_CTRL1_EOT; 
    848  
    849                         dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize); 
    850                 } else { 
    851                         if (rxout == (di->nrxd - 1)) 
    852                                 flags = CTRL_EOT; 
    853  
    854                         dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); 
    855                 } 
    856                 rxout = NEXTRXD(rxout); 
     977_dma_rxfill (dma_info_t * di) 
     978{ 
     979  void *p; 
     980  uint rxin, rxout; 
     981  uint32 flags = 0; 
     982  uint n; 
     983  uint i; 
     984  uint32 pa; 
     985  uint extra_offset = 0; 
     986 
     987  /* 
     988   * Determine how many receive buffers we're lacking 
     989   * from the full complement, allocate, initialize, 
     990   * and post them, then update the chip rx lastdscr. 
     991   */ 
     992 
     993  rxin = di->rxin; 
     994  rxout = di->rxout; 
     995 
     996  n = di->nrxpost - NRXDACTIVE (rxin, rxout); 
     997 
     998  DMA_TRACE (("%s: dma_rxfill: post %d\n", di->name, n)); 
     999 
     1000  if (di->rxbufsize > BCMEXTRAHDROOM) 
     1001    extra_offset = BCMEXTRAHDROOM; 
     1002 
     1003  for (i = 0; i < n; i++) 
     1004    { 
     1005      /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the 
     1006         size to be allocated 
     1007       */ 
     1008      if ((p = PKTGET (di->osh, di->rxbufsize + extra_offset, FALSE)) == NULL) 
     1009        { 
     1010          DMA_ERROR (("%s: dma_rxfill: out of rxbufs\n", di->name)); 
     1011          di->hnddma.rxnobuf++; 
     1012          break; 
    8571013        } 
    858  
    859         di->rxout = rxout; 
    860  
    861         /* update the chip lastdscr pointer */ 
    862         if (DMA64_ENAB(di)) { 
    863                 W_REG(di->osh, &di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); 
    864         } else { 
    865                 W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); 
     1014      /* reserve an extra headroom, if applicable */ 
     1015      if (extra_offset) 
     1016        PKTPULL (di->osh, p, extra_offset); 
     1017 
     1018      /* Do a cached write instead of uncached write since DMA_MAP 
     1019       * will flush the cache. 
     1020       */ 
     1021      *(uint32 *) (PKTDATA (di->osh, p)) = 0; 
     1022 
     1023      pa = (uint32) DMA_MAP (di->osh, PKTDATA (di->osh, p), 
     1024                             di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]); 
     1025 
     1026      ASSERT (ISALIGNED (pa, 4)); 
     1027 
     1028      /* save the free packet pointer */ 
     1029      ASSERT (di->rxp[rxout] == NULL); 
     1030      di->rxp[rxout] = p; 
     1031 
     1032      /* reset flags for each descriptor */ 
     1033      flags = 0; 
     1034      if (DMA64_ENAB (di)) 
     1035        { 
     1036          if (rxout == (di->nrxd - 1)) 
     1037            flags = D64_CTRL1_EOT; 
     1038 
     1039          dma64_dd_upd (di, di->rxd64, pa, rxout, &flags, di->rxbufsize); 
    8661040        } 
     1041      else 
     1042        { 
     1043          if (rxout == (di->nrxd - 1)) 
     1044            flags = CTRL_EOT; 
     1045 
     1046          dma32_dd_upd (di, di->rxd32, pa, rxout, &flags, di->rxbufsize); 
     1047        } 
     1048      rxout = NEXTRXD (rxout); 
     1049    } 
     1050 
     1051  di->rxout = rxout; 
     1052 
     1053  /* update the chip lastdscr pointer */ 
     1054  if (DMA64_ENAB (di)) 
     1055    { 
     1056      W_REG (di->osh, &di->d64rxregs->ptr, I2B (rxout, dma64dd_t)); 
     1057    } 
     1058  else 
     1059    { 
     1060      W_REG (di->osh, &di->d32rxregs->ptr, I2B (rxout, dma32dd_t)); 
     1061    } 
    8671062} 
    8681063 
    8691064/* like getnexttxp but no reclaim */ 
    8701065static void * 
    871 _dma_peeknexttxp(dma_info_t *di) 
    872 { 
    873         uint end, i; 
    874  
    875         if (di->ntxd == 0) 
    876                 return (NULL); 
    877  
    878         if (DMA64_ENAB(di)) { 
    879                 end = B2I(R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); 
    880         } else { 
    881                 end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); 
    882         } 
    883  
    884         for (i = di->txin; i != end; i = NEXTTXD(i)) 
    885                 if (di->txp[i]) 
    886                         return (di->txp[i]); 
    887  
    888         return (NULL); 
    889 } 
    890  
    891 static void 
    892 _dma_rxreclaim(dma_info_t *di) 
    893 { 
    894         void *p; 
    895  
    896         /* "unused local" warning suppression for OSLs that 
    897          * define PKTFREE() without using the di->osh arg 
    898          */ 
    899         di = di; 
    900  
    901         DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); 
    902  
    903         while ((p = _dma_getnextrxp(di, TRUE))) 
    904                 PKTFREE(di->osh, p, FALSE); 
     1066_dma_peeknexttxp (dma_info_t * di) 
     1067{ 
     1068  uint end, i; 
     1069 
     1070  if (di->ntxd == 0) 
     1071    return (NULL); 
     1072 
     1073  if (DMA64_ENAB (di)) 
     1074    { 
     1075      end = 
     1076        B2I (R_REG (di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK, 
     1077             dma64dd_t); 
     1078    } 
     1079  else 
     1080    { 
     1081      end = 
     1082        B2I (R_REG (di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); 
     1083    } 
     1084 
     1085  for (i = di->txin; i != end; i = NEXTTXD (i)) 
     1086    if (di->txp[i]) 
     1087      return (di->txp[i]); 
     1088 
     1089  return (NULL); 
     1090} 
     1091 
     1092static void 
     1093_dma_rxreclaim (dma_info_t * di) 
     1094{ 
     1095  void *p; 
     1096 
     1097  /* "unused local" warning suppression for OSLs that 
     1098   * define PKTFREE() without using the di->osh arg 
     1099   */ 
     1100  di = di; 
     1101 
     1102  DMA_TRACE (("%s: dma_rxreclaim\n", di->name)); 
     1103 
     1104  while ((p = _dma_getnextrxp (di, TRUE))) 
     1105    PKTFREE (di->osh, p, FALSE); 
    9051106} 
    9061107 
    9071108static void * 
    908 _dma_getnextrxp(dma_info_t *di, bool forceall) 
    909 { 
    910         if (di->nrxd == 0) 
    911                 return (NULL); 
    912  
    913         if (DMA64_ENAB(di)) { 
    914                 return dma64_getnextrxp(di, forceall); 
    915         } else { 
    916                 return dma32_getnextrxp(di, forceall); 
    917         } 
    918 } 
    919  
    920 static void 
    921 _dma_txblock(dma_info_t *di) 
    922 { 
    923         di->hnddma.txavail = 0; 
    924 } 
    925  
    926 static void 
    927 _dma_txunblock(dma_info_t *di) 
    928 { 
    929         di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; 
     1109_dma_getnextrxp (dma_info_t * di, bool forceall) 
     1110{ 
     1111  if (di->nrxd == 0) 
     1112    return (NULL); 
     1113 
     1114  if (DMA64_ENAB (di)) 
     1115    { 
     1116      return dma64_getnextrxp (di, forceall); 
     1117    } 
     1118  else 
     1119    { 
     1120      return dma32_getnextrxp (di, forceall); 
     1121    } 
     1122} 
     1123 
     1124static void 
     1125_dma_txblock (dma_info_t * di) 
     1126{ 
     1127  di->hnddma.txavail = 0; 
     1128} 
     1129 
     1130static void 
     1131_dma_txunblock (dma_info_t * di) 
     1132{ 
     1133  di->hnddma.txavail = di->ntxd - NTXDACTIVE (di->txin, di->txout) - 1; 
    9301134} 
    9311135 
    9321136static uint 
    933 _dma_txactive(dma_info_t *di) 
    934 { 
    935         return (NTXDACTIVE(di->txin, di->txout)); 
    936 } 
    937  
    938 static void 
    939 _dma_counterreset(dma_info_t *di) 
    940 { 
    941         /* reset all software counter */ 
    942         di->hnddma.rxgiants = 0; 
    943         di->hnddma.rxnobuf = 0; 
    944         di->hnddma.txnobuf = 0; 
     1137_dma_txactive (dma_info_t * di) 
     1138{ 
     1139  return (NTXDACTIVE (di->txin, di->txout)); 
     1140} 
     1141 
     1142static void 
     1143_dma_counterreset (dma_info_t * di) 
     1144{ 
     1145  /* reset all software counter */ 
     1146  di->hnddma.rxgiants = 0; 
     1147  di->hnddma.rxnobuf = 0; 
     1148  di->hnddma.txnobuf = 0; 
    9451149} 
    9461150 
    9471151/* get the address of the var in order to change later */ 
    9481152static uintptr 
    949 _dma_getvar(dma_info_t *di, const char *name) 
    950 { 
    951         if (!strcmp(name, "&txavail")) 
    952                 return ((uintptr) &(di->hnddma.txavail)); 
    953         else { 
    954                 ASSERT(0); 
     1153_dma_getvar (dma_info_t * di, const char *name) 
     1154{ 
     1155  if (!strcmp (name, "&txavail")) 
     1156    return ((uintptr) & (di->hnddma.txavail)); 
     1157  else 
     1158    { 
     1159      ASSERT (0); 
     1160    } 
     1161  return (0); 
     1162} 
     1163 
     1164void 
     1165dma_txpioloopback (osl_t * osh, dma32regs_t * regs) 
     1166{ 
     1167  OR_REG (osh, &regs->control, XC_LE); 
     1168} 
     1169 
     1170#ifdef BCMDBG 
     1171static void 
     1172dma32_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma32dd_t * ring, 
     1173                uint start, uint end, uint max_num) 
     1174{ 
     1175  uint i; 
     1176 
     1177  for (i = start; i != end; i = XXD ((i + 1), max_num)) 
     1178    { 
     1179      /* in the format of high->low 8 bytes */ 
     1180      bcm_bprintf (b, "ring index %d: 0x%x %x\n", i, ring[i].addr, 
     1181                   ring[i].ctrl); 
     1182    } 
     1183} 
     1184 
     1185static void 
     1186dma32_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1187{ 
     1188  if (di->ntxd == 0) 
     1189    return; 
     1190 
     1191  bcm_bprintf (b, "DMA32: txd32 %p txdpa 0x%lx txp %p txin %d txout %d " 
     1192               "txavail %d\n", di->txd32, di->txdpa, di->txp, di->txin, 
     1193               di->txout, di->hnddma.txavail); 
     1194 
     1195  bcm_bprintf (b, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n", 
     1196               R_REG (di->osh, &di->d32txregs->control), 
     1197               R_REG (di->osh, &di->d32txregs->addr), 
     1198               R_REG (di->osh, &di->d32txregs->ptr), 
     1199               R_REG (di->osh, &di->d32txregs->status)); 
     1200 
     1201  if (dumpring && di->txd32) 
     1202    dma32_dumpring (di, b, di->txd32, di->txin, di->txout, di->ntxd); 
     1203} 
     1204 
     1205static void 
     1206dma32_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1207{ 
     1208  if (di->nrxd == 0) 
     1209    return; 
     1210 
     1211  bcm_bprintf (b, "DMA32: rxd32 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n", 
     1212               di->rxd32, di->rxdpa, di->rxp, di->rxin, di->rxout); 
     1213 
     1214  bcm_bprintf (b, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n", 
     1215               R_REG (di->osh, &di->d32rxregs->control), 
     1216               R_REG (di->osh, &di->d32rxregs->addr), 
     1217               R_REG (di->osh, &di->d32rxregs->ptr), 
     1218               R_REG (di->osh, &di->d32rxregs->status)); 
     1219  if (di->rxd32 && dumpring) 
     1220    dma32_dumpring (di, b, di->rxd32, di->rxin, di->rxout, di->nrxd); 
     1221} 
     1222 
     1223static void 
     1224dma32_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1225{ 
     1226  dma32_dumptx (di, b, dumpring); 
     1227  dma32_dumprx (di, b, dumpring); 
     1228} 
     1229 
     1230static void 
     1231dma64_dumpring (dma_info_t * di, struct bcmstrbuf *b, dma64dd_t * ring, 
     1232                uint start, uint end, uint max_num) 
     1233{ 
     1234  uint i; 
     1235 
     1236  for (i = start; i != end; i = XXD ((i + 1), max_num)) 
     1237    { 
     1238      /* in the format of high->low 16 bytes */ 
     1239      bcm_bprintf (b, "ring index %d: 0x%x %x %x %x\n", 
     1240                   i, ring[i].addrhigh, ring[i].addrlow, ring[i].ctrl2, 
     1241                   ring[i].ctrl1); 
     1242    } 
     1243} 
     1244 
     1245static void 
     1246dma64_dumptx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1247{ 
     1248  if (di->ntxd == 0) 
     1249    return; 
     1250 
     1251  bcm_bprintf (b, "DMA64: txd64 %p txdpa 0x%lx txp %p txin %d txout %d " 
     1252               "txavail %d\n", di->txd64, di->txdpa, di->txp, di->txin, 
     1253               di->txout, di->hnddma.txavail); 
     1254 
     1255  bcm_bprintf (b, "xmtcontrol 0x%x xmtaddrlow 0x%x xmtaddrhigh 0x%x " 
     1256               "xmtptr 0x%x xmtstatus0 0x%x xmtstatus1 0x%x\n", 
     1257               R_REG (di->osh, &di->d64txregs->control), 
     1258               R_REG (di->osh, &di->d64txregs->addrlow), 
     1259               R_REG (di->osh, &di->d64txregs->addrhigh), 
     1260               R_REG (di->osh, &di->d64txregs->ptr), 
     1261               R_REG (di->osh, &di->d64txregs->status0), 
     1262               R_REG (di->osh, &di->d64txregs->status1)); 
     1263 
     1264  if (dumpring && di->txd64) 
     1265    { 
     1266      dma64_dumpring (di, b, di->txd64, di->txin, di->txout, di->ntxd); 
     1267    } 
     1268} 
     1269 
     1270static void 
     1271dma64_dumprx (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1272{ 
     1273  if (di->nrxd == 0) 
     1274    return; 
     1275 
     1276  bcm_bprintf (b, "DMA64: rxd64 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n", 
     1277               di->rxd64, di->rxdpa, di->rxp, di->rxin, di->rxout); 
     1278 
     1279  bcm_bprintf (b, "rcvcontrol 0x%x rcvaddrlow 0x%x rcvaddrhigh 0x%x rcvptr " 
     1280               "0x%x rcvstatus0 0x%x rcvstatus1 0x%x\n", 
     1281               R_REG (di->osh, &di->d64rxregs->control), 
     1282               R_REG (di->osh, &di->d64rxregs->addrlow), 
     1283               R_REG (di->osh, &di->d64rxregs->addrhigh), 
     1284               R_REG (di->osh, &di->d64rxregs->ptr), 
     1285               R_REG (di->osh, &di->d64rxregs->status0), 
     1286               R_REG (di->osh, &di->d64rxregs->status1)); 
     1287  if (di->rxd64 && dumpring) 
     1288    { 
     1289      dma64_dumpring (di, b, di->rxd64, di->rxin, di->rxout, di->nrxd); 
     1290    } 
     1291} 
     1292 
     1293static void 
     1294dma64_dump (dma_info_t * di, struct bcmstrbuf *b, bool dumpring) 
     1295{ 
     1296  dma64_dumptx (di, b, dumpring); 
     1297  dma64_dumprx (di, b, dumpring); 
     1298} 
     1299 
     1300#endif /* BCMDBG */ 
     1301 
     1302 
     1303/* 32 bits DMA functions */ 
     1304static void 
     1305dma32_txinit (dma_info_t * di) 
     1306{ 
     1307  DMA_TRACE (("%s: dma_txinit\n", di->name)); 
     1308 
     1309  if (di->ntxd == 0) 
     1310    return; 
     1311 
     1312  di->txin = di->txout = 0; 
     1313  di->hnddma.txavail = di->ntxd - 1; 
     1314 
     1315  /* clear tx descriptor ring */ 
     1316  BZERO_SM ((void *) (uintptr) di->txd32, (di->ntxd * sizeof (dma32dd_t))); 
     1317  W_REG (di->osh, &di->d32txregs->control, XC_XE); 
     1318  _dma_ddtable_init (di, DMA_TX, di->txdpa); 
     1319} 
     1320 
     1321static bool 
     1322dma32_txenabled (dma_info_t * di) 
     1323{ 
     1324  uint32 xc; 
     1325 
     1326  /* If the chip is dead, it is not enabled :-) */ 
     1327  xc = R_REG (di->osh, &di->d32txregs->control); 
     1328  return ((xc != 0xffffffff) && (xc & XC_XE)); 
     1329} 
     1330 
     1331static void 
     1332dma32_txsuspend (dma_info_t * di) 
     1333{ 
     1334  DMA_TRACE (("%s: dma_txsuspend\n", di->name)); 
     1335 
     1336  if (di->ntxd == 0) 
     1337    return; 
     1338 
     1339  OR_REG (di->osh, &di->d32txregs->control, XC_SE); 
     1340} 
     1341 
     1342static void 
     1343dma32_txresume (dma_info_t * di) 
     1344{ 
     1345  DMA_TRACE (("%s: dma_txresume\n", di->name)); 
     1346 
     1347  if (di->ntxd == 0) 
     1348    return; 
     1349 
     1350  AND_REG (di->osh, &di->d32txregs->control, ~XC_SE); 
     1351} 
     1352 
     1353static bool 
     1354dma32_txsuspended (dma_info_t * di) 
     1355{ 
     1356  return (di->ntxd == 0) 
     1357    || ((R_REG (di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); 
     1358} 
     1359 
     1360static void 
     1361dma32_txreclaim (dma_info_t * di, bool forceall) 
     1362{ 
     1363  void *p; 
     1364 
     1365  DMA_TRACE (("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); 
     1366 
     1367  while ((p = dma32_getnexttxp (di, forceall))) 
     1368    PKTFREE (di->osh, p, TRUE); 
     1369} 
     1370 
     1371static bool 
     1372dma32_txstopped (dma_info_t * di) 
     1373{ 
     1374  return ((R_REG (di->osh, &di->d32txregs->status) & XS_XS_MASK) == 
     1375          XS_XS_STOPPED); 
     1376} 
     1377 
     1378static bool 
     1379dma32_rxstopped (dma_info_t * di) 
     1380{ 
     1381  return ((R_REG (di->osh, &di->d32rxregs->status) & RS_RS_MASK) == 
     1382          RS_RS_STOPPED); 
     1383} 
     1384 
     1385static bool 
     1386dma32_alloc (dma_info_t * di, uint direction) 
     1387{ 
     1388  uint size; 
     1389  uint ddlen; 
     1390  void *va; 
     1391 
     1392  ddlen = sizeof (dma32dd_t); 
     1393 
     1394  size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); 
     1395 
     1396  if (!ISALIGNED (DMA_CONSISTENT_ALIGN, D32RINGALIGN)) 
     1397    size += D32RINGALIGN; 
     1398 
     1399 
     1400  if (direction == DMA_TX) 
     1401    { 
     1402      if ((va = 
     1403           DMA_ALLOC_CONSISTENT (di->osh, size, &di->txdpa, 
     1404                                 &di->tx_dmah)) == NULL) 
     1405        { 
     1406          DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", 
     1407                      di->name)); 
     1408          return FALSE; 
    9551409        } 
    956         return (0); 
    957 } 
    958  
    959 void 
    960 dma_txpioloopback(osl_t *osh, dma32regs_t *regs) 
    961 { 
    962         OR_REG(osh, &regs->control, XC_LE); 
    963 } 
    964  
    965  
    966  
    967 /* 32 bits DMA functions */ 
    968 static void 
    969 dma32_txinit(dma_info_t *di) 
    970 { 
    971         DMA_TRACE(("%s: dma_txinit\n", di->name)); 
    972  
    973         if (di->ntxd == 0) 
    974                 return; 
    975  
    976         di->txin = di->txout = 0; 
    977         di->hnddma.txavail = di->ntxd - 1; 
    978  
    979         /* clear tx descriptor ring */ 
    980         BZERO_SM((void *)(uintptr)di->txd32, (di->ntxd * sizeof(dma32dd_t))); 
    981         W_REG(di->osh, &di->d32txregs->control, XC_XE); 
    982         _dma_ddtable_init(di, DMA_TX, di->txdpa); 
    983 } 
    984  
    985 static bool 
    986 dma32_txenabled(dma_info_t *di) 
    987 { 
    988         uint32 xc; 
    989  
    990         /* If the chip is dead, it is not enabled :-) */ 
    991         xc = R_REG(di->osh, &di->d32txregs->control); 
    992         return ((xc != 0xffffffff) && (xc & XC_XE)); 
    993 } 
    994  
    995 static void 
    996 dma32_txsuspend(dma_info_t *di) 
    997 { 
    998         DMA_TRACE(("%s: dma_txsuspend\n", di->name)); 
    999  
    1000         if (di->ntxd == 0) 
    1001                 return; 
    1002  
    1003         OR_REG(di->osh, &di->d32txregs->control, XC_SE); 
    1004 } 
    1005  
    1006 static void 
    1007 dma32_txresume(dma_info_t *di) 
    1008 { 
    1009         DMA_TRACE(("%s: dma_txresume\n", di->name)); 
    1010  
    1011         if (di->ntxd == 0) 
    1012                 return; 
    1013  
    1014         AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); 
    1015 } 
    1016  
    1017 static bool 
    1018 dma32_txsuspended(dma_info_t *di) 
    1019 { 
    1020         return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); 
    1021 } 
    1022  
    1023 static void 
    1024 dma32_txreclaim(dma_info_t *di, bool forceall) 
    1025 { 
    1026         void *p; 
    1027  
    1028         DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); 
    1029  
    1030         while ((p = dma32_getnexttxp(di, forceall))) 
    1031                 PKTFREE(di->osh, p, TRUE); 
    1032 } 
    1033  
    1034 static bool 
    1035 dma32_txstopped(dma_info_t *di) 
    1036 { 
    1037         return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); 
    1038 } 
    1039  
    1040 static bool 
    1041 dma32_rxstopped(dma_info_t *di) 
    1042 { 
    1043         return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); 
    1044 } 
    1045  
    1046 static bool 
    1047 dma32_alloc(dma_info_t *di, uint direction) 
    1048 { 
    1049         uint size; 
    1050         uint ddlen; 
    1051         void *va; 
    1052  
    1053         ddlen = sizeof(dma32dd_t); 
    1054  
    1055         size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); 
    1056  
    1057         if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) 
    1058                 size += D32RINGALIGN; 
    1059  
    1060  
    1061         if (direction == DMA_TX) { 
    1062                 if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) { 
    1063                         DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", 
    1064                                    di->name)); 
    1065                         return FALSE; 
    1066                 } 
    1067  
    1068                 di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); 
    1069                 di->txdalign = (uint)((int8*)(uintptr)di->txd32 - (int8*)va); 
    1070                 di->txdpa += di->txdalign; 
    1071                 di->txdalloc = size; 
    1072                 ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); 
    1073         } else { 
    1074                 if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) { 
    1075                         DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", 
    1076                                    di->name)); 
    1077                         return FALSE; 
    1078                 } 
    1079                 di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); 
    1080                 di->rxdalign = (uint)((int8*)(uintptr)di->rxd32 - (int8*)va); 
    1081                 di->rxdpa += di->rxdalign; 
    1082                 di->rxdalloc = size; 
    1083                 ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); 
     1410 
     1411      di->txd32 = (dma32dd_t *) ROUNDUP ((uintptr) va, D32RINGALIGN); 
     1412      di->txdalign = (uint) ((int8 *) (uintptr) di->txd32 - (int8 *) va); 
     1413      di->txdpa += di->txdalign; 
     1414      di->txdalloc = size; 
     1415      ASSERT (ISALIGNED ((uintptr) di->txd32, D32RINGALIGN)); 
     1416    } 
     1417  else 
     1418    { 
     1419      if ((va = 
     1420           DMA_ALLOC_CONSISTENT (di->osh, size, &di->rxdpa, 
     1421                                 &di->rx_dmah)) == NULL) 
     1422        { 
     1423          DMA_ERROR (("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", 
     1424                      di->name)); 
     1425          return FALSE; 
    10841426        } 
    1085