aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/winbond/wbhal.c
blob: e40fdca4b9f3eb3ef386f6396ec0e97e171b2092 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include "sysdef.h"
#include "wbhal_f.h"
#include "wblinux_f.h"

void hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address)
{
	u32 ltmp[2];

	if (pHwData->SurpriseRemove)
		return;

	memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN);

	ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress);
	ltmp[1] =
	    cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff;

	Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT);
}

void hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address)
{
	if (pHwData->SurpriseRemove)
		return;

	memcpy(pethernet_address, pHwData->PermanentMacAddress, 6);
}

//---------------------------------------------------------------------------------------------------
void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
{
	u32 tmp;

	if (pHwData->SurpriseRemove)
		return;

	pHwData->BeaconPeriod = beacon_period;
	tmp = pHwData->BeaconPeriod << 16;
	tmp |= pHwData->ProbeDelay;
	Wb35Reg_Write(pHwData, 0x0848, tmp);
}

static void hal_set_current_channel_ex(struct hw_data *pHwData,
				       ChanInfo channel)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;

	printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);

	RFSynthesizer_SwitchingChannel(pHwData, channel);	// Switch channel
	pHwData->Channel = channel.ChanNo;
	pHwData->band = channel.band;
#ifdef _PE_STATE_DUMP_
	printk("Set channel is %d, band =%d\n", pHwData->Channel,
	       pHwData->band);
#endif
	reg->M28_MacControl &= ~0xff;	// Clean channel information field
	reg->M28_MacControl |= channel.ChanNo;
	Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
				       (s8 *) & channel, sizeof(ChanInfo));
}

//---------------------------------------------------------------------------------------------------
void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
{
	hal_set_current_channel_ex(pHwData, channel);
}

//---------------------------------------------------------------------------------------------------
void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;

	reg->M00_MacControl &= ~0x02000000;	//The HW value

	if (enable)
		reg->M00_MacControl |= 0x02000000;	//The HW value

	Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
}

//for wep key error detection, we need to accept broadcast packets to be received temporary.
void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;
	if (enable) {
		reg->M00_MacControl |= 0x00400000;
		Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
	} else {
		reg->M00_MacControl &= ~0x00400000;
		Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
	}
}

void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;

	reg->M00_MacControl &= ~0x01000000;	//The HW value
	if (enable)
		reg->M00_MacControl |= 0x01000000;	//The HW value
	Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
}

void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;

	// 20040108 debug
	if (!enable)		//Due to SME and MLME are not suitable for 35
		return;

	reg->M00_MacControl &= ~0x04000000;	//The HW value
	if (enable)
		reg->M00_MacControl |= 0x04000000;	//The HW value

	Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl);
}

//---------------------------------------------------------------------------------------------------

void hal_stop(struct hw_data *pHwData)
{
	struct wb35_reg *reg = &pHwData->reg;

	pHwData->Wb35Rx.rx_halt = 1;
	Wb35Rx_stop(pHwData);

	pHwData->Wb35Tx.tx_halt = 1;
	Wb35Tx_stop(pHwData);

	reg->D00_DmaControl &= ~0xc0000000;	//Tx Off, Rx Off
	Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl);
}

unsigned char hal_idle(struct hw_data *pHwData)
{
	struct wb35_reg *reg = &pHwData->reg;
	struct wb_usb *pWbUsb = &pHwData->WbUsb;

	if (!pHwData->SurpriseRemove
	    && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP))
		return false;

	return true;
}

void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return;

	if (radio_off)		//disable Baseband receive off
	{
		pHwData->CurrentRadioSw = 1;	// off
		reg->M24_MacControl &= 0xffffffbf;
	} else {
		pHwData->CurrentRadioSw = 0;	// on
		reg->M24_MacControl |= 0x00000040;
	}
	Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
}

u8 hal_get_antenna_number(struct hw_data *pHwData)
{
	struct wb35_reg *reg = &pHwData->reg;

	if ((reg->BB2C & BIT(11)) == 0)
		return 0;
	else
		return 1;
}

//----------------------------------------------------------------------------------------------------
//0 : radio on; 1: radio off
u8 hal_get_hw_radio_off(struct hw_data * pHwData)
{
	struct wb35_reg *reg = &pHwData->reg;

	if (pHwData->SurpriseRemove)
		return 1;

	//read the bit16 of register U1B0
	Wb35Reg_Read(pHwData, 0x3b0, &reg->U1B0);
	if ((reg->U1B0 & 0x00010000)) {
		pHwData->CurrentRadioHw = 1;
		return 1;
	} else {
		pHwData->CurrentRadioHw = 0;
		return 0;
	}
}

unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
{
	if (number < 0x1000)
		number += 0x1000;
	return Wb35Reg_ReadSync(pHwData, number, pValue);
}

unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
{
	unsigned char ret;

	if (number < 0x1000)
		number += 0x1000;
	ret = Wb35Reg_WriteSync(pHwData, number, value);
	return ret;
}

void hal_set_rf_power(struct hw_data *pHwData, u8 PowerIndex)
{
	RFSynthesizer_SetPowerIndex(pHwData, PowerIndex);
}