0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 #include <linux/module.h>
0055 #include <linux/kernel.h>
0056 #include <linux/sched.h>
0057 #include <linux/types.h>
0058 #include <linux/wireless.h>
0059 #include <linux/netdevice.h>
0060 #include <linux/io.h>
0061 #include <linux/delay.h>
0062 #include <asm/byteorder.h>
0063 #include <linux/usb.h>
0064 #include <linux/bitops.h>
0065
0066 #include "p80211types.h"
0067 #include "p80211hdr.h"
0068 #include "p80211mgmt.h"
0069 #include "p80211conv.h"
0070 #include "p80211msg.h"
0071 #include "p80211netdev.h"
0072 #include "p80211metadef.h"
0073 #include "p80211metastruct.h"
0074 #include "hfa384x.h"
0075 #include "prism2mgmt.h"
0076
0077 #define MIB_TMP_MAXLEN 200
0078
0079 #define F_STA 0x1
0080 #define F_READ 0x2
0081 #define F_WRITE 0x4
0082
0083 struct mibrec {
0084 u32 did;
0085 u16 flag;
0086 u16 parm1;
0087 u16 parm2;
0088 u16 parm3;
0089 int (*func)(struct mibrec *mib,
0090 int isget,
0091 struct wlandevice *wlandev,
0092 struct hfa384x *hw,
0093 struct p80211msg_dot11req_mibset *msg, void *data);
0094 };
0095
0096 static int prism2mib_bytearea2pstr(struct mibrec *mib,
0097 int isget,
0098 struct wlandevice *wlandev,
0099 struct hfa384x *hw,
0100 struct p80211msg_dot11req_mibset *msg,
0101 void *data);
0102
0103 static int prism2mib_uint32(struct mibrec *mib,
0104 int isget,
0105 struct wlandevice *wlandev,
0106 struct hfa384x *hw,
0107 struct p80211msg_dot11req_mibset *msg, void *data);
0108
0109 static int prism2mib_flag(struct mibrec *mib,
0110 int isget,
0111 struct wlandevice *wlandev,
0112 struct hfa384x *hw,
0113 struct p80211msg_dot11req_mibset *msg, void *data);
0114
0115 static int prism2mib_wepdefaultkey(struct mibrec *mib,
0116 int isget,
0117 struct wlandevice *wlandev,
0118 struct hfa384x *hw,
0119 struct p80211msg_dot11req_mibset *msg,
0120 void *data);
0121
0122 static int prism2mib_privacyinvoked(struct mibrec *mib,
0123 int isget,
0124 struct wlandevice *wlandev,
0125 struct hfa384x *hw,
0126 struct p80211msg_dot11req_mibset *msg,
0127 void *data);
0128
0129 static int
0130 prism2mib_fragmentationthreshold(struct mibrec *mib,
0131 int isget,
0132 struct wlandevice *wlandev,
0133 struct hfa384x *hw,
0134 struct p80211msg_dot11req_mibset *msg,
0135 void *data);
0136
0137 static int prism2mib_priv(struct mibrec *mib,
0138 int isget,
0139 struct wlandevice *wlandev,
0140 struct hfa384x *hw,
0141 struct p80211msg_dot11req_mibset *msg, void *data);
0142
0143 static struct mibrec mibtab[] = {
0144
0145 {didmib_dot11smt_wepdefaultkeystable_key(1),
0146 F_STA | F_WRITE,
0147 HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
0148 prism2mib_wepdefaultkey},
0149 {didmib_dot11smt_wepdefaultkeystable_key(2),
0150 F_STA | F_WRITE,
0151 HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
0152 prism2mib_wepdefaultkey},
0153 {didmib_dot11smt_wepdefaultkeystable_key(3),
0154 F_STA | F_WRITE,
0155 HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
0156 prism2mib_wepdefaultkey},
0157 {didmib_dot11smt_wepdefaultkeystable_key(4),
0158 F_STA | F_WRITE,
0159 HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
0160 prism2mib_wepdefaultkey},
0161 {DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
0162 F_STA | F_READ | F_WRITE,
0163 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
0164 prism2mib_privacyinvoked},
0165 {DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
0166 F_STA | F_READ | F_WRITE,
0167 HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
0168 prism2mib_uint32},
0169 {DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
0170 F_STA | F_READ | F_WRITE,
0171 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
0172 prism2mib_flag},
0173
0174
0175
0176 {DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS,
0177 F_STA | F_READ | F_WRITE,
0178 HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
0179 prism2mib_bytearea2pstr},
0180 {DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
0181 F_STA | F_READ | F_WRITE,
0182 HFA384x_RID_RTSTHRESH, 0, 0,
0183 prism2mib_uint32},
0184 {DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT,
0185 F_STA | F_READ,
0186 HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
0187 prism2mib_uint32},
0188 {DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT,
0189 F_STA | F_READ,
0190 HFA384x_RID_LONGRETRYLIMIT, 0, 0,
0191 prism2mib_uint32},
0192 {DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
0193 F_STA | F_READ | F_WRITE,
0194 HFA384x_RID_FRAGTHRESH, 0, 0,
0195 prism2mib_fragmentationthreshold},
0196 {DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME,
0197 F_STA | F_READ,
0198 HFA384x_RID_MAXTXLIFETIME, 0, 0,
0199 prism2mib_uint32},
0200
0201
0202
0203 {DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
0204 F_STA | F_READ,
0205 HFA384x_RID_CURRENTCHANNEL, 0, 0,
0206 prism2mib_uint32},
0207 {DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
0208 F_STA | F_READ | F_WRITE,
0209 HFA384x_RID_TXPOWERMAX, 0, 0,
0210 prism2mib_uint32},
0211
0212
0213
0214 {DIDMIB_P2_STATIC_CNFPORTTYPE,
0215 F_STA | F_READ | F_WRITE,
0216 HFA384x_RID_CNFPORTTYPE, 0, 0,
0217 prism2mib_uint32},
0218
0219
0220
0221 {DIDMIB_P2_MAC_CURRENTTXRATE,
0222 F_STA | F_READ,
0223 HFA384x_RID_CURRENTTXRATE, 0, 0,
0224 prism2mib_uint32},
0225
0226
0227 {DIDMIB_LNX_CONFIGTABLE_RSNAIE,
0228 F_STA | F_READ | F_WRITE,
0229 HFA384x_RID_CNFWPADATA, 0, 0,
0230 prism2mib_priv},
0231 {0, 0, 0, 0, 0, NULL}
0232 };
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp)
0255 {
0256 struct hfa384x *hw = wlandev->priv;
0257 int result, isget;
0258 struct mibrec *mib;
0259
0260 u16 which;
0261
0262 struct p80211msg_dot11req_mibset *msg = msgp;
0263 struct p80211itemd *mibitem;
0264
0265 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0266 msg->resultcode.data = P80211ENUM_resultcode_success;
0267
0268
0269
0270
0271
0272 which = F_STA;
0273
0274
0275
0276
0277
0278
0279
0280
0281 mibitem = (struct p80211itemd *)msg->mibattribute.data;
0282
0283 for (mib = mibtab; mib->did != 0; mib++)
0284 if (mib->did == mibitem->did && (mib->flag & which))
0285 break;
0286
0287 if (mib->did == 0) {
0288 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
0289 goto done;
0290 }
0291
0292
0293
0294
0295
0296
0297
0298 isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
0299
0300 if (isget) {
0301 if (!(mib->flag & F_READ)) {
0302 msg->resultcode.data =
0303 P80211ENUM_resultcode_cant_get_writeonly_mib;
0304 goto done;
0305 }
0306 } else {
0307 if (!(mib->flag & F_WRITE)) {
0308 msg->resultcode.data =
0309 P80211ENUM_resultcode_cant_set_readonly_mib;
0310 goto done;
0311 }
0312 }
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data);
0323
0324 if (msg->resultcode.data == P80211ENUM_resultcode_success) {
0325 if (result != 0) {
0326 pr_debug("get/set failure, result=%d\n", result);
0327 msg->resultcode.data =
0328 P80211ENUM_resultcode_implementation_failure;
0329 } else {
0330 if (isget) {
0331 msg->mibattribute.status =
0332 P80211ENUM_msgitem_status_data_ok;
0333 mibitem->status =
0334 P80211ENUM_msgitem_status_data_ok;
0335 }
0336 }
0337 }
0338
0339 done:
0340 return 0;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368 static int prism2mib_bytearea2pstr(struct mibrec *mib,
0369 int isget,
0370 struct wlandevice *wlandev,
0371 struct hfa384x *hw,
0372 struct p80211msg_dot11req_mibset *msg,
0373 void *data)
0374 {
0375 int result;
0376 struct p80211pstrd *pstr = data;
0377 u8 bytebuf[MIB_TMP_MAXLEN];
0378
0379 if (isget) {
0380 result =
0381 hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
0382 prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
0383 } else {
0384 memset(bytebuf, 0, mib->parm2);
0385 memcpy(bytebuf, pstr->data, pstr->len);
0386 result =
0387 hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
0388 }
0389
0390 return result;
0391 }
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 static int prism2mib_uint32(struct mibrec *mib,
0419 int isget,
0420 struct wlandevice *wlandev,
0421 struct hfa384x *hw,
0422 struct p80211msg_dot11req_mibset *msg, void *data)
0423 {
0424 int result;
0425 u32 *uint32 = data;
0426 u8 bytebuf[MIB_TMP_MAXLEN];
0427 u16 *wordbuf = (u16 *)bytebuf;
0428
0429 if (isget) {
0430 result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
0431 *uint32 = *wordbuf;
0432 } else {
0433 *wordbuf = *uint32;
0434 result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
0435 }
0436
0437 return result;
0438 }
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 static int prism2mib_flag(struct mibrec *mib,
0466 int isget,
0467 struct wlandevice *wlandev,
0468 struct hfa384x *hw,
0469 struct p80211msg_dot11req_mibset *msg, void *data)
0470 {
0471 int result;
0472 u32 *uint32 = data;
0473 u8 bytebuf[MIB_TMP_MAXLEN];
0474 u16 *wordbuf = (u16 *)bytebuf;
0475 u32 flags;
0476
0477 result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
0478 if (result == 0) {
0479 flags = *wordbuf;
0480 if (isget) {
0481 *uint32 = (flags & mib->parm2) ?
0482 P80211ENUM_truth_true : P80211ENUM_truth_false;
0483 } else {
0484 if ((*uint32) == P80211ENUM_truth_true)
0485 flags |= mib->parm2;
0486 else
0487 flags &= ~mib->parm2;
0488 *wordbuf = flags;
0489 result =
0490 hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
0491 }
0492 }
0493
0494 return result;
0495 }
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 static int prism2mib_wepdefaultkey(struct mibrec *mib,
0523 int isget,
0524 struct wlandevice *wlandev,
0525 struct hfa384x *hw,
0526 struct p80211msg_dot11req_mibset *msg,
0527 void *data)
0528 {
0529 int result;
0530 struct p80211pstrd *pstr = data;
0531 u8 bytebuf[MIB_TMP_MAXLEN];
0532 u16 len;
0533
0534 if (isget) {
0535 result = 0;
0536 } else {
0537 len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
0538 HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
0539 memset(bytebuf, 0, len);
0540 memcpy(bytebuf, pstr->data, pstr->len);
0541 result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
0542 }
0543
0544 return result;
0545 }
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 static int prism2mib_privacyinvoked(struct mibrec *mib,
0573 int isget,
0574 struct wlandevice *wlandev,
0575 struct hfa384x *hw,
0576 struct p80211msg_dot11req_mibset *msg,
0577 void *data)
0578 {
0579 if (wlandev->hostwep & HOSTWEP_DECRYPT) {
0580 if (wlandev->hostwep & HOSTWEP_DECRYPT)
0581 mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
0582 if (wlandev->hostwep & HOSTWEP_ENCRYPT)
0583 mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT;
0584 }
0585
0586 return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
0587 }
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 static int
0615 prism2mib_fragmentationthreshold(struct mibrec *mib,
0616 int isget,
0617 struct wlandevice *wlandev,
0618 struct hfa384x *hw,
0619 struct p80211msg_dot11req_mibset *msg,
0620 void *data)
0621 {
0622 u32 *uint32 = data;
0623
0624 if (!isget)
0625 if ((*uint32) % 2) {
0626 netdev_warn(wlandev->netdev,
0627 "Attempt to set odd number FragmentationThreshold\n");
0628 msg->resultcode.data =
0629 P80211ENUM_resultcode_not_supported;
0630 return 0;
0631 }
0632
0633 return prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
0634 }
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 static int prism2mib_priv(struct mibrec *mib,
0662 int isget,
0663 struct wlandevice *wlandev,
0664 struct hfa384x *hw,
0665 struct p80211msg_dot11req_mibset *msg, void *data)
0666 {
0667 struct p80211pstrd *pstr = data;
0668
0669 switch (mib->did) {
0670 case DIDMIB_LNX_CONFIGTABLE_RSNAIE: {
0671
0672
0673
0674
0675 struct hfa384x_wpa_data wpa;
0676
0677 if (isget) {
0678 hfa384x_drvr_getconfig(hw,
0679 HFA384x_RID_CNFWPADATA,
0680 (u8 *)&wpa,
0681 sizeof(wpa));
0682 pstr->len = 0;
0683 } else {
0684 wpa.datalen = 0;
0685
0686 hfa384x_drvr_setconfig(hw,
0687 HFA384x_RID_CNFWPADATA,
0688 (u8 *)&wpa,
0689 sizeof(wpa));
0690 }
0691 break;
0692 }
0693 default:
0694 netdev_err(wlandev->netdev, "Unhandled DID 0x%08x\n", mib->did);
0695 }
0696
0697 return 0;
0698 }
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715 void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
0716 struct p80211pstrd *pstr)
0717 {
0718 bytestr->len = cpu_to_le16((u16)(pstr->len));
0719 memcpy(bytestr->data, pstr->data, pstr->len);
0720 }
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737 void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
0738 struct p80211pstrd *pstr)
0739 {
0740 pstr->len = (u8)(le16_to_cpu(bytestr->len));
0741 memcpy(pstr->data, bytestr->data, pstr->len);
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759 void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len)
0760 {
0761 pstr->len = (u8)len;
0762 memcpy(pstr->data, bytearea, len);
0763 }