5 void hal_set_ethernet_address( phw_data_t pHwData
, u8
*current_address
)
9 if( pHwData
->SurpriseRemove
) return;
11 memcpy( pHwData
->CurrentMacAddress
, current_address
, ETH_LENGTH_OF_ADDRESS
);
13 ltmp
[0]= cpu_to_le32( *(u32
*)pHwData
->CurrentMacAddress
);
14 ltmp
[1]= cpu_to_le32( *(u32
*)(pHwData
->CurrentMacAddress
+ 4) ) & 0xffff;
16 Wb35Reg_BurstWrite( pHwData
, 0x03e8, ltmp
, 2, AUTO_INCREMENT
);
19 void hal_get_permanent_address( phw_data_t pHwData
, u8
*pethernet_address
)
21 if( pHwData
->SurpriseRemove
) return;
23 memcpy( pethernet_address
, pHwData
->PermanentMacAddress
, 6 );
26 static void hal_led_control(unsigned long data
)
28 struct wbsoft_priv
*adapter
= (struct wbsoft_priv
*) data
;
29 phw_data_t pHwData
= &adapter
->sHwData
;
30 struct wb35_reg
*reg
= &pHwData
->reg
;
31 u32 LEDSet
= (pHwData
->SoftwareSet
& HAL_LED_SET_MASK
) >> HAL_LED_SET_SHIFT
;
32 u8 LEDgray
[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
33 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 };
34 u32 TimeInterval
= 500, ltmp
, ltmp2
;
37 if( pHwData
->SurpriseRemove
) return;
39 if( pHwData
->LED_control
) {
40 ltmp2
= pHwData
->LED_control
& 0xff;
41 if( ltmp2
== 5 ) // 5 is WPS mode
44 ltmp2
= (pHwData
->LED_control
>>8) & 0xff;
47 case 1: // [0.2 On][0.1 Off]...
48 pHwData
->LED_Blinking
%= 3;
49 ltmp
= 0x1010; // Led 1 & 0 Green and Red
50 if( pHwData
->LED_Blinking
== 2 ) // Turn off
53 case 2: // [0.1 On][0.1 Off]...
54 pHwData
->LED_Blinking
%= 2;
55 ltmp
= 0x0010; // Led 0 red color
56 if( pHwData
->LED_Blinking
) // Turn off
59 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]...
60 pHwData
->LED_Blinking
%= 15;
61 ltmp
= 0x0010; // Led 0 red color
62 if( (pHwData
->LED_Blinking
>= 9) || (pHwData
->LED_Blinking
%2) ) // Turn off 0.6 sec
65 case 4: // [300 On][ off ]
66 ltmp
= 0x1000; // Led 1 Green color
67 if( pHwData
->LED_Blinking
>= 3000 )
68 ltmp
= 0; // led maybe on after 300sec * 32bit counter overlap.
71 pHwData
->LED_Blinking
++;
73 reg
->U1BC_LEDConfigure
= ltmp
;
74 if( LEDSet
!= 7 ) // Only 111 mode has 2 LEDs on PCB.
76 reg
->U1BC_LEDConfigure
|= (ltmp
&0xff)<<8; // Copy LED result to each LED control register
77 reg
->U1BC_LEDConfigure
|= (ltmp
&0xff00)>>8;
79 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
82 else if( pHwData
->CurrentRadioSw
|| pHwData
->CurrentRadioHw
) // If radio off
84 if( reg
->U1BC_LEDConfigure
& 0x1010 )
86 reg
->U1BC_LEDConfigure
&= ~0x1010;
87 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
94 case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
95 if( !pHwData
->LED_LinkOn
) // Blink only if not Link On
97 // Blinking if scanning is on progress
98 if( pHwData
->LED_Scanning
)
100 if( pHwData
->LED_Blinking
== 0 )
102 reg
->U1BC_LEDConfigure
|= 0x10;
103 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 On
104 pHwData
->LED_Blinking
= 1;
109 reg
->U1BC_LEDConfigure
&= ~0x10;
110 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
111 pHwData
->LED_Blinking
= 0;
118 if( reg
->U1BC_LEDConfigure
& 0x10 )
120 reg
->U1BC_LEDConfigure
&= ~0x10;
121 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
128 if( (reg
->U1BC_LEDConfigure
& 0x10) == 0 )
130 reg
->U1BC_LEDConfigure
|= 0x10;
131 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
136 case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
137 if( !pHwData
->LED_LinkOn
) // Blink only if not Link On
139 // Blinking if scanning is on progress
140 if( pHwData
->LED_Scanning
)
142 if( pHwData
->LED_Blinking
== 0 )
144 reg
->U1BC_LEDConfigure
&= ~0xf;
145 reg
->U1BC_LEDConfigure
|= 0x10;
146 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 On
147 pHwData
->LED_Blinking
= 1;
152 reg
->U1BC_LEDConfigure
&= ~0x1f;
153 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
154 pHwData
->LED_Blinking
= 0;
160 // 20060901 Gray blinking if in disconnect state and not scanning
161 ltmp
= reg
->U1BC_LEDConfigure
;
162 reg
->U1BC_LEDConfigure
&= ~0x1f;
163 if( LEDgray2
[(pHwData
->LED_Blinking
%30)] )
165 reg
->U1BC_LEDConfigure
|= 0x10;
166 reg
->U1BC_LEDConfigure
|= LEDgray2
[ (pHwData
->LED_Blinking
%30) ];
168 pHwData
->LED_Blinking
++;
169 if( reg
->U1BC_LEDConfigure
!= ltmp
)
170 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
177 if( (reg
->U1BC_LEDConfigure
& 0x10) == 0 )
179 reg
->U1BC_LEDConfigure
|= 0x10;
180 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_0 Off
185 case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
186 if( !pHwData
->LED_LinkOn
) // Blink only if not Link On
188 // Blinking if scanning is on progress
189 if( pHwData
->LED_Scanning
)
191 if( pHwData
->LED_Blinking
== 0 )
193 reg
->U1BC_LEDConfigure
|= 0x1000;
194 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
195 pHwData
->LED_Blinking
= 1;
200 reg
->U1BC_LEDConfigure
&= ~0x1000;
201 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 Off
202 pHwData
->LED_Blinking
= 0;
209 if( reg
->U1BC_LEDConfigure
& 0x1000 )
211 reg
->U1BC_LEDConfigure
&= ~0x1000;
212 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 Off
218 // Is transmitting/receiving ??
219 if( (adapter
->RxByteCount
!= pHwData
->RxByteCountLast
) ||
220 (adapter
->TxByteCount
!= pHwData
->TxByteCountLast
) )
222 if( (reg
->U1BC_LEDConfigure
& 0x3000) != 0x3000 )
224 reg
->U1BC_LEDConfigure
|= 0x3000;
225 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
229 pHwData
->RxByteCountLast
= adapter
->RxByteCount
;
230 pHwData
->TxByteCountLast
= adapter
->TxByteCount
;
235 // Turn On LED_1 and blinking if transmitting/receiving
236 if( (reg
->U1BC_LEDConfigure
& 0x3000) != 0x1000 )
238 reg
->U1BC_LEDConfigure
&= ~0x3000;
239 reg
->U1BC_LEDConfigure
|= 0x1000;
240 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
); // LED_1 On
246 default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
247 if( (reg
->U1BC_LEDConfigure
& 0x3000) != 0x3000 )
249 reg
->U1BC_LEDConfigure
|= 0x3000;// LED_1 is always on and event enable
250 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
253 if( pHwData
->LED_Blinking
)
256 reg
->U1BC_LEDConfigure
&= ~0x0f;
257 reg
->U1BC_LEDConfigure
|= 0x10;
258 reg
->U1BC_LEDConfigure
|= LEDgray
[ (pHwData
->LED_Blinking
-1)%20 ];
259 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
261 pHwData
->LED_Blinking
+= 2;
262 if( pHwData
->LED_Blinking
< 40 )
266 pHwData
->LED_Blinking
= 0; // Stop blinking
267 reg
->U1BC_LEDConfigure
&= ~0x0f;
268 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
273 if( pHwData
->LED_LinkOn
)
275 if( !(reg
->U1BC_LEDConfigure
& 0x10) ) // Check the LED_0
277 //Try to turn ON LED_0 after gray blinking
278 reg
->U1BC_LEDConfigure
|= 0x10;
279 pHwData
->LED_Blinking
= 1; //Start blinking
285 if( reg
->U1BC_LEDConfigure
& 0x10 ) // Check the LED_0
287 reg
->U1BC_LEDConfigure
&= ~0x10;
288 Wb35Reg_Write( pHwData
, 0x03bc, reg
->U1BC_LEDConfigure
);
294 //20060828.1 Active send null packet to avoid AP disconnect
295 if( pHwData
->LED_LinkOn
)
297 pHwData
->NullPacketCount
+= TimeInterval
;
298 if( pHwData
->NullPacketCount
>= DEFAULT_NULL_PACKET_COUNT
)
300 pHwData
->NullPacketCount
= 0;
305 pHwData
->time_count
+= TimeInterval
;
306 Wb35Tx_CurrentTime(adapter
, pHwData
->time_count
); // 20060928 add
307 pHwData
->LEDTimer
.expires
= jiffies
+ msecs_to_jiffies(TimeInterval
);
308 add_timer(&pHwData
->LEDTimer
);
311 u8
hal_init_hardware(struct ieee80211_hw
*hw
)
313 struct wbsoft_priv
*priv
= hw
->priv
;
314 phw_data_t pHwData
= &priv
->sHwData
;
317 // Initial the variable
318 pHwData
->MaxReceiveLifeTime
= DEFAULT_MSDU_LIFE_TIME
; // Setting Rx maximum MSDU life time
319 pHwData
->FragmentThreshold
= DEFAULT_FRAGMENT_THRESHOLD
; // Setting default fragment threshold
321 pHwData
->InitialResource
= 1;
322 if( Wb35Reg_initial(pHwData
)) {
323 pHwData
->InitialResource
= 2;
324 if (Wb35Tx_initial(pHwData
)) {
325 pHwData
->InitialResource
= 3;
326 if (Wb35Rx_initial(pHwData
)) {
327 pHwData
->InitialResource
= 4;
328 init_timer(&pHwData
->LEDTimer
);
329 pHwData
->LEDTimer
.function
= hal_led_control
;
330 pHwData
->LEDTimer
.data
= (unsigned long) priv
;
331 pHwData
->LEDTimer
.expires
= jiffies
+ msecs_to_jiffies(1000);
332 add_timer(&pHwData
->LEDTimer
);
335 // For restrict to vendor's hardware
337 SoftwareSet
= hal_software_set( pHwData
);
340 // Try to make sure the EEPROM contain
342 if( SoftwareSet
!= 0x82 )
347 Wb35Tx_EP2VM_start(priv
);
354 pHwData
->SurpriseRemove
= 1;
359 void hal_halt(phw_data_t pHwData
, void *ppa_data
)
361 switch( pHwData
->InitialResource
)
364 case 3: del_timer_sync(&pHwData
->LEDTimer
);
365 msleep(100); // Wait for Timer DPC exit 940623.2
366 Wb35Rx_destroy( pHwData
); // Release the Rx
367 case 2: Wb35Tx_destroy( pHwData
); // Release the Tx
368 case 1: Wb35Reg_destroy( pHwData
); // Release the Wb35 Regisster resources
372 //---------------------------------------------------------------------------------------------------
373 void hal_set_beacon_period( phw_data_t pHwData
, u16 beacon_period
)
377 if( pHwData
->SurpriseRemove
) return;
379 pHwData
->BeaconPeriod
= beacon_period
;
380 tmp
= pHwData
->BeaconPeriod
<< 16;
381 tmp
|= pHwData
->ProbeDelay
;
382 Wb35Reg_Write( pHwData
, 0x0848, tmp
);
386 static void hal_set_current_channel_ex( phw_data_t pHwData
, ChanInfo channel
)
388 struct wb35_reg
*reg
= &pHwData
->reg
;
390 if( pHwData
->SurpriseRemove
)
393 printk("Going to channel: %d/%d\n", channel
.band
, channel
.ChanNo
);
395 RFSynthesizer_SwitchingChannel( pHwData
, channel
);// Switch channel
396 pHwData
->Channel
= channel
.ChanNo
;
397 pHwData
->band
= channel
.band
;
398 #ifdef _PE_STATE_DUMP_
399 WBDEBUG(("Set channel is %d, band =%d\n", pHwData
->Channel
, pHwData
->band
));
401 reg
->M28_MacControl
&= ~0xff; // Clean channel information field
402 reg
->M28_MacControl
|= channel
.ChanNo
;
403 Wb35Reg_WriteWithCallbackValue( pHwData
, 0x0828, reg
->M28_MacControl
,
404 (s8
*)&channel
, sizeof(ChanInfo
));
406 //---------------------------------------------------------------------------------------------------
407 void hal_set_current_channel( phw_data_t pHwData
, ChanInfo channel
)
409 hal_set_current_channel_ex( pHwData
, channel
);
411 //---------------------------------------------------------------------------------------------------
412 void hal_set_accept_broadcast( phw_data_t pHwData
, u8 enable
)
414 struct wb35_reg
*reg
= &pHwData
->reg
;
416 if( pHwData
->SurpriseRemove
) return;
418 reg
->M00_MacControl
&= ~0x02000000;//The HW value
421 reg
->M00_MacControl
|= 0x02000000;//The HW value
423 Wb35Reg_Write( pHwData
, 0x0800, reg
->M00_MacControl
);
426 //for wep key error detection, we need to accept broadcast packets to be received temporary.
427 void hal_set_accept_promiscuous( phw_data_t pHwData
, u8 enable
)
429 struct wb35_reg
*reg
= &pHwData
->reg
;
431 if (pHwData
->SurpriseRemove
) return;
433 reg
->M00_MacControl
|= 0x00400000;
434 Wb35Reg_Write( pHwData
, 0x0800, reg
->M00_MacControl
);
436 reg
->M00_MacControl
&=~0x00400000;
437 Wb35Reg_Write( pHwData
, 0x0800, reg
->M00_MacControl
);
441 void hal_set_accept_multicast( phw_data_t pHwData
, u8 enable
)
443 struct wb35_reg
*reg
= &pHwData
->reg
;
445 if( pHwData
->SurpriseRemove
) return;
447 reg
->M00_MacControl
&= ~0x01000000;//The HW value
448 if (enable
) reg
->M00_MacControl
|= 0x01000000;//The HW value
449 Wb35Reg_Write( pHwData
, 0x0800, reg
->M00_MacControl
);
452 void hal_set_accept_beacon( phw_data_t pHwData
, u8 enable
)
454 struct wb35_reg
*reg
= &pHwData
->reg
;
456 if( pHwData
->SurpriseRemove
) return;
459 if( !enable
)//Due to SME and MLME are not suitable for 35
462 reg
->M00_MacControl
&= ~0x04000000;//The HW value
464 reg
->M00_MacControl
|= 0x04000000;//The HW value
466 Wb35Reg_Write( pHwData
, 0x0800, reg
->M00_MacControl
);
468 //---------------------------------------------------------------------------------------------------
470 void hal_stop( phw_data_t pHwData
)
472 struct wb35_reg
*reg
= &pHwData
->reg
;
474 pHwData
->Wb35Rx
.rx_halt
= 1;
475 Wb35Rx_stop( pHwData
);
477 pHwData
->Wb35Tx
.tx_halt
= 1;
478 Wb35Tx_stop( pHwData
);
480 reg
->D00_DmaControl
&= ~0xc0000000;//Tx Off, Rx Off
481 Wb35Reg_Write( pHwData
, 0x0400, reg
->D00_DmaControl
);
484 unsigned char hal_idle(phw_data_t pHwData
)
486 struct wb35_reg
*reg
= &pHwData
->reg
;
487 PWBUSB pWbUsb
= &pHwData
->WbUsb
;
489 if( !pHwData
->SurpriseRemove
&& ( pWbUsb
->DetectCount
|| reg
->EP0vm_state
!=VM_STOP
) )
494 //---------------------------------------------------------------------------------------------------
495 void hal_set_phy_type( phw_data_t pHwData
, u8 PhyType
)
497 pHwData
->phy_type
= PhyType
;
500 void hal_set_radio_mode( phw_data_t pHwData
, unsigned char radio_off
)
502 struct wb35_reg
*reg
= &pHwData
->reg
;
504 if( pHwData
->SurpriseRemove
) return;
506 if (radio_off
) //disable Baseband receive off
508 pHwData
->CurrentRadioSw
= 1; // off
509 reg
->M24_MacControl
&= 0xffffffbf;
513 pHwData
->CurrentRadioSw
= 0; // on
514 reg
->M24_MacControl
|= 0x00000040;
516 Wb35Reg_Write( pHwData
, 0x0824, reg
->M24_MacControl
);
519 u8
hal_get_antenna_number( phw_data_t pHwData
)
521 struct wb35_reg
*reg
= &pHwData
->reg
;
523 if ((reg
->BB2C
& BIT(11)) == 0)
529 //----------------------------------------------------------------------------------------------------
530 //0 : radio on; 1: radio off
531 u8
hal_get_hw_radio_off( phw_data_t pHwData
)
533 struct wb35_reg
*reg
= &pHwData
->reg
;
535 if( pHwData
->SurpriseRemove
) return 1;
537 //read the bit16 of register U1B0
538 Wb35Reg_Read( pHwData
, 0x3b0, ®
->U1B0
);
539 if ((reg
->U1B0
& 0x00010000)) {
540 pHwData
->CurrentRadioHw
= 1;
543 pHwData
->CurrentRadioHw
= 0;
548 unsigned char hal_get_dxx_reg( phw_data_t pHwData
, u16 number
, u32
* pValue
)
550 if( number
< 0x1000 )
552 return Wb35Reg_ReadSync( pHwData
, number
, pValue
);
555 unsigned char hal_set_dxx_reg( phw_data_t pHwData
, u16 number
, u32 value
)
559 if( number
< 0x1000 )
561 ret
= Wb35Reg_WriteSync( pHwData
, number
, value
);
565 void hal_set_rf_power(phw_data_t pHwData
, u8 PowerIndex
)
567 RFSynthesizer_SetPowerIndex( pHwData
, PowerIndex
);