Re: Fast channel switching

Vishal Sevani <[email protected]> Tue, 23 Mar 2010 20:36:53 +0530
Newsgroups gmane.linux.drivers.madwifi.user
Message-ID <[email protected]>
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 <[email protected]>
>>
>> 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 <[email protected]>
>>> 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 <[email protected]>
>>> 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 <[email protected]>
>>> > > > > To: [email protected]
>>> > > > > 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 <
>>> [email protected]>
>>> > > > > 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.
>>> > > > > >
>>>
>>

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev

_______________________________________________
Madwifi-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/madwifi-users