Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Fix NIC-memory leak for symbol firmware at reinit...



details:   https://anonhg.NetBSD.org/src/rev/6f4c55cb1767
branches:  trunk
changeset: 537588:6f4c55cb1767
user:      onoe <onoe%NetBSD.org@localhost>
date:      Wed Oct 02 17:11:34 2002 +0000

description:
Fix NIC-memory leak for symbol firmware at reinitialization.  After 4-5
times changing of 802.11 parameters, such as nwid, the error
"tx buffer allocation failed" occured unless ifconfig down up.

Pass signal streangth and timestamp to ieee80211_input, though it is not
useful for wi driver for now.

diffstat:

 sys/dev/ic/wi.c    |  78 +++++++++++++++++++++++++++++++++++------------------
 sys/dev/ic/wireg.h |  16 ++++++----
 2 files changed, 60 insertions(+), 34 deletions(-)

diffs (180 lines):

diff -r 46293d5992b9 -r 6f4c55cb1767 sys/dev/ic/wi.c
--- a/sys/dev/ic/wi.c   Wed Oct 02 17:08:10 2002 +0000
+++ b/sys/dev/ic/wi.c   Wed Oct 02 17:11:34 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wi.c,v 1.95 2002/10/01 16:11:19 onoe Exp $     */
+/*     $NetBSD: wi.c,v 1.96 2002/10/02 17:11:34 onoe Exp $     */
 
 /*
  * Copyright (c) 1997, 1998, 1999
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.95 2002/10/01 16:11:19 onoe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.96 2002/10/02 17:11:34 onoe Exp $");
 
 #define WI_HERMES_AUTOINC_WAR  /* Work around data write autoinc bug. */
 #define WI_HERMES_STATS_WAR    /* Work around stats counter bug. */
@@ -602,20 +602,22 @@
        /* Set multicast filter. */
        wi_write_multi(sc);
 
-       sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
-       if (sc->sc_firmware_type == WI_SYMBOL)
-               sc->sc_buflen = 1585;   /* XXX */
-       for (i = 0; i < WI_NTXBUF; i++) {
-               error = wi_alloc_fid(sc, sc->sc_buflen,
-                   &sc->sc_txd[i].d_fid);
-               if (error) {
-                       printf("%s: tx buffer allocation failed\n",
-                           sc->sc_dev.dv_xname);
-                       goto out;
+       if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
+               sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
+               if (sc->sc_firmware_type == WI_SYMBOL)
+                       sc->sc_buflen = 1585;   /* XXX */
+               for (i = 0; i < WI_NTXBUF; i++) {
+                       error = wi_alloc_fid(sc, sc->sc_buflen,
+                           &sc->sc_txd[i].d_fid);
+                       if (error) {
+                               printf("%s: tx buffer allocation failed\n",
+                                   sc->sc_dev.dv_xname);
+                               goto out;
+                       }
+                       DPRINTF2(("wi_init: txbuf %d allocated %x\n", i,
+                           sc->sc_txd[i].d_fid));
+                       sc->sc_txd[i].d_len = 0;
                }
-               DPRINTF2(("wi_init: txbuf %d allocated %x\n", i,
-                   sc->sc_txd[i].d_fid));
-               sc->sc_txd[i].d_len = 0;
        }
        sc->sc_txcur = sc->sc_txnext = 0;
        if (ic->ic_opmode == IEEE80211_M_IBSS)
@@ -634,7 +636,9 @@
        /* Enable interrupts */
        CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
 
-       if (!wasenabled && ic->ic_opmode == IEEE80211_M_HOSTAP) {
+       if (!wasenabled &&
+           ic->ic_opmode == IEEE80211_M_HOSTAP &&
+           sc->sc_firmware_type == WI_INTERSIL) {
                /* XXX: some card need to be re-enabled for hostap */
                wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
                wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
@@ -1052,8 +1056,9 @@
        struct wi_frame frmhdr;
        struct mbuf *m;
        struct ieee80211_frame *wh;
+       int fid, len, off, rssi;
        u_int16_t status;
-       int fid, len, off;
+       u_int32_t rstamp;
 
        fid = CSR_READ_2(sc, WI_RX_FID);
 
@@ -1075,6 +1080,9 @@
                DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
                return;
        }
+       rssi = frmhdr.wi_rx_signal;
+       rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
+           le16toh(frmhdr.wi_rx_tstamp1);
 
        len = le16toh(frmhdr.wi_dat_len);
        off = ALIGN(sizeof(struct ieee80211_frame));
@@ -1126,7 +1134,7 @@
                 */
                wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
        }
-       ieee80211_input(ifp, m, 0 /*rssi*/, 0 /*rstamp*/);
+       ieee80211_input(ifp, m, rssi, rstamp);
 }
 
 static void
