Merge git://git.infradead.org/mtd-2.6
[linux-2.6] / drivers / staging / winbond / wbhal.c
1 #include "os_common.h"
2
3 void hal_get_ethernet_address( phw_data_t pHwData, u8 *current_address )
4 {
5         if( pHwData->SurpriseRemove ) return;
6
7         memcpy( current_address, pHwData->CurrentMacAddress, ETH_LENGTH_OF_ADDRESS );
8 }
9
10 void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
11 {
12         u32 ltmp[2];
13
14         if( pHwData->SurpriseRemove ) return;
15
16         memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
17
18         ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress );
19         ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
20
21         Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
22 }
23
24 void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
25 {
26         if( pHwData->SurpriseRemove ) return;
27
28         memcpy( pethernet_address, pHwData->PermanentMacAddress, 6 );
29 }
30
31 u8 hal_init_hardware(phw_data_t pHwData, PWB32_ADAPTER Adapter)
32 {
33         u16 SoftwareSet;
34         pHwData->Adapter = Adapter;
35
36         // Initial the variable
37         pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; // Setting Rx maximum MSDU life time
38         pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; // Setting default fragment threshold
39
40         if (WbUsb_initial(pHwData)) {
41                 pHwData->InitialResource = 1;
42                 if( Wb35Reg_initial(pHwData)) {
43                         pHwData->InitialResource = 2;
44                         if (Wb35Tx_initial(pHwData)) {
45                                 pHwData->InitialResource = 3;
46                                 if (Wb35Rx_initial(pHwData)) {
47                                         pHwData->InitialResource = 4;
48                                         OS_TIMER_INITIAL( &pHwData->LEDTimer, hal_led_control, pHwData );
49                                         OS_TIMER_SET( &pHwData->LEDTimer, 1000 ); // 20060623
50
51                                         //
52                                         // For restrict to vendor's hardware
53                                         //
54                                         SoftwareSet = hal_software_set( pHwData );
55
56                                         #ifdef Vendor2
57                                         // Try to make sure the EEPROM contain
58                                         SoftwareSet >>= 8;
59                                         if( SoftwareSet != 0x82 )
60                                                 return FALSE;
61                                         #endif
62
63                                         Wb35Rx_start( pHwData );
64                                         Wb35Tx_EP2VM_start( pHwData );
65
66                                         return TRUE;
67                                 }
68                         }
69                 }
70         }
71
72         pHwData->SurpriseRemove = 1;
73         return FALSE;
74 }
75
76
77 void hal_halt(phw_data_t pHwData, void *ppa_data)
78 {
79         switch( pHwData->InitialResource )
80         {
81                 case 4:
82                 case 3: OS_TIMER_CANCEL( &pHwData->LEDTimer, &cancel );
83                         OS_SLEEP(100000); // Wait for Timer DPC exit 940623.2
84                         Wb35Rx_destroy( pHwData ); // Release the Rx
85                 case 2: Wb35Tx_destroy( pHwData ); // Release the Tx
86                 case 1: Wb35Reg_destroy( pHwData ); // Release the Wb35 Regisster resources
87                                 WbUsb_destroy( pHwData );// Release the WbUsb
88         }
89 }
90
91 //---------------------------------------------------------------------------------------------------
92 void hal_set_rates(phw_data_t pHwData, u8 *pbss_rates,
93                    u8 length, unsigned char basic_rate_set)
94 {
95         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
96         u32             tmp, tmp1;
97         u8              Rate[12]={ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
98         u8              SupportedRate[16];
99         u8              i, j, k, Count1, Count2, Byte;
100
101         if( pHwData->SurpriseRemove ) return;
102
103         if (basic_rate_set) {
104                 pWb35Reg->M28_MacControl &= ~0x000fff00;
105                 tmp1 = 0x00000100;
106         } else {
107                 pWb35Reg->M28_MacControl &= ~0xfff00000;
108                 tmp1 = 0x00100000;
109         }
110
111         tmp = 0;
112         for (i=0; i<length; i++) {
113                 Byte = pbss_rates[i] & 0x7f;
114                 for (j=0; j<12; j++) {
115                         if( Byte == Rate[j] )
116                                 break;
117                 }
118
119                 if (j < 12)
120                         tmp |= (tmp1<<j);
121         }
122
123         pWb35Reg->M28_MacControl |= tmp;
124         Wb35Reg_Write( pHwData, 0x0828, pWb35Reg->M28_MacControl );
125
126         // 930206.2.c M78 setting
127         j = k = Count1 = Count2 = 0;
128         memset( SupportedRate, 0, 16 );
129         tmp = 0x00100000;
130         tmp1 = 0x00000100;
131         for (i=0; i<12; i++) { // Get the supported rate
132                 if (tmp & pWb35Reg->M28_MacControl) {
133                         SupportedRate[j] = Rate[i];
134
135                         if (tmp1 & pWb35Reg->M28_MacControl)
136                                 SupportedRate[j] |= 0x80;
137
138                         if (k)
139                                 Count2++;
140                         else
141                                 Count1++;
142
143                         j++;
144                 }
145
146                 if (i==4 && k==0) {
147                         if( !(pWb35Reg->M28_MacControl & 0x000ff000) ) // if basic rate in 11g domain)
148                         {
149                                 k = 1;
150                                 j = 8;
151                         }
152                 }
153
154                 tmp <<= 1;
155                 tmp1 <<= 1;
156         }
157
158         // Fill data into support rate until buffer full
159         //---20060926 add by anson's endian
160         for (i=0; i<4; i++)
161                 *(u32 *)(SupportedRate+(i<<2)) = cpu_to_le32( *(u32 *)(SupportedRate+(i<<2)) );
162         //--- end 20060926 add by anson's endian
163         Wb35Reg_BurstWrite( pHwData,0x087c, (u32 *)SupportedRate, 4, AUTO_INCREMENT );
164         pWb35Reg->M7C_MacControl = ((u32 *)SupportedRate)[0];
165         pWb35Reg->M80_MacControl = ((u32 *)SupportedRate)[1];
166         pWb35Reg->M84_MacControl = ((u32 *)SupportedRate)[2];
167         pWb35Reg->M88_MacControl = ((u32 *)SupportedRate)[3];
168
169         // Fill length
170         tmp = Count1<<28 | Count2<<24;
171         pWb35Reg->M78_ERPInformation &= ~0xff000000;
172         pWb35Reg->M78_ERPInformation |= tmp;
173         Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
174 }
175
176
177 //---------------------------------------------------------------------------------------------------
178 void hal_set_beacon_period(  phw_data_t pHwData,  u16 beacon_period )
179 {
180         u32     tmp;
181
182         if( pHwData->SurpriseRemove ) return;
183
184         pHwData->BeaconPeriod = beacon_period;
185         tmp = pHwData->BeaconPeriod << 16;
186         tmp |= pHwData->ProbeDelay;
187         Wb35Reg_Write( pHwData, 0x0848, tmp );
188 }
189
190
191 void hal_set_current_channel_ex(  phw_data_t pHwData,  ChanInfo channel )
192 {
193         PWB35REG pWb35Reg = &pHwData->Wb35Reg;
194
195         if( pHwData->SurpriseRemove )
196                 return;
197
198         printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
199
200         RFSynthesizer_SwitchingChannel( pHwData, channel );// Switch channel
201         pHwData->Channel = channel.ChanNo;
202         pHwData->band = channel.band;
203         #ifdef _PE_STATE_DUMP_
204         WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band));
205         #endif
206         pWb35Reg->M28_MacControl &= ~0xff; // Clean channel information field
207         pWb35Reg->M28_MacControl |= channel.ChanNo;
208         Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, pWb35Reg->M28_MacControl,
209                                         (s8 *)&channel, sizeof(ChanInfo));
210 }
211 //---------------------------------------------------------------------------------------------------
212 void hal_set_current_channel(  phw_data_t pHwData,  ChanInfo channel )
213 {
214         hal_set_current_channel_ex( pHwData, channel );
215 }
216 //---------------------------------------------------------------------------------------------------
217 void hal_get_current_channel(  phw_data_t pHwData,  ChanInfo *channel )
218 {
219         channel->ChanNo = pHwData->Channel;
220         channel->band = pHwData->band;
221 }
222 //---------------------------------------------------------------------------------------------------
223 void hal_set_accept_broadcast(  phw_data_t pHwData,  u8 enable )
224 {
225         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
226
227         if( pHwData->SurpriseRemove ) return;
228
229         pWb35Reg->M00_MacControl &= ~0x02000000;//The HW value
230
231         if (enable)
232                 pWb35Reg->M00_MacControl |= 0x02000000;//The HW value
233
234         Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
235 }
236
237 //for wep key error detection, we need to accept broadcast packets to be received temporary.
238 void hal_set_accept_promiscuous( phw_data_t pHwData,  u8 enable)
239 {
240         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
241
242         if (pHwData->SurpriseRemove) return;
243         if (enable) {
244                 pWb35Reg->M00_MacControl |= 0x00400000;
245                 Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
246         } else {
247                 pWb35Reg->M00_MacControl&=~0x00400000;
248                 Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
249         }
250 }
251
252 void hal_set_accept_multicast(  phw_data_t pHwData,  u8 enable )
253 {
254         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
255
256         if( pHwData->SurpriseRemove ) return;
257
258         pWb35Reg->M00_MacControl &= ~0x01000000;//The HW value
259         if (enable)  pWb35Reg->M00_MacControl |= 0x01000000;//The HW value
260         Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
261 }
262
263 void hal_set_accept_beacon(  phw_data_t pHwData,  u8 enable )
264 {
265         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
266
267         if( pHwData->SurpriseRemove ) return;
268
269         // 20040108 debug
270         if( !enable )//Due to SME and MLME are not suitable for 35
271                 return;
272
273         pWb35Reg->M00_MacControl &= ~0x04000000;//The HW value
274         if( enable )
275                 pWb35Reg->M00_MacControl |= 0x04000000;//The HW value
276
277         Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
278 }
279 //---------------------------------------------------------------------------------------------------
280 void hal_set_multicast_address( phw_data_t pHwData, u8 *address, u8 number )
281 {
282         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
283         u8              Byte, Bit;
284
285         if( pHwData->SurpriseRemove ) return;
286
287         //Erases and refills the card multicast registers. Used when an address
288         //    has been deleted and all bits must be recomputed.
289         pWb35Reg->M04_MulticastAddress1 = 0;
290         pWb35Reg->M08_MulticastAddress2 = 0;
291
292         while( number )
293         {
294                 number--;
295                 CardGetMulticastBit( (address+(number*ETH_LENGTH_OF_ADDRESS)), &Byte, &Bit);
296                 pWb35Reg->Multicast[Byte] |= Bit;
297         }
298
299         // Updating register
300         Wb35Reg_BurstWrite( pHwData, 0x0804, (u32 *)pWb35Reg->Multicast, 2, AUTO_INCREMENT );
301 }
302 //---------------------------------------------------------------------------------------------------
303 u8 hal_get_accept_beacon(  phw_data_t pHwData )
304 {
305         PWB35REG pWb35Reg = &pHwData->Wb35Reg;
306
307         if( pHwData->SurpriseRemove ) return 0;
308
309         if( pWb35Reg->M00_MacControl & 0x04000000 )
310                 return 1;
311         else
312                 return 0;
313 }
314
315 unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa )
316 {
317         // Not implement yet
318         return TRUE;
319 }
320
321 void hal_stop(  phw_data_t pHwData )
322 {
323         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
324
325         pHwData->Wb35Rx.rx_halt = 1;
326         Wb35Rx_stop( pHwData );
327
328         pHwData->Wb35Tx.tx_halt = 1;
329         Wb35Tx_stop( pHwData );
330
331         pWb35Reg->D00_DmaControl &= ~0xc0000000;//Tx Off, Rx Off
332         Wb35Reg_Write( pHwData, 0x0400, pWb35Reg->D00_DmaControl );
333
334         WbUsb_Stop( pHwData ); // 20051230 Add.4
335 }
336
337 unsigned char hal_idle(phw_data_t pHwData)
338 {
339         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
340         PWBUSB  pWbUsb = &pHwData->WbUsb;
341
342         if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || pWb35Reg->EP0vm_state!=VM_STOP ) )
343                 return FALSE;
344
345         return TRUE;
346 }
347 //---------------------------------------------------------------------------------------------------
348 void hal_set_cwmin(  phw_data_t pHwData,  u8    cwin_min )
349 {
350         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
351
352         if( pHwData->SurpriseRemove ) return;
353
354         pHwData->cwmin = cwin_min;
355         pWb35Reg->M2C_MacControl &= ~0x7c00;    //bit 10 ~ 14
356         pWb35Reg->M2C_MacControl |= (pHwData->cwmin<<10);
357         Wb35Reg_Write( pHwData, 0x082c, pWb35Reg->M2C_MacControl );
358 }
359
360 s32 hal_get_rssi(  phw_data_t pHwData,  u32 *HalRssiArry,  u8 Count )
361 {
362         PWB35REG pWb35Reg = &pHwData->Wb35Reg;
363         R01_DESCRIPTOR  r01;
364         s32 ltmp = 0, tmp;
365         u8      i;
366
367         if( pHwData->SurpriseRemove ) return -200;
368         if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
369                 Count = MAX_ACC_RSSI_COUNT;
370
371         // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
372         // C1 = -195, C2 = 0.66 = 85/128
373         for (i=0; i<Count; i++)
374         {
375                 r01.value = HalRssiArry[i];
376                 tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
377                 ltmp += tmp;
378         }
379         ltmp /= Count;
380         if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
381         if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
382
383         //if( ltmp < -200 ) ltmp = -200;
384         if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
385
386         return ltmp;
387 }
388 //----------------------------------------------------------------------------------------------------
389 s32 hal_get_rssi_bss(  phw_data_t pHwData,  u16 idx,  u8 Count )
390 {
391         PWB35REG pWb35Reg = &pHwData->Wb35Reg;
392         R01_DESCRIPTOR  r01;
393         s32 ltmp = 0, tmp;
394         u8      i, j;
395         PADAPTER        Adapter = pHwData->Adapter;
396 //      u32 *HalRssiArry = psBSS(idx)->HalRssi;
397
398         if( pHwData->SurpriseRemove ) return -200;
399         if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
400                 Count = MAX_ACC_RSSI_COUNT;
401
402         // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
403         // C1 = -195, C2 = 0.66 = 85/128
404 #if 0
405         for (i=0; i<Count; i++)
406         {
407                 r01.value = HalRssiArry[i];
408                 tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
409                 ltmp += tmp;
410         }
411 #else
412         if (psBSS(idx)->HalRssiIndex == 0)
413                 psBSS(idx)->HalRssiIndex = MAX_ACC_RSSI_COUNT;
414         j = (u8)psBSS(idx)->HalRssiIndex-1;
415
416         for (i=0; i<Count; i++)
417         {
418                 r01.value = psBSS(idx)->HalRssi[j];
419                 tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
420                 ltmp += tmp;
421                 if (j == 0)
422                 {
423                         j = MAX_ACC_RSSI_COUNT;
424                 }
425                 j--;
426         }
427 #endif
428         ltmp /= Count;
429         if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
430         if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
431
432         //if( ltmp < -200 ) ltmp = -200;
433         if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
434
435         return ltmp;
436 }
437
438 //---------------------------------------------------------------------------
439 void hal_led_control_1a(  phw_data_t pHwData )
440 {
441         hal_led_control( NULL, pHwData, NULL, NULL );
442 }
443
444 void hal_led_control(  void* S1,  phw_data_t pHwData,  void* S3,  void* S4 )
445 {
446         PADAPTER        Adapter = pHwData->Adapter;
447         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
448         u32     LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
449         u8      LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
450         u8      LEDgray2[30] = { 7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,15,14,13,12,11,10,9,8 };
451         u32     TimeInterval = 500, ltmp, ltmp2;
452         ltmp=0;
453
454         if( pHwData->SurpriseRemove ) return;
455
456         if( pHwData->LED_control ) {
457                 ltmp2 = pHwData->LED_control & 0xff;
458                 if( ltmp2 == 5 ) // 5 is WPS mode
459                 {
460                         TimeInterval = 100;
461                         ltmp2 = (pHwData->LED_control>>8) & 0xff;
462                         switch( ltmp2 )
463                         {
464                                 case 1: // [0.2 On][0.1 Off]...
465                                         pHwData->LED_Blinking %= 3;
466                                         ltmp = 0x1010; // Led 1 & 0 Green and Red
467                                         if( pHwData->LED_Blinking == 2 ) // Turn off
468                                                 ltmp = 0;
469                                         break;
470                                 case 2: // [0.1 On][0.1 Off]...
471                                         pHwData->LED_Blinking %= 2;
472                                         ltmp = 0x0010; // Led 0 red color
473                                         if( pHwData->LED_Blinking ) // Turn off
474                                                 ltmp = 0;
475                                         break;
476                                 case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]...
477                                         pHwData->LED_Blinking %= 15;
478                                         ltmp = 0x0010; // Led 0 red color
479                                         if( (pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking%2) ) // Turn off 0.6 sec
480                                                 ltmp = 0;
481                                         break;
482                                 case 4: // [300 On][ off ]
483                                         ltmp = 0x1000; // Led 1 Green color
484                                         if( pHwData->LED_Blinking >= 3000 )
485                                                 ltmp = 0; // led maybe on after 300sec * 32bit counter overlap.
486                                         break;
487                         }
488                         pHwData->LED_Blinking++;
489
490                         pWb35Reg->U1BC_LEDConfigure = ltmp;
491                         if( LEDSet != 7 ) // Only 111 mode has 2 LEDs on PCB.
492                         {
493                                 pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff)<<8; // Copy LED result to each LED control register
494                                 pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff00)>>8;
495                         }
496                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
497                 }
498         }
499         else if( pHwData->CurrentRadioSw || pHwData->CurrentRadioHw ) // If radio off
500         {
501                 if( pWb35Reg->U1BC_LEDConfigure & 0x1010 )
502                 {
503                         pWb35Reg->U1BC_LEDConfigure &= ~0x1010;
504                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
505                 }
506         }
507         else
508         {
509                 switch( LEDSet )
510                 {
511                         case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
512                                 if( !pHwData->LED_LinkOn ) // Blink only if not Link On
513                                 {
514                                         // Blinking if scanning is on progress
515                                         if( pHwData->LED_Scanning )
516                                         {
517                                                 if( pHwData->LED_Blinking == 0 )
518                                                 {
519                                                         pWb35Reg->U1BC_LEDConfigure |= 0x10;
520                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
521                                                         pHwData->LED_Blinking = 1;
522                                                         TimeInterval = 300;
523                                                 }
524                                                 else
525                                                 {
526                                                         pWb35Reg->U1BC_LEDConfigure &= ~0x10;
527                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
528                                                         pHwData->LED_Blinking = 0;
529                                                         TimeInterval = 300;
530                                                 }
531                                         }
532                                         else
533                                         {
534                                                 //Turn Off LED_0
535                                                 if( pWb35Reg->U1BC_LEDConfigure & 0x10 )
536                                                 {
537                                                         pWb35Reg->U1BC_LEDConfigure &= ~0x10;
538                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
539                                                 }
540                                         }
541                                 }
542                                 else
543                                 {
544                                         // Turn On LED_0
545                                         if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
546                                         {
547                                                 pWb35Reg->U1BC_LEDConfigure |= 0x10;
548                                                 Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
549                                         }
550                                 }
551                                 break;
552
553                         case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
554                                 if( !pHwData->LED_LinkOn ) // Blink only if not Link On
555                                 {
556                                         // Blinking if scanning is on progress
557                                         if( pHwData->LED_Scanning )
558                                         {
559                                                 if( pHwData->LED_Blinking == 0 )
560                                                 {
561                                                         pWb35Reg->U1BC_LEDConfigure &= ~0xf;
562                                                         pWb35Reg->U1BC_LEDConfigure |= 0x10;
563                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
564                                                         pHwData->LED_Blinking = 1;
565                                                         TimeInterval = 300;
566                                                 }
567                                                 else
568                                                 {
569                                                         pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
570                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
571                                                         pHwData->LED_Blinking = 0;
572                                                         TimeInterval = 300;
573                                                 }
574                                         }
575                                         else
576                                         {
577                                                 // 20060901 Gray blinking if in disconnect state and not scanning
578                                                 ltmp = pWb35Reg->U1BC_LEDConfigure;
579                                                 pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
580                                                 if( LEDgray2[(pHwData->LED_Blinking%30)] )
581                                                 {
582                                                         pWb35Reg->U1BC_LEDConfigure |= 0x10;
583                                                         pWb35Reg->U1BC_LEDConfigure |= LEDgray2[ (pHwData->LED_Blinking%30) ];
584                                                 }
585                                                 pHwData->LED_Blinking++;
586                                                 if( pWb35Reg->U1BC_LEDConfigure != ltmp )
587                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
588                                                 TimeInterval = 100;
589                                         }
590                                 }
591                                 else
592                                 {
593                                         // Turn On LED_0
594                                         if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
595                                         {
596                                                 pWb35Reg->U1BC_LEDConfigure |= 0x10;
597                                                 Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
598                                         }
599                                 }
600                                 break;
601
602                         case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
603                                 if( !pHwData->LED_LinkOn ) // Blink only if not Link On
604                                 {
605                                         // Blinking if scanning is on progress
606                                         if( pHwData->LED_Scanning )
607                                         {
608                                                 if( pHwData->LED_Blinking == 0 )
609                                                 {
610                                                         pWb35Reg->U1BC_LEDConfigure |= 0x1000;
611                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
612                                                         pHwData->LED_Blinking = 1;
613                                                         TimeInterval = 300;
614                                                 }
615                                                 else
616                                                 {
617                                                         pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
618                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
619                                                         pHwData->LED_Blinking = 0;
620                                                         TimeInterval = 300;
621                                                 }
622                                         }
623                                         else
624                                         {
625                                                 //Turn Off LED_1
626                                                 if( pWb35Reg->U1BC_LEDConfigure & 0x1000 )
627                                                 {
628                                                         pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
629                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
630                                                 }
631                                         }
632                                 }
633                                 else
634                                 {
635                                         // Is transmitting/receiving ??
636                                         if( (OS_CURRENT_RX_BYTE( Adapter ) != pHwData->RxByteCountLast ) ||
637                                                 (OS_CURRENT_TX_BYTE( Adapter ) != pHwData->TxByteCountLast ) )
638                                         {
639                                                 if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
640                                                 {
641                                                         pWb35Reg->U1BC_LEDConfigure |= 0x3000;
642                                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
643                                                 }
644
645                                                 // Update variable
646                                                 pHwData->RxByteCountLast = OS_CURRENT_RX_BYTE( Adapter );
647                                                 pHwData->TxByteCountLast = OS_CURRENT_TX_BYTE( Adapter );
648                                                 TimeInterval = 200;
649                                         }
650                                         else
651                                         {
652                                                 // Turn On LED_1 and blinking if transmitting/receiving
653                                                  if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x1000 )
654                                                  {
655                                                          pWb35Reg->U1BC_LEDConfigure &= ~0x3000;
656                                                          pWb35Reg->U1BC_LEDConfigure |= 0x1000;
657                                                          Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
658                                                  }
659                                         }
660                                 }
661                                 break;
662
663                         default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
664                                 if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
665                                 {
666                                         pWb35Reg->U1BC_LEDConfigure |= 0x3000;// LED_1 is always on and event enable
667                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
668                                 }
669
670                                 if( pHwData->LED_Blinking )
671                                 {
672                                         // Gray blinking
673                                         pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
674                                         pWb35Reg->U1BC_LEDConfigure |= 0x10;
675                                         pWb35Reg->U1BC_LEDConfigure |= LEDgray[ (pHwData->LED_Blinking-1)%20 ];
676                                         Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
677
678                                         pHwData->LED_Blinking += 2;
679                                         if( pHwData->LED_Blinking < 40 )
680                                                 TimeInterval = 100;
681                                         else
682                                         {
683                                                 pHwData->LED_Blinking = 0; // Stop blinking
684                                                 pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
685                                                 Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
686                                         }
687                                         break;
688                                 }
689
690                                 if( pHwData->LED_LinkOn )
691                                 {
692                                         if( !(pWb35Reg->U1BC_LEDConfigure & 0x10) ) // Check the LED_0
693                                         {
694                                                 //Try to turn ON LED_0 after gray blinking
695                                                 pWb35Reg->U1BC_LEDConfigure |= 0x10;
696                                                 pHwData->LED_Blinking = 1; //Start blinking
697                                                 TimeInterval = 50;
698                                         }
699                                 }
700                                 else
701                                 {
702                                         if( pWb35Reg->U1BC_LEDConfigure & 0x10 ) // Check the LED_0
703                                         {
704                                                 pWb35Reg->U1BC_LEDConfigure &= ~0x10;
705                                                 Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
706                                         }
707                                 }
708                                 break;
709                 }
710
711                 //20060828.1 Active send null packet to avoid AP disconnect
712                 if( pHwData->LED_LinkOn )
713                 {
714                         pHwData->NullPacketCount += TimeInterval;
715                         if( pHwData->NullPacketCount >= DEFAULT_NULL_PACKET_COUNT )
716                         {
717                                 pHwData->NullPacketCount = 0;
718                         }
719                 }
720         }
721
722         pHwData->time_count += TimeInterval;
723         Wb35Tx_CurrentTime( pHwData, pHwData->time_count ); // 20060928 add
724         OS_TIMER_SET( &pHwData->LEDTimer, TimeInterval ); // 20060623.1
725 }
726
727
728 void hal_set_phy_type(  phw_data_t pHwData,  u8 PhyType )
729 {
730         pHwData->phy_type = PhyType;
731 }
732
733 void hal_get_phy_type(  phw_data_t pHwData,  u8 *PhyType )
734 {
735         *PhyType = pHwData->phy_type;
736 }
737
738 void hal_reset_counter(  phw_data_t pHwData )
739 {
740         pHwData->dto_tx_retry_count = 0;
741         pHwData->dto_tx_frag_count = 0;
742         memset( pHwData->tx_retry_count, 0, 8);
743 }
744
745 void hal_set_radio_mode( phw_data_t pHwData,  unsigned char radio_off)
746 {
747         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
748
749         if( pHwData->SurpriseRemove ) return;
750
751         if (radio_off)  //disable Baseband receive off
752         {
753                 pHwData->CurrentRadioSw = 1; // off
754                 pWb35Reg->M24_MacControl &= 0xffffffbf;
755         }
756         else
757         {
758                 pHwData->CurrentRadioSw = 0; // on
759                 pWb35Reg->M24_MacControl |= 0x00000040;
760         }
761         Wb35Reg_Write( pHwData, 0x0824, pWb35Reg->M24_MacControl );
762 }
763
764 u8 hal_get_antenna_number(  phw_data_t pHwData )
765 {
766         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
767
768         if ((pWb35Reg->BB2C & BIT(11)) == 0)
769                 return 0;
770         else
771                 return 1;
772 }
773
774 void hal_set_antenna_number(  phw_data_t pHwData, u8 number )
775 {
776
777         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
778
779         if (number == 1) {
780                 pWb35Reg->BB2C |= BIT(11);
781         } else {
782                 pWb35Reg->BB2C &= ~BIT(11);
783         }
784         Wb35Reg_Write( pHwData, 0x102c, pWb35Reg->BB2C );
785 #ifdef _PE_STATE_DUMP_
786         WBDEBUG(("Current antenna number : %d\n", number));
787 #endif
788 }
789
790 //----------------------------------------------------------------------------------------------------
791 //0 : radio on; 1: radio off
792 u8 hal_get_hw_radio_off(  phw_data_t pHwData )
793 {
794         PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
795
796         if( pHwData->SurpriseRemove ) return 1;
797
798         //read the bit16 of register U1B0
799         Wb35Reg_Read( pHwData, 0x3b0, &pWb35Reg->U1B0 );
800         if ((pWb35Reg->U1B0 & 0x00010000)) {
801                 pHwData->CurrentRadioHw = 1;
802                 return 1;
803         } else {
804                 pHwData->CurrentRadioHw = 0;
805                 return 0;
806         }
807 }
808
809 unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 * pValue )
810 {
811         if( number < 0x1000 )
812                 number += 0x1000;
813         return Wb35Reg_ReadSync( pHwData, number, pValue );
814 }
815
816 unsigned char hal_set_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 value )
817 {
818         unsigned char   ret;
819
820         if( number < 0x1000 )
821                 number += 0x1000;
822         ret = Wb35Reg_WriteSync( pHwData, number, value );
823         return ret;
824 }
825
826 void hal_scan_status_indicate(phw_data_t pHwData, unsigned char IsOnProgress)
827 {
828         if( pHwData->SurpriseRemove ) return;
829         pHwData->LED_Scanning = IsOnProgress ? 1 : 0;
830 }
831
832 void hal_system_power_change(phw_data_t pHwData, u32 PowerState)
833 {
834         if( PowerState != 0 )
835         {
836                 pHwData->SurpriseRemove = 1;
837                 if( pHwData->WbUsb.IsUsb20 )
838                         hal_stop( pHwData );
839         }
840         else
841         {
842                 if( !pHwData->WbUsb.IsUsb20 )
843                         hal_stop( pHwData );
844         }
845 }
846
847 void hal_surprise_remove(  phw_data_t pHwData )
848 {
849         PADAPTER Adapter = pHwData->Adapter;
850         if (OS_ATOMIC_INC( Adapter, &pHwData->SurpriseRemoveCount ) == 1) {
851                 #ifdef _PE_STATE_DUMP_
852                 WBDEBUG(("Calling hal_surprise_remove\n"));
853                 #endif
854                 OS_STOP( Adapter );
855         }
856 }
857
858 void hal_rate_change(  phw_data_t pHwData ) // Notify the HAL rate is changing 20060613.1
859 {
860         PADAPTER        Adapter = pHwData->Adapter;
861         u8              rate = CURRENT_TX_RATE;
862
863         BBProcessor_RateChanging( pHwData, rate );
864 }
865
866 void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
867 {
868         RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
869 }
870
871 unsigned char hal_set_LED(phw_data_t pHwData, u32 Mode) // 20061108 for WPS led control
872 {
873         pHwData->LED_Blinking = 0;
874         pHwData->LED_control = Mode;
875         OS_TIMER_SET( &pHwData->LEDTimer, 10 ); // 20060623
876         return TRUE;
877 }
878