summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorpengcheng chen - Sun Microsystems - Beijing China <Pengcheng.Chen@Sun.COM>2009-02-09 11:32:10 +0800
committerpengcheng chen - Sun Microsystems - Beijing China <Pengcheng.Chen@Sun.COM>2009-02-09 11:32:10 +0800
commitf3c4902c7f91725a7b538a3d82f1993bff02944f (patch)
tree69be516f3c7e86f922ea5a514b2bcff5c64ae7fd /usr/src
parentf5281d3839034a29b615ba4c302e45ed1ef62069 (diff)
downloadillumos-gate-f3c4902c7f91725a7b538a3d82f1993bff02944f.tar.gz
6795075 iwk driver complaining of fatal firmware error
6788308 Array overrun in iwk
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/iwk/iwk2.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/usr/src/uts/common/io/iwk/iwk2.c b/usr/src/uts/common/io/iwk/iwk2.c
index 0abbd91775..f32433804f 100644
--- a/usr/src/uts/common/io/iwk/iwk2.c
+++ b/usr/src/uts/common/io/iwk/iwk2.c
@@ -337,6 +337,7 @@ static int iwk_m_getprop(void *arg, const char *pr_name,
static void iwk_destroy_locks(iwk_sc_t *sc);
static int iwk_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
static void iwk_thread(iwk_sc_t *sc);
+static void iwk_watchdog(void *arg);
static int iwk_run_state_config_ibss(ieee80211com_t *ic);
static int iwk_run_state_config_sta(ieee80211com_t *ic);
static int iwk_start_tx_beacon(ieee80211com_t *ic);
@@ -698,6 +699,7 @@ iwk_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
*/
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = iwk_newstate;
+ ic->ic_watchdog = iwk_watchdog;
sc->sc_recv_mgmt = ic->ic_recv_mgmt;
ic->ic_recv_mgmt = iwk_recv_mgmt;
ic->ic_node_alloc = iwk_node_alloc;
@@ -1542,6 +1544,7 @@ iwk_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
iwk_add_sta_t node;
sc->sc_flags |= IWK_F_SCANNING;
+ sc->sc_scan_pending = 0;
iwk_set_led(sc, 2, 10, 2);
/*
@@ -1581,6 +1584,15 @@ iwk_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
}
break;
}
+
+ case IEEE80211_S_AUTH:
+ case IEEE80211_S_ASSOC:
+ case IEEE80211_S_RUN:
+ sc->sc_flags |= IWK_F_SCANNING;
+ sc->sc_scan_pending = 0;
+
+ iwk_set_led(sc, 2, 10, 2);
+ /* FALLTHRU */
case IEEE80211_S_SCAN:
mutex_exit(&sc->sc_glock);
/* step to next channel before actual FW scan */
@@ -1763,6 +1775,33 @@ iwk_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
return (err);
}
+static void
+iwk_watchdog(void *arg)
+{
+ iwk_sc_t *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+#ifdef DEBUG
+ timeout_id_t timeout_id = ic->ic_watchdog_timer;
+#endif
+
+ ieee80211_stop_watchdog(ic);
+
+ if ((ic->ic_state != IEEE80211_S_AUTH) &&
+ (ic->ic_state != IEEE80211_S_ASSOC))
+ return;
+
+ if (ic->ic_bss->in_fails > 0) {
+ IWK_DBG((IWK_DEBUG_80211, "watchdog (0x%x) reset: "
+ "node (0x%x)\n", timeout_id, &ic->ic_bss));
+ ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+ } else {
+ IWK_DBG((IWK_DEBUG_80211, "watchdog (0x%x) timeout: "
+ "node (0x%x), retry (%d)\n",
+ timeout_id, &ic->ic_bss, ic->ic_bss->in_fails + 1));
+ ieee80211_watchdog(ic);
+ }
+}
+
/*ARGSUSED*/
static int iwk_key_set(ieee80211com_t *ic, const struct ieee80211_key *k,
const uint8_t mac[IEEE80211_ADDR_LEN])
@@ -2953,10 +2992,9 @@ iwk_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
txpower.tx_power.ht_ofdm_power[i].
s.dsp_predis_atten = 110 | (110 << 8);
}
- txpower.tx_power.ht_ofdm_power[POWER_TABLE_NUM_HT_OFDM_ENTRIES].
- s.ramon_tx_gain = 0x3f3f;
- txpower.tx_power.ht_ofdm_power[POWER_TABLE_NUM_HT_OFDM_ENTRIES].
- s.dsp_predis_atten = 110 | (110 << 8);
+ txpower.tx_power.legacy_cck_power.s.ramon_tx_gain = 0x3f3f;
+ txpower.tx_power.legacy_cck_power.s.dsp_predis_atten
+ = 110 | (110 << 8);
err1 = iwk_cmd(sc, REPLY_TX_PWR_TABLE_CMD, &txpower,
sizeof (txpower), 1);
if (err1 != IWK_SUCCESS) {
@@ -3173,13 +3211,13 @@ iwk_m_stop(void *arg)
iwk_stop(sc);
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+ ieee80211_stop_watchdog(ic);
mutex_enter(&sc->sc_mt_lock);
sc->sc_flags &= ~IWK_F_HW_ERR_RECOVER;
sc->sc_flags &= ~IWK_F_RATE_AUTO_CTL;
mutex_exit(&sc->sc_mt_lock);
mutex_enter(&sc->sc_glock);
sc->sc_flags &= ~IWK_F_RUNNING;
- sc->sc_flags &= ~IWK_F_SCANNING;
mutex_exit(&sc->sc_glock);
}
@@ -3430,6 +3468,13 @@ iwk_hw_set_before_auth(iwk_sc_t *sc)
uint16_t masks = 0, rate;
int i, err;
+ if (in->in_chan == IEEE80211_CHAN_ANYC) {
+ cmn_err(CE_WARN, "iwk_hw_set_before_auth():"
+ "channel (%d) isn't in proper range\n",
+ ieee80211_chan2ieee(ic, in->in_chan));
+ return (IWK_FAIL);
+ }
+
/* update adapter's configuration according the info of target AP */
IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid);
sc->sc_config.chan = ieee80211_chan2ieee(ic, in->in_chan);
@@ -4211,6 +4256,9 @@ iwk_stop(iwk_sc_t *sc)
iwk_stop_master(sc);
sc->sc_tx_timer = 0;
+ sc->sc_flags &= ~IWK_F_SCANNING;
+ sc->sc_scan_pending = 0;
+
tmp = IWK_READ(sc, CSR_RESET);
IWK_WRITE(sc, CSR_RESET, tmp | CSR_RESET_REG_FLAG_SW_RESET);