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