Please note: This project is no longer active. The website is kept online for historic purposes only.
If you´re looking for a Linux driver for your Atheros WLAN device, you should continue here .

Ticket #900: ath-mib-irq-status-debug-2.diff

File ath-mib-irq-status-debug-2.diff, 6.9 kB (added by valins@soften.ktu.lt, 13 years ago)

Second try, please see attached patch.

  • ath/if_ath.c

    old new  
    15861586        struct net_device *dev = dev_id; 
    15871587        struct ath_softc *sc = dev->priv; 
    15881588        struct ath_hal *ah = sc->sc_ah; 
    1589         HAL_INT status
    1590         int needmark
     1589        HAL_INT status, saved
     1590        int needmark, i
    15911591 
    15921592        if (sc->sc_invalid) { 
    15931593                /* 
     
    16061606                return IRQ_HANDLED; 
    16071607        } 
    16081608        needmark = 0; 
    1609         /* 
    1610          * Figure out the reason(s) for the interrupt.  Note 
    1611          * that the hal returns a pseudo-ISR that may include 
    1612          * bits we haven't explicitly enabled so we mask the 
    1613          * value to ensure we only process bits we requested. 
    1614          */ 
    1615         ath_hal_getisr(ah, &status);            /* NB: clears ISR too */ 
    1616         DPRINTF(sc, ATH_DEBUG_INTR, "%s: status 0x%x\n", __func__, status); 
    1617         status &= sc->sc_imask;                 /* discard unasked for bits */ 
    1618         if (status & HAL_INT_FATAL) { 
    1619                 sc->sc_stats.ast_hardware++; 
    1620                 ath_hal_intrset(ah, 0);         /* disable intr's until reset */ 
    1621                 ATH_SCHEDULE_TQUEUE(&sc->sc_fataltq, &needmark); 
    1622         } else if (status & HAL_INT_RXORN) { 
    1623                 sc->sc_stats.ast_rxorn++; 
    1624                 ath_hal_intrset(ah, 0);         /* disable intr's until reset */ 
    1625                 ATH_SCHEDULE_TQUEUE(&sc->sc_rxorntq, &needmark); 
    1626         } else { 
    1627                 if (status & HAL_INT_SWBA) { 
    1628                         /* 
    1629                          * Software beacon alert--time to send a beacon. 
    1630                          * Handle beacon transmission directly; deferring 
    1631                          * this is too slow to meet timing constraints 
    1632                          * under load. 
    1633                          */ 
    1634                         ath_beacon_send(sc, &needmark); 
    1635                 } 
    1636                 if (status & HAL_INT_RXEOL) { 
    1637                         /* 
    1638                          * NB: the hardware should re-read the link when 
    1639                          *     RXE bit is written, but it doesn't work at 
    1640                          *     least on older hardware revs. 
    1641                          */ 
    1642                         sc->sc_stats.ast_rxeol++; 
    1643                 } 
    1644                 if (status & HAL_INT_TXURN) { 
    1645                         sc->sc_stats.ast_txurn++; 
    1646                         /* bump tx trigger level */ 
    1647                         ath_hal_updatetxtriglevel(ah, AH_TRUE); 
    1648                 } 
    1649                 if (status & HAL_INT_RX) { 
    1650                         ath_uapsd_processtriggers(sc); 
    1651                         ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark); 
    1652                 } 
    1653                 if (status & HAL_INT_TX) { 
     1609 
     1610        for(i=0; i < 5; i++) { 
     1611                /* 
     1612                 * Figure out the reason(s) for the interrupt.  Note 
     1613                 * that the hal returns a pseudo-ISR that may include 
     1614                 * bits we haven't explicitly enabled so we mask the 
     1615                 * value to ensure we only process bits we requested. 
     1616                 */ 
     1617                ath_hal_getisr(ah, &status);            /* NB: clears ISR too */ 
     1618                saved = status; 
     1619                status &= sc->sc_imask;                 /* discard unasked for bits */ 
     1620 
     1621                if ((i > 0) && (status == 0)) { 
     1622                        break; 
     1623                } 
     1624 
     1625                DPRINTF(sc, ATH_DEBUG_INTR, "%s: status 0x%x\n", __func__, status); 
     1626                status &= sc->sc_imask;                 /* discard unasked for bits */ 
     1627                if (status & HAL_INT_FATAL) { 
     1628                        sc->sc_stats.ast_hardware++; 
     1629                        ath_hal_intrset(ah, 0);         /* disable intr's until reset */ 
     1630                        ATH_SCHEDULE_TQUEUE(&sc->sc_fataltq, &needmark); 
     1631                } else if (status & HAL_INT_RXORN) { 
     1632                        sc->sc_stats.ast_rxorn++; 
     1633                        ath_hal_intrset(ah, 0);         /* disable intr's until reset */ 
     1634                        ATH_SCHEDULE_TQUEUE(&sc->sc_rxorntq, &needmark); 
     1635                } else { 
     1636                        if (status & HAL_INT_SWBA) { 
     1637                                /* 
     1638                                 * Software beacon alert--time to send a beacon. 
     1639                                 * Handle beacon transmission directly; deferring 
     1640                                 * this is too slow to meet timing constraints 
     1641                                 * under load. 
     1642                                 */ 
     1643                                ath_beacon_send(sc, &needmark); 
     1644                        } 
     1645                        if (status & HAL_INT_RXEOL) { 
     1646                                /* 
     1647                                 * NB: the hardware should re-read the link when 
     1648                                 *     RXE bit is written, but it doesn't work at 
     1649                                 *     least on older hardware revs. 
     1650                                 */ 
     1651                                sc->sc_stats.ast_rxeol++; 
     1652                        } 
     1653                        if (status & HAL_INT_TXURN) { 
     1654                                sc->sc_stats.ast_txurn++; 
     1655                                /* bump tx trigger level */ 
     1656                                ath_hal_updatetxtriglevel(ah, AH_TRUE); 
     1657                        } 
     1658                        if (status & HAL_INT_RX) { 
     1659                                ath_uapsd_processtriggers(sc); 
     1660                                ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark); 
     1661                        } 
     1662                        if (status & HAL_INT_TX) { 
    16541663#ifdef ATH_SUPERG_DYNTURBO 
    1655                         /* 
    1656                         * Check if the beacon queue caused the interrupt  
    1657                         * when a dynamic turbo switch 
    1658                         * is pending so we can initiate the change.  
    1659                         * XXX must wait for all vap's beacons 
    1660                         */ 
     1664                               /* 
     1665                                * Check if the beacon queue caused the interrupt  
     1666                                * when a dynamic turbo switch 
     1667                                * is pending so we can initiate the change.  
     1668                                * XXX must wait for all vap's beacons 
     1669                                */ 
    16611670 
    1662                         if (sc->sc_dturbo_switch) { 
    1663                                 u_int32_t txqs = (1 << sc->sc_bhalq); 
    1664                                 ath_hal_gettxintrtxqs(ah, &txqs); 
    1665                                 if(txqs & (1 << sc->sc_bhalq)) { 
    1666                                         sc->sc_dturbo_switch = 0; 
     1671                                if (sc->sc_dturbo_switch) { 
     1672                                        u_int32_t txqs = (1 << sc->sc_bhalq); 
     1673                                        ath_hal_gettxintrtxqs(ah, &txqs); 
     1674                                        if(txqs & (1 << sc->sc_bhalq)) { 
     1675                                                sc->sc_dturbo_switch = 0; 
     1676                                                /* 
     1677                                                 * Hack: defer switch for 10ms to permit slow 
     1678                                                 * clients time to track us.  This especially 
     1679                                                 * noticeable with Windows clients. 
     1680                                                 */ 
     1681                                                mod_timer(&sc->sc_dturbo_switch_mode, 
     1682                                                          jiffies + msecs_to_jiffies(10)); 
     1683                                        } 
     1684                                }  
     1685#endif 
     1686                                ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark); 
     1687                        } 
     1688                        if (status & HAL_INT_BMISS) { 
     1689                                sc->sc_stats.ast_bmiss++; 
     1690                                ATH_SCHEDULE_TQUEUE(&sc->sc_bmisstq, &needmark); 
     1691                        } 
     1692                        if (status & HAL_INT_MIB) { 
     1693                                int i; 
     1694                                HAL_INT mibstatus; 
     1695 
     1696                                sc->sc_stats.ast_mib++; 
     1697                                for(i=0; i < 3; i++) { 
    16671698                                        /* 
    1668                                          * Hack: defer switch for 10ms to permit slow 
    1669                                          * clients time to track us.  This especially 
    1670                                          * noticeable with Windows clients. 
     1699                                         * Disable interrupts until we service the MIB 
     1700                                         * interrupt; otherwise it will continue to fire. 
    16711701                                         */ 
    1672                                         mod_timer(&sc->sc_dturbo_switch_mode, 
    1673                                                           jiffies + msecs_to_jiffies(10)); 
     1702                                        ath_hal_intrset(ah, 0); 
     1703 
     1704                                        ath_hal_mibevent(ah, &sc->sc_halstats); 
     1705                                        ath_hal_intrset(ah, sc->sc_imask); 
     1706 
     1707                                        ath_hal_getisr(ah, &mibstatus); 
     1708 
     1709                                        if (!(mibstatus & HAL_INT_MIB)) 
     1710                                                break; 
    16741711                                } 
    1675                         }  
    1676 #endif 
    1677                         ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark); 
     1712 
     1713                                if (i > 0) { 
     1714                                        printk("ath_intr(): MIB retry count: %d, status: 0x%0X, mibstatus: 0x%0X\n", 
     1715                                               i, status, mibstatus); 
     1716                                } 
     1717 
     1718                                if (mibstatus & HAL_INT_MIB) { 
     1719                                        printk("ath_intr(): mibstatus: 0x%0X, HAL_INT_MIB is not cleared.\n", 
     1720                                               mibstatus); 
     1721                                        sc->sc_stats.ast_hardware++; 
     1722                                        ath_hal_intrset(ah, 0);         /* disable intr's until reset */ 
     1723                                        ATH_SCHEDULE_TQUEUE(&sc->sc_fataltq, &needmark); 
     1724                                } 
     1725                        } 
    16781726                } 
    1679                 if (status & HAL_INT_BMISS) { 
    1680                         sc->sc_stats.ast_bmiss++; 
    1681                         ATH_SCHEDULE_TQUEUE(&sc->sc_bmisstq, &needmark); 
    1682                 } 
    1683                 if (status & HAL_INT_MIB) { 
    1684                         sc->sc_stats.ast_mib++; 
    1685                         /* 
    1686                          * Disable interrupts until we service the MIB 
    1687                          * interrupt; otherwise it will continue to fire. 
    1688                          */ 
    1689                         ath_hal_intrset(ah, 0); 
    1690                         /* 
    1691                          * Let the hal handle the event.  We assume it will 
    1692                          * clear whatever condition caused the interrupt. 
    1693                          */ 
    1694                         ath_hal_mibevent(ah, &sc->sc_halstats); 
    1695                         ath_hal_intrset(ah, sc->sc_imask); 
    1696                 } 
    16971727        } 
     1728 
     1729        if ((i == 5) && (status != 0)) { 
     1730                printk("count: %d, saved: %0X, masked: %0X\n", i, saved, status); 
     1731        } 
     1732 
    16981733        if (needmark) 
    16991734                mark_bh(IMMEDIATE_BH); 
    17001735        return IRQ_HANDLED;