b43: N-PHY: add RSSI calculation for PHY rev < 3
PATCH 3/6 b43: N-PHY: add RSSI calculation for PHY rev < 3
--- drivers/net/wireless/b43/phy_n.c | 159 +++++++++++++++++++++++++++++++++++++- 1 files changed, 158 insertions(+), 1 deletions(-)
drivers/net/wireless/b43/phy_n.c +158 -1
@@ -810,7 +810,164 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ static void b43_nphy_rev2_rssi_cal (struct b43_wldev *dev,u8 type) { -//TODO +int i, j; +u8 state[4 ]; +u8 code, val; +u16 class, override; +u8 regs_save_radio[2 ]; +u16 regs_save_phy[2 ]; +s8 offset[4 ]; + +u16 clip_state[2 ]; +u16 clip_off[2 ] = {0xFFFF ,0xFFFF }; +s32 results_min[4 ]; +u8 vcm_final[4 ]; +s32 results[4 ][4 ]; +s32 miniq[4 ][2 ]; +memset (results_min,0 ,sizeof (s32) *4 ); +memset (vcm_final,0 ,sizeof (u8) *4 ); +memset (results,0 ,sizeof (s32) *4 *4 ); +memset (miniq,0 ,sizeof (s32) *4 *2 ); + +if (type ==2 ) { + code =0 ; + val =6 ; + }else if (type <2 ) { + code =25 ; + val =4 ; + }else { +B43_WARN_ON (1 ); +return ; + } + + class =b43_nphy_classifier (dev,0 ,0 ); +b43_nphy_classifier (dev,7 ,4 ); +b43_nphy_read_clip_detection (dev, clip_state); +b43_nphy_write_clip_detection (dev, clip_off); + +if (b43_current_band (dev->wl) ==IEEE80211_BAND_5GHZ ) + override =0x140 ; +else + override =0x110 ; + + regs_save_phy[0 ] =b43_phy_read (dev,B43_NPHY_RFCTL_INTC1 ); + regs_save_radio[0 ] =b43_radio_read16 (dev,B2055_C1_PD_RXTX ); +b43_phy_write (dev,B43_NPHY_RFCTL_INTC1 , override); +b43_radio_write16 (dev,B2055_C1_PD_RXTX , val); + + regs_save_phy[1 ] =b43_phy_read (dev,B43_NPHY_RFCTL_INTC2 ); + regs_save_radio[1 ] =b43_radio_read16 (dev,B2055_C2_PD_RXTX ); +b43_phy_write (dev,B43_NPHY_RFCTL_INTC2 , override); +b43_radio_write16 (dev,B2055_C2_PD_RXTX , val); + + state[0 ] =b43_radio_read16 (dev,B2055_C1_PD_RSSIMISC ) &0x07 ; + state[1 ] =b43_radio_read16 (dev,B2055_C2_PD_RSSIMISC ) &0x07 ; +b43_radio_maskset (dev,B2055_C1_PD_RSSIMISC ,0xF8 ,0 ); +b43_radio_maskset (dev,B2055_C2_PD_RSSIMISC ,0xF8 ,0 ); + state[2 ] =b43_radio_read16 (dev,B2055_C1_SP_RSSI ) &0x07 ; + state[3 ] =b43_radio_read16 (dev,B2055_C2_SP_RSSI ) &0x07 ; + +b43_nphy_rssi_select (dev,5 , type); +b43_nphy_scale_offset_rssi (dev,0 ,0 ,5 ,0 , type); +b43_nphy_scale_offset_rssi (dev,0 ,0 ,5 ,1 , type); + +for (i =0 ; i <4 ; i++) { +u8 tmp[4 ]; +for (j =0 ; j <4 ; j++) + tmp[j] = i; +if (type !=1 ) +b43_nphy_set_rssi_2055_vcm (dev, type, tmp); +b43_nphy_poll_rssi (dev, type, results[i],8 ); +if (type <2 ) +for (j =0 ; j <2 ; j++) + miniq[i][j] =min (results[i][2 * j], + results[i][2 * j +1 ]); + } + +for (i =0 ; i <4 ; i++) { +s32 mind =40 ; +u8 minvcm =0 ; +s32 minpoll =249 ; +s32 curr; +for (j =0 ; j <4 ; j++) { +if (type ==2 ) + curr =abs (results[j][i]); +else + curr =abs (miniq[j][i /2 ] - code *8 ); + +if (curr < mind) { + mind = curr; + minvcm = j; + } + +if (results[j][i] < minpoll) + minpoll = results[j][i]; + } + results_min[i] = minpoll; + vcm_final[i] = minvcm; + } + +if (type !=1 ) +b43_nphy_set_rssi_2055_vcm (dev, type, vcm_final); + +for (i =0 ; i <4 ; i++) { + offset[i] = (code *8 ) - results[vcm_final[i]][i]; + +if (offset[i] <0 ) + offset[i] = -((abs (offset[i]) +4 ) /8 ); +else + offset[i] = (offset[i] +4 ) /8 ; + +if (results_min[i] ==248 ) + offset[i] = code -32 ; + +if (i %2 ==0 ) +b43_nphy_scale_offset_rssi (dev,0 , offset[i],1 ,0 , + type); +else +b43_nphy_scale_offset_rssi (dev,0 , offset[i],2 ,1 , + type); + } + +b43_radio_maskset (dev,B2055_C1_PD_RSSIMISC ,0xF8 , state[0 ]); +b43_radio_maskset (dev,B2055_C1_PD_RSSIMISC ,0xF8 , state[1 ]); + +switch (state[2 ]) { +case 1 : +b43_nphy_rssi_select (dev,1 ,2 ); +break ; +case 4 : +b43_nphy_rssi_select (dev,1 ,0 ); +break ; +case 2 : +b43_nphy_rssi_select (dev,1 ,1 ); +break ; +default : +b43_nphy_rssi_select (dev,1 ,1 ); +break ; + } + +switch (state[3 ]) { +case 1 : +b43_nphy_rssi_select (dev,2 ,2 ); +break ; +case 4 : +b43_nphy_rssi_select (dev,2 ,0 ); +break ; +default : +b43_nphy_rssi_select (dev,2 ,1 ); +break ; + } + +b43_nphy_rssi_select (dev,0 , type); + +b43_phy_write (dev,B43_NPHY_RFCTL_INTC1 , regs_save_phy[0 ]); +b43_radio_write16 (dev,B2055_C1_PD_RXTX , regs_save_radio[0 ]); +b43_phy_write (dev,B43_NPHY_RFCTL_INTC2 , regs_save_phy[1 ]); +b43_radio_write16 (dev,B2055_C2_PD_RXTX , regs_save_radio[1 ]); + +b43_nphy_classifier (dev,7 , class); +b43_nphy_write_clip_detection (dev, clip_state); }/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
Signature · 1 line
1.6.4.2
drivers/net/wireless/b43/phy_n.c static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, · line 830
Quoted 8 lines · On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
drivers/net/wireless/b43/phy_n.c +8
-0+s32 results_min[4 ]; +u8 vcm_final[4 ]; +s32 results[4 ][4 ]; +s32 miniq[4 ][2 ]; +memset (results_min,0 ,sizeof (s32) *4 ); +memset (vcm_final,0 ,sizeof (u8) *4 ); +memset (results,0 ,sizeof (s32) *4 *4 ); +memset (miniq,0 ,sizeof (s32) *4 *2 );
Just initialize the variables to zero instead of doing a memset:
+ s32 results_min[4] = { 0, };
+ u8 vcm_final[4] = { 0, };
+ s32 results[4][4] = { 0, };
+ s32 miniq[4][2] = { 0, };
drivers/net/wireless/b43/phy_n.c static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, · line 866
Quoted 2 lines
drivers/net/wireless/b43/phy_n.c +2
-0+b43_radio_maskset (dev,B2055_C1_PD_RSSIMISC ,0xF8 ,0 ); +b43_radio_maskset (dev,B2055_C2_PD_RSSIMISC ,0xF8 ,0 );
If you don't set anything, you can useb43_radio_mask();
Signature · 1 line
Greetings, Michael.
2010/1/10 Michael Buesch <[email protected]>:
Quoted 10 lines · On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
Quoted 8 lines
+ s32 results_min[4];
+ u8 vcm_final[4];
+ s32 results[4][4];
+ s32 miniq[4][2];
+memset(results_min, 0, sizeof(s32) * 4);
+memset(vcm_final, 0, sizeof(u8) * 4);
+memset(results, 0, sizeof(s32) * 4 * 4);
+memset(miniq, 0, sizeof(s32) * 4 * 2);
Quoted 6 lines
Just initialize the variables to zero instead of doing a memset:
+ s32 results_min[4] = { 0, };
+ u8 vcm_final[4] = { 0, };
+ s32 results[4][4] = { 0, };
+ s32 miniq[4][2] = { 0, };
Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
I believe.
Quoted 5 lines
Quoted 2 lines
+
b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, 0);
+b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, 0);If you don't set anything, you can use
b43_radio_mask();
Sure I can ;) Thanks.
Signature · 1 line
Rafał
Quoted 13 lines · On Monday 11 January 2010 22:13:31 Rafał Miłecki wrote:
2010/1/10 Michael Buesch <[email protected]>:
Quoted 12 lines · On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
Quoted 8 lines
+ s32 results_min[4];
+ u8 vcm_final[4];
+ s32 results[4][4];
+ s32 miniq[4][2];
+memset(results_min, 0, sizeof(s32) * 4);
+memset(vcm_final, 0, sizeof(u8) * 4);
+memset(results, 0, sizeof(s32) * 4 * 4);
+memset(miniq, 0, sizeof(s32) * 4 * 2);Just initialize the variables to zero instead of doing a memset:
Quoted 8 lines
Quoted 4 lines
+ s32 results_min[4] = { 0, };
+ u8 vcm_final[4] = { 0, };
+ s32 results[4][4] = { 0, };
+ s32 miniq[4][2] = { 0, };Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
I believe.
No I don't think so.
It's C standard that uninitialized elements on automatic variables are initialized to zero, _if_ at least one element is initialized to something.
So if you init one element to 0, all others will be 0, too.
I think that should also work for multidimensional arrays. So my example s32 results[4][4] = { 0, };
should do the right thing. Am I wrong?
Here's a test-program:
mb@maggie:~$ cat t.c #include <stdio.h> #include <stdint.h>
int main(void)
{
int i, j;
int32_t results[4][4]#ifdef INIT_IT
= { 0, };
#else
;
#endif
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
printf("%d\n", results[i][j]);}
mb@maggie:~$ gcc -o t t.c mb@maggie:~$ ./t 0 0 0 1 -1077483840 0 0 0 -1077483824 268436224 268536212 0 -1077483776 268436888 268353524 0 mb@maggie:~$ gcc -D INIT_IT -o t t.c mb@maggie:~$ ./t 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Signature · 1 line
Greetings, Michael.
Johannes Berg
maintainerQuoted 5 lines · Michael Buesch
No I don't think so.
It's C standard that uninitialized elements on automatic variables are initialized
to zero, _if_ at least one element is initialized to something. So if you init one element to 0, all others will be 0, too.
AFAIK, you don't even have to init anything, since otherwise not mentioned fields will be set to 0. Hence, just = {} is sufficient for arrays and will hopefully compile to the same code as an explicit memset().
johannes
Quoted 8 lines · On Monday 11 January 2010 23:19:52 Johannes Berg wrote:
Quoted 5 lines · Michael Buesch
No I don't think so.
It's C standard that uninitialized elements on automatic variables are initialized
to zero, _if_ at least one element is initialized to something. So if you init one element to 0, all others will be 0, too.
Quoted 4 lines
AFAIK, you don't even have to init anything, since otherwise not mentioned fields will be set to 0. Hence, just = {} is sufficient for arrays and will hopefully compile to the same code as an explicit
memset().
Oh, nice. You are right, indeed. I didn't know that.
Signature · 1 line
Greetings, Michael.
Quoted 23 lines · W dniu 11 stycznia 2010 23:13 użytkownik Michael Buesch <[email protected]> napisał:
Quoted 13 lines · On Monday 11 January 2010 22:13:31 Rafał Miłecki wrote:
2010/1/10 Michael Buesch <[email protected]>:
Quoted 12 lines · On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
Quoted 8 lines
+ s32 results_min[4];
+ u8 vcm_final[4];
+ s32 results[4][4];
+ s32 miniq[4][2];
+memset(results_min, 0, sizeof(s32) * 4);
+memset(vcm_final, 0, sizeof(u8) * 4);
+memset(results, 0, sizeof(s32) * 4 * 4);
+memset(miniq, 0, sizeof(s32) * 4 * 2);Just initialize the variables to zero instead of doing a memset:
Quoted 8 lines
Quoted 4 lines
+ s32 results_min[4] = { 0, };
+ u8 vcm_final[4] = { 0, };
+ s32 results[4][4] = { 0, };
+ s32 miniq[4][2] = { 0, };Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
I believe.
Quoted 7 lines
No I don't think so.
It's C standard that uninitialized elements on automatic variables are initialized to zero, _if_ at least one element is initialized to something.
So if you init one element to 0, all others will be 0, too.
I think that should also work for multidimensional arrays. So my example s32 results[4][4] = { 0, };
should do the right thing. Am I wrong?
Whoops, I should have explained what I mean. I am not sure what CFLAGS "make" picks for compiled but I get:
CC [M] drivers/net/wireless/b43/phy_n.odrivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializer drivers/net/wireless/b43/phy_n.c:887: warning: (near initialization for ‘results[0]’)
for s32 results[4][4] = { 0, };
Signature · 1 line
Rafał
Quoted 11 lines · On Monday 11 January 2010 23:27:18 Rafał Miłecki wrote:
Whoops, I should have explained what I mean. I am not sure what CFLAGS "make" picks for compiled but I get:
CC [M]
drivers/net/wireless/b43/phy_n.odrivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializerdrivers/net/wireless/b43/phy_n.c:887: warning: (near initialization for ‘results[0]’)for s32 results[4][4] = { 0, };
But does this work?
s32 results[4][4] = { };
Signature · 1 line
Greetings, Michael.
Quoted 10 lines · W dniu 11 stycznia 2010 23:42 użytkownik Michael Buesch <[email protected]> napisał:
Quoted 9 lines · On Monday 11 January 2010 23:27:18 Rafał Miłecki wrote:
Whoops, I should have explained what I mean. I am not sure what CFLAGS "make" picks for compiled but I get:
CC [M] drivers/net/wireless/b43/phy_n.o
drivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializerdrivers/net/wireless/b43/phy_n.c:887: warning: (near initialization for ‘results[0]’)
Quoted 5 lines
Quoted 2 lines
for s32 results[4][4] = { 0, };
But does this work?
s32 results[4][4] = { };
Yes, this compiles fine, and I believe it works fine :)
Signature · 1 line
Rafał