Hi

For debugging I disabled the HAL_INT_RXORN (Receive overrun) interrupt by commenting the call to ATH_SCHEDULE_TQUEUE(&sc->sc_rxorntq, &needmark); in ath_intr function.

Now I observed that after some time the number of Receive overrun interrupts keeps on increasing (as observed using athstats), however no HAL_INT_RX interrupts are being received. So the issue seems to be that after some time HAL_INT_RX interrupt gets disabled. For this in my code for channel switching before I enable interrupts I specially add HAL_INT_RX to sc_mask.

sc->sc_mask |= HAL_INT_RX;
ath_hal_intrset(ah, sc->sc_imask);  //enable interrupts

However still the same behaviour persists ie. after some time rx interrupt gets disabled and rx fifo overrun occurs. I have verified that rxorn interrupts are being issued the above code segment is getting executed. So I would like to know as to why is rx interrupt getting disabled when i am enabling it? Is it the problem with the NIC ie. am I setting some registers which is causing the card to not to issue rx interrupts or something else??

Any help would be greatly appreciated.

Thanks
Vishal 



On Tue, Mar 23, 2010 at 8:36 PM, Vishal Sevani <vishal.sevani@gmail.com> wrote:
Hi

I have implemented the channel switching functionality as suggested by Ivan (similar to ar5212SetChannel function). The code is as follows,

           
            uint32_t channelSelect, freq;
             freq = 2412;
            channelSelect = ((freq - 672) * 2 - 3040)/10;
            channelSelect = (channelSelect << 2) & 0xff;
            channelSelect = ath_hal_reverseBits_vs(
channelSelect, 8);
            channelSelect = (channelSelect << 4) | 0x1005;
           
            ath_hal_intrset(ah, 0);  //disable interrupt
            ath_reg_write(sc, 0x997C, 0x00000001); //seek the grant for RFBus
           
            for(ulCount=0; ulCount<100; ulCount++)
            {
                if(ath_reg_read(sc, 0x9c20))
                    break;
                udelay(5);
            }
            if(ulCount >= 100)
            {
                goto freq_changed;
            }
           
            ath_reg_write(sc, 0x981C, 0x00000000); //disable phy
           
            udelay(0xA);
            ath_reg_write(sc, 0x989c, (channelSelect & 0xff));  //set internal registers
            channelSelect = (channelSelect >> 8) & 0x7f;
            ath_reg_write(sc, 0x98d8, channelSelect); //set internal registers
            udelay(0xA);
            ath_reg_write(sc, 0x981C, 0x00000001); //enable phy
            udelay(0xA);
           
            ath_reg_write(sc, 0x9860, (ath_reg_read(sc, 0x9860) | 0x2));
           
            channelSelect = 0x2;
            for (ii=0; (ii< 0xC8) && channelSelect ;ii++)channelSelect = ath_reg_read(sc, 0x9860) & 0x2;
            ath_reg_write(sc, 0x997C, 0); //release RFBus
            ath_hal_intrset(ah, sc->sc_imask);  //enable interrupts

The code is working and the channel is getting switched in about 1ms as tested on Mikrotik Router Boards. However after some time Iam getting the following error

Receive FIFO overrun; resetting.
PCI error 1 at PCI addr 0x10004000
Data bus error, epc == c019a378, ra == c019b840

and the system restarts.

I would like to know why am I getting PCI error? Iam not able to figure out as to what could I be doing wrong which cause PCI error?

I tried to ignore the Receive FIFO overrun error, however if I do so the system stops working. Any help wud be greatly appreciated.

Thanks
Vishal

2010/2/25 IVAN KORSHUN <2002_ivan@mail.ru>

harware limitation for Rx ...
noise level ... e.t.s.

