diff options
Diffstat (limited to 'drivers/staging/winbond/wbusb.c')
-rw-r--r-- | drivers/staging/winbond/wbusb.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index c5fd054c0fa..c46ff4717b1 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c | |||
@@ -120,6 +120,127 @@ static int wbsoft_start(struct ieee80211_hw *dev) | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off) | ||
124 | { | ||
125 | struct wb35_reg *reg = &pHwData->reg; | ||
126 | |||
127 | if (pHwData->SurpriseRemove) | ||
128 | return; | ||
129 | |||
130 | if (radio_off) //disable Baseband receive off | ||
131 | { | ||
132 | pHwData->CurrentRadioSw = 1; // off | ||
133 | reg->M24_MacControl &= 0xffffffbf; | ||
134 | } else { | ||
135 | pHwData->CurrentRadioSw = 0; // on | ||
136 | reg->M24_MacControl |= 0x00000040; | ||
137 | } | ||
138 | Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); | ||
139 | } | ||
140 | |||
141 | static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) | ||
142 | { | ||
143 | u32 tmp; | ||
144 | |||
145 | if (pHwData->SurpriseRemove) | ||
146 | return; | ||
147 | |||
148 | pHwData->BeaconPeriod = beacon_period; | ||
149 | tmp = pHwData->BeaconPeriod << 16; | ||
150 | tmp |= pHwData->ProbeDelay; | ||
151 | Wb35Reg_Write(pHwData, 0x0848, tmp); | ||
152 | } | ||
153 | |||
154 | static void | ||
155 | hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) | ||
156 | { | ||
157 | struct wb35_reg *reg = &pHwData->reg; | ||
158 | |||
159 | if (pHwData->SurpriseRemove) | ||
160 | return; | ||
161 | |||
162 | printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); | ||
163 | |||
164 | RFSynthesizer_SwitchingChannel(pHwData, channel); // Switch channel | ||
165 | pHwData->Channel = channel.ChanNo; | ||
166 | pHwData->band = channel.band; | ||
167 | #ifdef _PE_STATE_DUMP_ | ||
168 | printk("Set channel is %d, band =%d\n", pHwData->Channel, | ||
169 | pHwData->band); | ||
170 | #endif | ||
171 | reg->M28_MacControl &= ~0xff; // Clean channel information field | ||
172 | reg->M28_MacControl |= channel.ChanNo; | ||
173 | Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, | ||
174 | (s8 *) & channel, sizeof(ChanInfo)); | ||
175 | } | ||
176 | |||
177 | static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel) | ||
178 | { | ||
179 | hal_set_current_channel_ex(pHwData, channel); | ||
180 | } | ||
181 | |||
182 | static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable) | ||
183 | { | ||
184 | struct wb35_reg *reg = &pHwData->reg; | ||
185 | |||
186 | if (pHwData->SurpriseRemove) | ||
187 | return; | ||
188 | |||
189 | reg->M00_MacControl &= ~0x02000000; //The HW value | ||
190 | |||
191 | if (enable) | ||
192 | reg->M00_MacControl |= 0x02000000; //The HW value | ||
193 | |||
194 | Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); | ||
195 | } | ||
196 | |||
197 | //for wep key error detection, we need to accept broadcast packets to be received temporary. | ||
198 | static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable) | ||
199 | { | ||
200 | struct wb35_reg *reg = &pHwData->reg; | ||
201 | |||
202 | if (pHwData->SurpriseRemove) | ||
203 | return; | ||
204 | if (enable) { | ||
205 | reg->M00_MacControl |= 0x00400000; | ||
206 | Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); | ||
207 | } else { | ||
208 | reg->M00_MacControl &= ~0x00400000; | ||
209 | Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable) | ||
214 | { | ||
215 | struct wb35_reg *reg = &pHwData->reg; | ||
216 | |||
217 | if (pHwData->SurpriseRemove) | ||
218 | return; | ||
219 | |||
220 | reg->M00_MacControl &= ~0x01000000; //The HW value | ||
221 | if (enable) | ||
222 | reg->M00_MacControl |= 0x01000000; //The HW value | ||
223 | Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); | ||
224 | } | ||
225 | |||
226 | static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable) | ||
227 | { | ||
228 | struct wb35_reg *reg = &pHwData->reg; | ||
229 | |||
230 | if (pHwData->SurpriseRemove) | ||
231 | return; | ||
232 | |||
233 | // 20040108 debug | ||
234 | if (!enable) //Due to SME and MLME are not suitable for 35 | ||
235 | return; | ||
236 | |||
237 | reg->M00_MacControl &= ~0x04000000; //The HW value | ||
238 | if (enable) | ||
239 | reg->M00_MacControl |= 0x04000000; //The HW value | ||
240 | |||
241 | Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); | ||
242 | } | ||
243 | |||
123 | static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) | 244 | static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) |
124 | { | 245 | { |
125 | struct wbsoft_priv *priv = dev->priv; | 246 | struct wbsoft_priv *priv = dev->priv; |
@@ -171,6 +292,87 @@ static const struct ieee80211_ops wbsoft_ops = { | |||
171 | .get_tsf = wbsoft_get_tsf, | 292 | .get_tsf = wbsoft_get_tsf, |
172 | }; | 293 | }; |
173 | 294 | ||
295 | static void | ||
296 | hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address) | ||
297 | { | ||
298 | u32 ltmp[2]; | ||
299 | |||
300 | if (pHwData->SurpriseRemove) | ||
301 | return; | ||
302 | |||
303 | memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN); | ||
304 | |||
305 | ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress); | ||
306 | ltmp[1] = | ||
307 | cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff; | ||
308 | |||
309 | Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT); | ||
310 | } | ||
311 | |||
312 | static void | ||
313 | hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address) | ||
314 | { | ||
315 | if (pHwData->SurpriseRemove) | ||
316 | return; | ||
317 | |||
318 | memcpy(pethernet_address, pHwData->PermanentMacAddress, 6); | ||
319 | } | ||
320 | |||
321 | static void hal_stop(struct hw_data *pHwData) | ||
322 | { | ||
323 | struct wb35_reg *reg = &pHwData->reg; | ||
324 | |||
325 | pHwData->Wb35Rx.rx_halt = 1; | ||
326 | Wb35Rx_stop(pHwData); | ||
327 | |||
328 | pHwData->Wb35Tx.tx_halt = 1; | ||
329 | Wb35Tx_stop(pHwData); | ||
330 | |||
331 | reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off | ||
332 | Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl); | ||
333 | } | ||
334 | |||
335 | static unsigned char hal_idle(struct hw_data *pHwData) | ||
336 | { | ||
337 | struct wb35_reg *reg = &pHwData->reg; | ||
338 | struct wb_usb *pWbUsb = &pHwData->WbUsb; | ||
339 | |||
340 | if (!pHwData->SurpriseRemove | ||
341 | && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP)) | ||
342 | return false; | ||
343 | |||
344 | return true; | ||
345 | } | ||
346 | |||
347 | u8 hal_get_antenna_number(struct hw_data *pHwData) | ||
348 | { | ||
349 | struct wb35_reg *reg = &pHwData->reg; | ||
350 | |||
351 | if ((reg->BB2C & BIT(11)) == 0) | ||
352 | return 0; | ||
353 | else | ||
354 | return 1; | ||
355 | } | ||
356 | |||
357 | /* 0 : radio on; 1: radio off */ | ||
358 | static u8 hal_get_hw_radio_off(struct hw_data * pHwData) | ||
359 | { | ||
360 | struct wb35_reg *reg = &pHwData->reg; | ||
361 | |||
362 | if (pHwData->SurpriseRemove) | ||
363 | return 1; | ||
364 | |||
365 | //read the bit16 of register U1B0 | ||
366 | Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0); | ||
367 | if ((reg->U1B0 & 0x00010000)) { | ||
368 | pHwData->CurrentRadioHw = 1; | ||
369 | return 1; | ||
370 | } else { | ||
371 | pHwData->CurrentRadioHw = 0; | ||
372 | return 0; | ||
373 | } | ||
374 | } | ||
375 | |||
174 | static u8 LED_GRAY[20] = { | 376 | static u8 LED_GRAY[20] = { |
175 | 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2 | 377 | 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2 |
176 | }; | 378 | }; |