Loading...
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *
20 * File: mac.c
21 *
22 * Purpose: MAC routines
23 *
24 * Author: Tevin Chen
25 *
26 * Date: May 21, 1996
27 *
28 * Functions:
29 *
30 * Revision History:
31 */
32
33#include "tmacro.h"
34#include "tether.h"
35#include "desc.h"
36#include "mac.h"
37#include "80211hdr.h"
38#include "rndis.h"
39#include "control.h"
40
41/*--------------------- Static Definitions -------------------------*/
42//static int msglevel =MSG_LEVEL_DEBUG;
43static int msglevel =MSG_LEVEL_INFO;
44/*--------------------- Static Classes ----------------------------*/
45
46/*--------------------- Static Variables --------------------------*/
47
48/*--------------------- Static Functions --------------------------*/
49
50/*--------------------- Export Variables --------------------------*/
51
52/*--------------------- Export Functions --------------------------*/
53
54
55
56
57
58/*
59 * Description:
60 * Set this hash index into multicast address register bit
61 *
62 * Parameters:
63 * In:
64 * byHashIdx - Hash index to set
65 * Out:
66 * none
67 *
68 * Return Value: none
69 *
70 */
71void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx)
72{
73 unsigned int uByteIdx;
74 BYTE byBitMask;
75 BYTE pbyData[2];
76
77
78 // calculate byte position
79 uByteIdx = byHashIdx / 8;
80
81 // calculate bit position
82 byBitMask = 1;
83 byBitMask <<= (byHashIdx % 8);
84 // turn on the bit
85
86 pbyData[0] = byBitMask;
87 pbyData[1] = byBitMask;
88
89 CONTROLnsRequestOut(pDevice,
90 MESSAGE_TYPE_WRITE_MASK,
91 (WORD) (MAC_REG_MAR0 + uByteIdx),
92 MESSAGE_REQUEST_MACREG,
93 2,
94 pbyData);
95}
96
97
98
99/*
100 * Description:
101 * Write MAC Multicast Address Mask
102 *
103 * Parameters:
104 * In:
105 * uByteidx - Index of Mask
106 * byData - Mask Value to write
107 * Out:
108 * none
109 *
110 * Return Value: none
111 *
112 */
113void MACvWriteMultiAddr(PSDevice pDevice, unsigned int uByteIdx, BYTE byData)
114{
115 BYTE byData1;
116
117 byData1 = byData;
118 CONTROLnsRequestOut(pDevice,
119 MESSAGE_TYPE_WRITE,
120 (WORD) (MAC_REG_MAR0 + uByteIdx),
121 MESSAGE_REQUEST_MACREG,
122 1,
123 &byData1);
124}
125
126
127/*
128 * Description:
129 * Shut Down MAC
130 *
131 * Parameters:
132 * In:
133 * Out:
134 * none
135 *
136 * Return Value: TRUE if success; otherwise FALSE
137 *
138 */
139BOOL MACbShutdown (PSDevice pDevice)
140{
141 CONTROLnsRequestOutAsyn(pDevice,
142 MESSAGE_TYPE_MACSHUTDOWN,
143 0,
144 0,
145 0,
146 NULL
147 );
148 return TRUE;
149}
150
151void MACvSetBBType(PSDevice pDevice,BYTE byType)
152{
153BYTE pbyData[2];
154
155
156 pbyData[0] = byType;
157 pbyData[1] = EnCFG_BBType_MASK;
158
159 CONTROLnsRequestOut(pDevice,
160 MESSAGE_TYPE_WRITE_MASK,
161 MAC_REG_ENCFG0,
162 MESSAGE_REQUEST_MACREG,
163 2,
164 pbyData
165 );
166}
167
168void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData)
169{
170BYTE pbyData[4];
171
172 if (wOffset > 273)
173 return;
174 pbyData[0] = (BYTE)dwData;
175 pbyData[1] = (BYTE)(dwData>>8);
176 pbyData[2] = (BYTE)(dwData>>16);
177 pbyData[3] = (BYTE)(dwData>>24);
178
179 CONTROLnsRequestOut(pDevice,
180 MESSAGE_TYPE_WRITE_MISCFF,
181 wOffset,
182 0,
183 4,
184 pbyData
185 );
186}
187
188/*
189 * Description:
190 * Disable the Key Entry by MISCFIFO
191 *
192 * Parameters:
193 * In:
194 * dwIoBase - Base Address for MAC
195 *
196 * Out:
197 * none
198 *
199 * Return Value: none
200 *
201 */
202void MACvDisableKeyEntry(PSDevice pDevice, unsigned int uEntryIdx)
203{
204WORD wOffset;
205BYTE byData;
206
207
208 byData = (BYTE) uEntryIdx;
209
210 wOffset = MISCFIFO_KEYETRY0;
211 wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
212
213 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
214 //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
215 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
216
217 //issue write misc fifo command to device
218 CONTROLnsRequestOut(pDevice,
219 MESSAGE_TYPE_CLRKEYENTRY,
220 0,
221 0,
222 1,
223 &byData
224 );
225}
226
227
228/*
229 * Description:
230 * Set the Key by MISCFIFO
231 *
232 * Parameters:
233 * In:
234 * dwIoBase - Base Address for MAC
235 *
236 * Out:
237 * none
238 *
239 * Return Value: none
240 *
241 */
242void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl,
243 unsigned int uEntryIdx, unsigned int uKeyIdx,
244 PBYTE pbyAddr, PDWORD pdwKey)
245{
246PBYTE pbyKey;
247WORD wOffset;
248DWORD dwData1,dwData2;
249int ii;
250BYTE pbyData[24];
251
252 if ( pDevice->byLocalID <= MAC_REVISION_A1 ) {
253 if ( pDevice->sMgmtObj.byCSSPK == KEY_CTL_CCMP )
254 return;
255 }
256
257 wOffset = MISCFIFO_KEYETRY0;
258 wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
259
260 dwData1 = 0;
261 dwData1 |= wKeyCtl;
262 dwData1 <<= 16;
263 dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
264
265 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
266
267 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
268 //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
269 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
270
271 //wOffset++;
272
273 dwData2 = 0;
274 dwData2 |= *(pbyAddr+3);
275 dwData2 <<= 8;
276 dwData2 |= *(pbyAddr+2);
277 dwData2 <<= 8;
278 dwData2 |= *(pbyAddr+1);
279 dwData2 <<= 8;
280 dwData2 |= *(pbyAddr+0);
281
282 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2);
283
284 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
285 //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
286 //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
287
288 //wOffset++;
289
290 //wOffset += (uKeyIdx * 4);
291/* for (ii=0;ii<4;ii++) {
292 // alway push 128 bits
293 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
294 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
295 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
296 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
297 }
298*/
299 pbyKey = (PBYTE)pdwKey;
300
301 pbyData[0] = (BYTE)dwData1;
302 pbyData[1] = (BYTE)(dwData1>>8);
303 pbyData[2] = (BYTE)(dwData1>>16);
304 pbyData[3] = (BYTE)(dwData1>>24);
305 pbyData[4] = (BYTE)dwData2;
306 pbyData[5] = (BYTE)(dwData2>>8);
307 pbyData[6] = (BYTE)(dwData2>>16);
308 pbyData[7] = (BYTE)(dwData2>>24);
309 for (ii = 8; ii < 24; ii++)
310 pbyData[ii] = *pbyKey++;
311
312 CONTROLnsRequestOut(pDevice,
313 MESSAGE_TYPE_SETKEY,
314 wOffset,
315 (WORD)uKeyIdx,
316 24,
317 pbyData
318 );
319
320
321}
322
323
324void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
325{
326BYTE pbyData[2];
327
328 pbyData[0] = 0;
329 pbyData[1] = byBits;
330
331 CONTROLnsRequestOut(pDevice,
332 MESSAGE_TYPE_WRITE_MASK,
333 byRegOfs,
334 MESSAGE_REQUEST_MACREG,
335 2,
336 pbyData
337 );
338}
339
340
341void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
342{
343BYTE pbyData[2];
344
345
346 pbyData[0] = byBits;
347 pbyData[1] = byBits;
348
349 CONTROLnsRequestOut(pDevice,
350 MESSAGE_TYPE_WRITE_MASK,
351 byRegOfs,
352 MESSAGE_REQUEST_MACREG,
353 2,
354 pbyData
355 );
356}
357
358void MACvWriteWord(PSDevice pDevice, BYTE byRegOfs, WORD wData)
359{
360BYTE pbyData[2];
361
362
363 pbyData[0] = (BYTE)(wData & 0xff);
364 pbyData[1] = (BYTE)(wData >> 8);
365
366 CONTROLnsRequestOut(pDevice,
367 MESSAGE_TYPE_WRITE,
368 byRegOfs,
369 MESSAGE_REQUEST_MACREG,
370 2,
371 pbyData
372 );
373
374}
375
376void MACvWriteBSSIDAddress(PSDevice pDevice, PBYTE pbyEtherAddr)
377{
378BYTE pbyData[6];
379
380
381 pbyData[0] = *((PBYTE)pbyEtherAddr);
382 pbyData[1] = *((PBYTE)pbyEtherAddr+1);
383 pbyData[2] = *((PBYTE)pbyEtherAddr+2);
384 pbyData[3] = *((PBYTE)pbyEtherAddr+3);
385 pbyData[4] = *((PBYTE)pbyEtherAddr+4);
386 pbyData[5] = *((PBYTE)pbyEtherAddr+5);
387
388 CONTROLnsRequestOut(pDevice,
389 MESSAGE_TYPE_WRITE,
390 MAC_REG_BSSID0,
391 MESSAGE_REQUEST_MACREG,
392 6,
393 pbyData
394 );
395}
396
397void MACvEnableProtectMD(PSDevice pDevice)
398{
399BYTE pbyData[2];
400
401
402 pbyData[0] = EnCFG_ProtectMd;
403 pbyData[1] = EnCFG_ProtectMd;
404
405 CONTROLnsRequestOut(pDevice,
406 MESSAGE_TYPE_WRITE_MASK,
407 MAC_REG_ENCFG0,
408 MESSAGE_REQUEST_MACREG,
409 2,
410 pbyData
411 );
412}
413
414void MACvDisableProtectMD(PSDevice pDevice)
415{
416BYTE pbyData[2];
417
418
419 pbyData[0] = 0;
420 pbyData[1] = EnCFG_ProtectMd;
421
422 CONTROLnsRequestOut(pDevice,
423 MESSAGE_TYPE_WRITE_MASK,
424 MAC_REG_ENCFG0,
425 MESSAGE_REQUEST_MACREG,
426 2,
427 pbyData
428 );
429}
430
431void MACvEnableBarkerPreambleMd(PSDevice pDevice)
432{
433BYTE pbyData[2];
434
435
436 pbyData[0] = EnCFG_BarkerPream;
437 pbyData[1] = EnCFG_BarkerPream;
438
439 CONTROLnsRequestOut(pDevice,
440 MESSAGE_TYPE_WRITE_MASK,
441 MAC_REG_ENCFG2,
442 MESSAGE_REQUEST_MACREG,
443 2,
444 pbyData
445 );
446}
447
448void MACvDisableBarkerPreambleMd(PSDevice pDevice)
449{
450BYTE pbyData[2];
451
452
453 pbyData[0] = 0;
454 pbyData[1] = EnCFG_BarkerPream;
455
456 CONTROLnsRequestOut(pDevice,
457 MESSAGE_TYPE_WRITE_MASK,
458 MAC_REG_ENCFG2,
459 MESSAGE_REQUEST_MACREG,
460 2,
461 pbyData
462 );
463}
464
465
466void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval)
467{
468BYTE pbyData[2];
469
470 pbyData[0] = (BYTE) (wInterval & 0xff);
471 pbyData[1] = (BYTE) (wInterval >> 8);
472
473 CONTROLnsRequestOut(pDevice,
474 MESSAGE_TYPE_WRITE,
475 MAC_REG_BI,
476 MESSAGE_REQUEST_MACREG,
477 2,
478 pbyData
479 );
480}
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 *
16 * File: mac.c
17 *
18 * Purpose: MAC routines
19 *
20 * Author: Tevin Chen
21 *
22 * Date: May 21, 1996
23 *
24 * Functions:
25 *
26 * Revision History:
27 */
28
29#include <linux/etherdevice.h>
30
31#include "desc.h"
32#include "mac.h"
33#include "usbpipe.h"
34
35/*
36 * Description:
37 * Write MAC Multicast Address Mask
38 *
39 * Parameters:
40 * In:
41 * mc_filter (mac filter)
42 * Out:
43 * none
44 *
45 * Return Value: none
46 *
47 */
48void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter)
49{
50 __le64 le_mc = cpu_to_le64(mc_filter);
51
52 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0,
53 MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc);
54}
55
56/*
57 * Description:
58 * Shut Down MAC
59 *
60 * Parameters:
61 * In:
62 * Out:
63 * none
64 *
65 *
66 */
67void vnt_mac_shutdown(struct vnt_private *priv)
68{
69 vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL);
70}
71
72void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type)
73{
74 u8 data[2];
75
76 data[0] = type;
77 data[1] = EnCFG_BBType_MASK;
78
79 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
80 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
81}
82
83/*
84 * Description:
85 * Disable the Key Entry by MISCFIFO
86 *
87 * Parameters:
88 * In:
89 * dwIoBase - Base Address for MAC
90 *
91 * Out:
92 * none
93 *
94 * Return Value: none
95 *
96 */
97void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx)
98{
99 vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0,
100 sizeof(entry_idx), &entry_idx);
101}
102
103/*
104 * Description:
105 * Set the Key by MISCFIFO
106 *
107 * Parameters:
108 * In:
109 * dwIoBase - Base Address for MAC
110 *
111 * Out:
112 * none
113 *
114 * Return Value: none
115 *
116 */
117void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
118 u32 key_idx, u8 *addr, u8 *key)
119{
120 struct vnt_mac_set_key set_key;
121 u16 offset;
122
123 offset = MISCFIFO_KEYETRY0;
124 offset += entry_idx * MISCFIFO_KEYENTRYSIZE;
125
126 set_key.u.write.key_ctl = cpu_to_le16(key_ctl);
127 ether_addr_copy(set_key.u.write.addr, addr);
128
129 /* swap over swap[0] and swap[1] to get correct write order */
130 swap(set_key.u.swap[0], set_key.u.swap[1]);
131
132 memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP);
133
134 dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n",
135 offset, key_ctl, (u8 *)&set_key);
136
137 vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset,
138 (u16)key_idx, sizeof(struct vnt_mac_set_key), (u8 *)&set_key);
139}
140
141void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits)
142{
143 u8 data[2];
144
145 data[0] = 0;
146 data[1] = bits;
147
148 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
149 reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
150}
151
152void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits)
153{
154 u8 data[2];
155
156 data[0] = bits;
157 data[1] = bits;
158
159 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
160 reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
161}
162
163void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word)
164{
165 u8 data[2];
166
167 data[0] = (u8)(word & 0xff);
168 data[1] = (u8)(word >> 8);
169
170 vnt_control_out(priv, MESSAGE_TYPE_WRITE,
171 reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
172}
173
174void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr)
175{
176 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0,
177 MESSAGE_REQUEST_MACREG, ETH_ALEN, addr);
178}
179
180void vnt_mac_enable_protect_mode(struct vnt_private *priv)
181{
182 u8 data[2];
183
184 data[0] = EnCFG_ProtectMd;
185 data[1] = EnCFG_ProtectMd;
186
187 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
188 MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
189}
190
191void vnt_mac_disable_protect_mode(struct vnt_private *priv)
192{
193 u8 data[2];
194
195 data[0] = 0;
196 data[1] = EnCFG_ProtectMd;
197
198 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
199 MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
200}
201
202void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv)
203{
204 u8 data[2];
205
206 data[0] = EnCFG_BarkerPream;
207 data[1] = EnCFG_BarkerPream;
208
209 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
210 MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
211}
212
213void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv)
214{
215 u8 data[2];
216
217 data[0] = 0;
218 data[1] = EnCFG_BarkerPream;
219
220 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
221 MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
222}
223
224void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval)
225{
226 u8 data[2];
227
228 data[0] = (u8)(interval & 0xff);
229 data[1] = (u8)(interval >> 8);
230
231 vnt_control_out(priv, MESSAGE_TYPE_WRITE,
232 MAC_REG_BI, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
233}
234
235void vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led)
236{
237 u8 data[2];
238
239 data[0] = led;
240 data[1] = state;
241
242 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_PAPEDELAY,
243 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
244}