Thread: Re: [Madwifi-users] Fast channel switching
Status: Beta
Brought to you by:
otaku
From: Vishal S. <vis...@gm...> - 2010-03-23 15:07:00
|
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 <200...@ma...> >> >> 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 <200...@ma...> >>> 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 <200...@ma...> >>> 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 <vis...@gm...> >>> > > > > To: mad...@li... >>> > > > > 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 < >>> 200...@ma...> >>> > > > > 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. >>> > > > > > >>> >> |
From: Vishal S. <vis...@gm...> - 2010-03-25 04:59:18
|
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 <vis...@gm...>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 <200...@ma...> >>> >>> 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 <200...@ma...> >>>> 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 <200...@ma...> >>>> 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 <vis...@gm...> >>>> > > > > To: mad...@li... >>>> > > > > 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 < >>>> 200...@ma...> >>>> > > > > 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. >>>> > > > > > >>>> >>> |