@@ -1141,8 +1149,9 @@
 
        cur = sc->sc_txcur;
        if (sc->sc_txd[cur].d_fid != fid) {
-               printf("%s: bad alloc %x != %x\n",
-                   sc->sc_dev.dv_xname, fid, sc->sc_txd[cur].d_fid);
+               printf("%s: bad alloc %x != %x, cur %d nxt %d\n",
+                   sc->sc_dev.dv_xname, fid, sc->sc_txd[cur].d_fid, cur,
+                   sc->sc_txnext);
                return;
        }
        sc->sc_tx_timer = 0;
@@ -1980,7 +1989,7 @@
        struct wi_softc *sc = arg;
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_node *ni = &ic->ic_bss;
-       int buflen;
+       int i, buflen;
        u_int16_t val;
        struct wi_ssid ssid;
        enum ieee80211_state ostate;
@@ -2006,12 +2015,27 @@
                wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
                ni->ni_chan = le16toh(val);
 
-               buflen = sizeof(ssid);
-               wi_read_rid(sc, WI_RID_CURRENT_SSID, &ssid, &buflen);
-               ni->ni_esslen = le16toh(ssid.wi_len);
-               if (ni->ni_esslen > IEEE80211_NWID_LEN)
-                       ni->ni_esslen = IEEE80211_NWID_LEN;     /*XXX*/
-               memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen);
+               if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+                       ni->ni_esslen = ic->ic_des_esslen;
+                       memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
+                       ni->ni_nrate = 0;
+                       for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
+                               if (ic->ic_sup_rates[i])
+                                       ni->ni_rates[ni->ni_nrate++] =
+                                           ic->ic_sup_rates[i];
+                       }
+                       ni->ni_intval = ic->ic_lintval;
+                       ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
+                       if (ic->ic_flags & IEEE80211_F_WEPON)
+                               ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
+               } else {
+                       buflen = sizeof(ssid);
+                       wi_read_rid(sc, WI_RID_CURRENT_SSID, &ssid, &buflen);
+                       ni->ni_esslen = le16toh(ssid.wi_len);
+                       if (ni->ni_esslen > IEEE80211_NWID_LEN)
+                               ni->ni_esslen = IEEE80211_NWID_LEN;     /*XXX*/
+                       memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen);
+               }
                break;
 
        case IEEE80211_S_SCAN:
diff -r 46293d5992b9 -r 6f4c55cb1767 sys/dev/ic/wireg.h
--- a/sys/dev/ic/wireg.h        Wed Oct 02 17:08:10 2002 +0000
+++ b/sys/dev/ic/wireg.h        Wed Oct 02 17:11:34 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wireg.h,v 1.40 2002/09/30 06:50:36 onoe Exp $  */
+/*     $NetBSD: wireg.h,v 1.41 2002/10/02 17:11:36 onoe Exp $  */
 
 /*
  * Copyright (c) 1997, 1998, 1999
@@ -524,12 +524,14 @@
  */
 struct wi_frame {
        u_int16_t               wi_status;      /* 0x00 */
-       u_int16_t               wi_rsvd0;       /* 0x02 */ /* 0 */
-       u_int16_t               wi_rsvd1;       /* 0x04 */ /* 0 */
-       u_int16_t               wi_q_info;      /* 0x06 */
-       u_int16_t               wi_rsvd2;       /* 0x08 */
-       u_int8_t                wi_tx_rtry;     /* 0x0a */ /* (Prism2 Only) */
-       u_int8_t                wi_tx_rate;     /* 0x0b */ /* (Prism2 Only) */
+       u_int16_t               wi_rx_tstamp1;  /* 0x02 */
+       u_int16_t               wi_rx_tstamp0;  /* 0x04 */
+       u_int8_t                wi_rx_silence;  /* 0x06 */
+       u_int8_t                wi_rx_signal;   /* 0x07 */
+       u_int8_t                wi_rx_rate;     /* 0x08 */
+       u_int8_t                wi_rx_flow;     /* 0x09 */
+       u_int8_t                wi_tx_rtry;     /* 0x0a */ /* Prism2 AP Only */
+       u_int8_t                wi_tx_rate;     /* 0x0b */ /* Prism2 AP Only */
        u_int16_t               wi_tx_ctl;      /* 0x0c */
        struct ieee80211_frame_addr4 wi_whdr;   /* 0x0e */
        u_int16_t               wi_dat_len;     /* 0x2c */



Home | Main Index | Thread Index | Old Index