> 800 -- 1000 microseconds seems to be working (in ahdemo mode atleast),
> though I have to test intensely. But why do u suggest 30 - 50ms, is it
> harware limitation or it is an issue with madwifi driver??
>
> On Wed, Feb 24, 2010 at 3:45 PM, IVAN KORSHUN <2002_ivan@mail.ru> wrote:
>
> > 100 microsecond  too small ...
> > need 30 ... 50 ms
> >
> >
> > > Hi Ivan
> > >
> > > Thanks a lot for the help. The function seems to be working, although I
> > had
> > > to make few changes. If I used the addess, 0xb8510024 for AR_IER it was
> > > giving segmentation fault. However it did work with address 0x0024
> > (likewise
> > > for other registers too). But although the frequency does get changed, it
> > > does not get reflected in iwconfig command. For it I guess I will have to
> > > set the member variable ic_curchan of variable ic (of type ieee80211com),
> > > which Iam trying to figure out.
> > >
> > > However one of the other issues is that this function is taking about
> > 30ms
> > > for switching the channel (I have tested it on x86 based IBM laptop).
> > > Whereas we need a channel switching functionality of the order of
> > > microseconds (preferably around 500 microseconds if possible). On
> > analyzing
> > > your function I observed that following for loop
> > >
> > > for (ii=0; (ii< 0x3FFFE) && channelSelect ;ii++)channelSelect =*hard_reg
> > &
> > > 0x2;
> > >
> > > takes about 30ms. Although in place of this for loop I put a delay of
> > about
> > > 100 microsecond and it does seem to work (though I have to test
> > thouroughly
> > > as to whether any packets are getting lost). Also Iam trying to figure
> > the
> > > optimal values for the different delays that you have called in your
> > > function.
> > >
> > > Could you please let me know as to on what basis have you come up with
> > these
> > > different values of delay (ie. 0x3E8, 0xA, 0x64, and the for loop), as it
> > > would help me in optimizing these values for my hardware.
> > >
> > > Thanks
> > > Vishal
> > >
> > > On Tue, Feb 23, 2010 at 1:27 PM, IVAN KORSHUN <2002_ivan@mail.ru> wrote:
> > >
> > > > sysUDelayFlash its ath_hal_delay(int n) /* Delay n microseconds */
> > > > I use non Linux OS ...
> > > >
> > > > ar5212SetChannel5112work2192(2192); //set freq 2192 MHz
> > > > ar5212SetChannel5112work2192(2195); //set freq 2195 MHz
> > > > ...
> > > > ar5212SetChannel5112work2192(2512); //set freq 2512 MHz
> > > >
> > > > and hard_reg ...
> > > > 0xB8510024 its AR_IER                  0x0024  /* MAC Interrupt enable
> > > > register */
> > > > 0xb851981c its AR_PHY_ACTIVE           0x981C  /* activation register
> > */
> > > > 0xb8519860 its AR_PHY_AGC_CONTROL      0x9860  /* chip calibration and
> > > > noise floor setting */
> > > >
> > > > 0xb851989C & 0xb85198D8  its regs for internal use ...
> > > >
> > > >
> > > > -----Original Message-----
> > > > From: Vishal Sevani <vishal.sevani@gmail.com>
> > > > To: madwifi-users@lists.sourceforge.net
> > > > Date: Tue, 23 Feb 2010 12:05:05 +0530
> > > > Subject: Re: [Madwifi-users] Fast channel switching
> > > >
> > > > > On Mon, Feb 22, 2010 at 10:19 PM, IVAN KORSHUN <2002_ivan@mail.ru>
> > > > wrote:
> > > > >
> > > > > > void ar5212SetChannel5112work2192(UINT32 freq)
> > > > > > {
> > > > > > /* Step 5 MHz */
> > > > > >           UINT32       ii,channelSelect;
> > > > > > volatile   UINT32 *hard_reg;
> > > > > >
> > > > > >        channelSelect = ((freq - 672) * 2 - 3040)/10;
> > > > > >            channelSelect = (channelSelect << 2) & 0xff;
> > > > > >            channelSelect = ath_hal_reverseBits(channelSelect, 8);
> > > > > >
> > > > > >
> > > > > >        channelSelect = (channelSelect << 4) | 0x1005;
> > > > > >
> > > > > >        hard_reg = (void*)0xB8510024; *hard_reg = 0x0;
> > > > > >        sysUDelayFlash (0x3E8);
> > > > > >        hard_reg = (void*)0xb851981c; *hard_reg = 0x0;
> > > > > >        sysUDelayFlash (0xA);
> > > > > >        hard_reg = (void*)0xb851989C; *hard_reg = (channelSelect &
> > > > 0xff);
> > > > > >
> > > > > >        channelSelect = (channelSelect >> 8) & 0x7f;
> > > > > >        hard_reg = (void*)0xb85198D8; *hard_reg = channelSelect;
> > > > > >        sysUDelayFlash (0xA);
> > > > > >        hard_reg = (void*)0xb851981c; *hard_reg = 0x1;
> > > > > >        sysUDelayFlash (0x64);
> > > > > >        hard_reg = (void*)0xb8519860;
> > > > > >        *hard_reg = *hard_reg |0x2;
> > > > > >        channelSelect = 0x2;
> > > > > >        for (ii=0; (ii< 0x3FFFE) && channelSelect
> > ;ii++)channelSelect =
> > > > > > *hard_reg & 0x2;
> > > > > >
> > > > > >        hard_reg = (void*)0xB8510024; *hard_reg = 0x1;
> > > > > >
> > > > > > }
> > > > > >
> > > > >
> > > > > Hi Ivan
> > > > >
> > > > > Do you intend to suggest that I can call this function directly for
> > > > > switching the frequency?? If so could you please explain as to what
> > the
> > > > > function does. You are setting the values for the variable, hard_reg
> > and
> > > > > channelSelect, but dont you need to set these values in the register
> > so
> > > > that
> > > > > the hardware actually changes the channel?
> > > > >
> > > > >  Also what is the definition for the function, sysUDelayFlash ()
> > since it
> > > > is
> > > > > not available in the madwifi code.
> > > > >