diff options
author | pengcheng chen - Sun Microsystems - Beijing China <Pengcheng.Chen@Sun.COM> | 2009-02-09 11:32:10 +0800 |
---|---|---|
committer | pengcheng chen - Sun Microsystems - Beijing China <Pengcheng.Chen@Sun.COM> | 2009-02-09 11:32:10 +0800 |
commit | f3c4902c7f91725a7b538a3d82f1993bff02944f (patch) | |
tree | 69be516f3c7e86f922ea5a514b2bcff5c64ae7fd /usr/src | |
parent | f5281d3839034a29b615ba4c302e45ed1ef62069 (diff) | |
download | illumos-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.c | 58 |
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); |