REG_WRITE(ah, AR_PHY_RESTART, val);
}
EXPORT_SYMBOL(ar9003_hw_disable_phy_restart);
+
+void ar9003_hw_dump_ani_reg(struct ath_hw *ah)
+{
+ u32 reg;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ reg = REG_READ(ah, AR_PHY_FIND_SIG_LOW);
+ ath_dbg(common, RX_STUCK, "FIRStep Low = 0x%x (%d)\n",
+ MS(reg, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW),
+ MS(reg, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW));
+ reg = REG_READ(ah, AR_PHY_DESIRED_SZ);
+ ath_dbg(common, RX_STUCK, "Total Desired = 0x%x (%d)\n",
+ MS(reg, AR_PHY_DESIRED_SZ_TOT_DES),
+ MS(reg, AR_PHY_DESIRED_SZ_TOT_DES));
+ ath_dbg(common, RX_STUCK, "ADC Desired = 0x%x (%d)\n",
+ MS(reg, AR_PHY_DESIRED_SZ_ADC),
+ MS(reg, AR_PHY_DESIRED_SZ_ADC));
+ reg = REG_READ(ah, AR_PHY_FIND_SIG);
+ ath_dbg(common, RX_STUCK, "FIRStep = 0x%x (%d)\n",
+ MS(reg, AR_PHY_FIND_SIG_FIRSTEP),
+ MS(reg, AR_PHY_FIND_SIG_FIRSTEP));
+ reg = REG_READ(ah, AR_PHY_AGC);
+ ath_dbg(common, RX_STUCK, "Coarse High = 0x%x (%d)\n",
+ MS(reg, AR_PHY_AGC_COARSE_HIGH),
+ MS(reg, AR_PHY_AGC_COARSE_HIGH));
+ ath_dbg(common, RX_STUCK, "Coarse Low = 0x%x (%d)\n",
+ MS(reg, AR_PHY_AGC_COARSE_LOW),
+ MS(reg, AR_PHY_AGC_COARSE_LOW));
+ ath_dbg(common, RX_STUCK, "Coarse Power Constant = 0x%x (%d)\n",
+ MS(reg, AR_PHY_AGC_COARSE_PWR_CONST),
+ MS(reg, AR_PHY_AGC_COARSE_PWR_CONST));
+ reg = REG_READ(ah, AR_PHY_TIMING5);
+ ath_dbg(common, RX_STUCK, "Enable Cyclic Power Thresh = %d\n",
+ MS(reg, AR_PHY_TIMING5_CYCPWR_THR1_ENABLE));
+ ath_dbg(common, RX_STUCK, "Cyclic Power Thresh = 0x%x (%d)\n",
+ MS(reg, AR_PHY_TIMING5_CYCPWR_THR1),
+ MS(reg, AR_PHY_TIMING5_CYCPWR_THR1));
+ ath_dbg(common, RX_STUCK, "Cyclic Power Thresh 1A= 0x%x (%d)\n",
+ MS(reg, AR_PHY_TIMING5_CYCPWR_THR1A),
+ MS(reg, AR_PHY_TIMING5_CYCPWR_THR1A));
+ reg = REG_READ(ah, AR_PHY_DAG_CTRLCCK);
+ ath_dbg(common, RX_STUCK, "Barker RSSI Thresh Enable = %d\n",
+ MS(reg, AR_PHY_DAG_CTRLCCK_EN_RSSI_THR));
+ ath_dbg(common, RX_STUCK, "Barker RSSI Thresh = 0x%x (%d)\n",
+ MS(reg, AR_PHY_DAG_CTRLCCK_RSSI_THR),
+ MS(reg, AR_PHY_DAG_CTRLCCK_RSSI_THR));
+}
+EXPORT_SYMBOL(ar9003_hw_dump_ani_reg);
ath_tx_node_cleanup(sc, an);
}
+void ath_rx_poll_work(unsigned long data)
+{
+ struct ath_softc *sc = (struct ath_softc *)data;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &common->hw->conf;
+ struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist;
+ static u32 iter, match_count;
+ static u64 last_run;
+ unsigned long flags;
+ u32 rx_clear, rx, tx, delay = 10, reg;
+ int i, j;
+ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
+ u8 nread;
+
+ if (jiffies_to_msecs(jiffies - last_run) > 30)
+ iter = match_count = 0;
+ else {
+ if (atomic_read(&sc->stop_rx_poll) && iter) {
+ iter = match_count = 0;
+ return;
+ }
+ iter += 1;
+ }
+ sc->ps_flags |= PS_WAIT_FOR_BEACON;
+ ath9k_ps_wakeup(sc);
+
+ spin_lock_irqsave(&common->cc_lock, flags);
+ ath_hw_cycle_counters_update(common);
+
+ rx_clear = common->cc_rxpoll.rx_busy * 100 / common->cc_rxpoll.cycles;
+ rx = common->cc_rxpoll.rx_frame * 100 / common->cc_rxpoll.cycles;
+ tx = common->cc_rxpoll.tx_frame * 100 / common->cc_rxpoll.cycles;
+ memset(&common->cc_rxpoll, 0, sizeof(common->cc_rxpoll));
+
+ spin_unlock_irqrestore(&common->cc_lock, flags);
+
+ ath_dbg(common, RX_STUCK,
+ "--------------------------------------------------\n");
+ ath_dbg(common, RX_STUCK, "Iteration: %d\n", iter);
+ ath_dbg(common, RX_STUCK, "Cycle Counters:\n");
+ ath_dbg(common, RX_STUCK,
+ "rx_clear = %d%% rx_frame %d%% tx_frame %d%%\n",
+ rx_clear, rx, tx);
+
+ ath_dbg(common, RX_STUCK, "IMR %08x IER %08x intr_cnt %d\n",
+ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER),
+ atomic_read(&ah->intr_ref_cnt));
+ ar9003_hw_dump_txdesc(ah);
+
+ REG_SET_BIT(ah, AR_DIAG_SW, 0x8080000);
+ for (i = 0; i < 5; i++) {
+ ath_dbg(common, RX_STUCK,
+ "OBS_BUS_1(0x806c) = %08x "
+ "OBS_BUS_CTRL(0x8068) = %08x\n",
+ REG_READ(ah, AR_OBS_BUS_1),
+ REG_READ(ah, AR_OBS_BUS_CTRL));
+ }
+ ath_dbg(common, RX_STUCK,
+ "DIAG_SW(0x8048) = %08x MAC_PCU_LOGIC_ANALYZER(0x8264) = %08x"
+ " PCU_MISC_MODE2(0x8344) = %08x\n",
+ REG_READ(ah, AR_DIAG_SW),
+ REG_READ(ah, AR_MAC_PCU_LOGIC_ANALYZER),
+ REG_READ(ah, AR_PCU_MISC_MODE2));
+
+ ath_dbg(common, RX_STUCK, "0x100 = %08x 0x104 = %08x\n",
+ REG_READ(ah, 0x100), REG_READ(ah, 0x104));
+ for (i = 0; i < 10; i++)
+ ath_dbg(common, RX_STUCK, "QSTS(%d) = %08x\n",
+ i, REG_READ(ah, AR_QSTS(i)));
+
+ ath_dbg(common, RX_STUCK, "Rxdp: hp %08x lp %08x\n",
+ REG_READ(ah, AR_HP_RXDP), REG_READ(ah, AR_LP_RXDP));
+ ath_dbg(common, RX_STUCK,
+ "rx filter: %08x\n", REG_READ(ah, AR_RX_FILTER));
+
+ ath_dbg(common, RX_STUCK, "DMADBG dump:\n");
+ for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
+ ath_dbg(common, RX_STUCK, "%d: %08x ",
+ i, REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32))));
+ ath_dbg(common, RX_STUCK, "\n");
+
+ ath_dbg(common, RX_STUCK, "BB Debug dump:\n");
+ /* Step 1a: Set bit 23 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x00800000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2a: Set register 0xa364 to 0x1000 */
+ reg = 0x1000;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3a: Read bits 17:0 of register 0x9c20 */
+ reg = REG_READ(ah, 0x9c20);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x1000] 0x9c20[17:0] = 0x%x\n", reg);
+
+ /* Step 1b: Set bit 23 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x00800000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2b: Set register 0xa364 to 0x1400 */
+ reg = 0x1400;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3b: Read bits 17:0 of register 0x9c20 */
+ reg = REG_READ(ah, 0x9c20);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x1400] 0x9c20[17:0] = 0x%x\n", reg);
+
+ /* Step 1c: Set bit 23 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x00800000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2c: Set register 0xa364 to 0x3C00 */
+ reg = 0x3c00;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3c: Read bits 17:0 of register 0x9c20 */
+ reg = REG_READ(ah, 0x9c20);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x3C00] 0x9c20[17:0] = 0x%x\n", reg);
+
+ /* Step 1d: Set bit 24 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x001040000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2d: Set register 0xa364 to 0x5005D */
+ reg = 0x5005D;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3d: Read bits 17:0 of register 0xa368 */
+ reg = REG_READ(ah, 0xa368);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x5005D] 0xa368[17:0] = 0x%x\n", reg);
+
+ /* Step 1e: Set bit 24 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x001040000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2e: Set register 0xa364 to 0x7005D */
+ reg = 0x7005D;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3e: Read bits 17:0 of register 0xa368 */
+ reg = REG_READ(ah, 0xa368);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x7005D] 0xa368[17:0] = 0x%x\n", reg);
+
+ /* Step 1f: Set bit 24 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x001000000;
+ reg |= 0x40000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2f: Set register 0xa364 to 0x3005D */
+ reg = 0x3005D;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3f: Read bits 17:0 of register 0xa368 */
+ reg = REG_READ(ah, 0xa368);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x3005D] 0xa368[17:0] = 0x%x\n", reg);
+
+ /* Step 1g: Set bit 24 of register 0xa360 to 0 */
+ reg = REG_READ(ah, 0xa360);
+ reg &= ~0x001000000;
+ reg |= 0x40000;
+ REG_WRITE(ah, 0xa360, reg);
+
+ /* Step 2g: Set register 0xa364 to 0x6005D */
+ reg = 0x6005D;
+ REG_WRITE(ah, 0xa364, reg);
+
+ /* Step 3g: Read bits 17:0 of register 0xa368 */
+ reg = REG_READ(ah, 0xa368);
+ reg &= 0x0003ffff;
+ ath_dbg(common, RX_STUCK,
+ "Test Control Status [0x6005D] 0xa368[17:0] = 0x%x\n", reg);
+
+ ar9003_hw_dump_ani_reg(ah);
+
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "WATCHDOG",
+ sc->debug.stats.istats.bb_watchdog);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
+ ath_dbg(common, RX_STUCK, "%8s: %10u\n", "RXPHY",
+ sc->debug.stats.istats.rxphyerr);
+ ath_dbg(common, RX_STUCK, "%8s: %10u\n", "RXKCM",
+ sc->debug.stats.istats.rx_keycache_miss);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
+ ath_dbg(common, RX_STUCK,
+ "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
+
+ ath_dbg(common, RX_STUCK, "Noise floor dump:\n");
+ ath_dbg(common, RX_STUCK,
+ "Channel Noise Floor : %d\n", ah->noise);
+ ath_dbg(common, RX_STUCK,
+ "Chain | privNF | # Readings | NF Readings\n");
+ for (i = 0; i < 6; i++) {
+ if (!(chainmask & (1 << i)) ||
+ ((i >= 3) && !conf_is_ht40(conf)))
+ continue;
+
+ nread = 5 - h[i].invalidNFcount;
+ ath_dbg(common, RX_STUCK,
+ " %d\t %d\t %d\t\t", i, h[i].privNF, nread);
+ for (j = 0; j < nread; j++)
+ ath_dbg(common, RX_STUCK,
+ " %d", h[i].nfCalBuffer[j]);
+ ath_dbg(common, RX_STUCK, "\n");
+ }
+
+ last_run = jiffies;
+ if (rx_clear > 98) {
+ ath_dbg(common, RX_STUCK,
+ "rx clear %d tx %d matched count %d\n",
+ rx_clear, tx, match_count);
+ if (match_count++ > 9) {
+ ath9k_ps_restore(sc);
+ ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
+ iter = match_count = 0;
+ return;
+ }
+ } else if (ath9k_hw_detect_mac_hang(ah)) {
+ ath_dbg(common, RX_STUCK, "MAC hang signature found\n");
+ ath9k_ps_restore(sc);
+ ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
+ iter = match_count = 0;
+ return;
+ } else if (iter >= 15) {
+ iter = match_count = 0;
+ delay = 200;
+ }
+ ath9k_ps_restore(sc);
+ atomic_set(&sc->stop_rx_poll, 0);
+ mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies(delay));
+}
void ath9k_tasklet(unsigned long data)
{