1 // SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
4 * Management request for mibset/mibget
6 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
7 * --------------------------------------------------------------------
11 * --------------------------------------------------------------------
13 * Inquiries regarding the linux-wlan Open Source project can be
16 * AbsoluteValue Systems Inc.
18 * http://www.linux-wlan.com
20 * --------------------------------------------------------------------
22 * Portions of the development of this software were funded by
23 * Intersil Corporation as part of PRISM(R) chipset product development.
25 * --------------------------------------------------------------------
27 * The functions in this file handle the mibset/mibget management
30 * --------------------------------------------------------------------
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/sched.h>
36 #include <linux/types.h>
37 #include <linux/wireless.h>
38 #include <linux/netdevice.h>
40 #include <linux/delay.h>
41 #include <asm/byteorder.h>
42 #include <linux/usb.h>
43 #include <linux/bitops.h>
45 #include "p80211types.h"
46 #include "p80211hdr.h"
47 #include "p80211mgmt.h"
48 #include "p80211conv.h"
49 #include "p80211msg.h"
50 #include "p80211netdev.h"
51 #include "p80211metadef.h"
52 #include "p80211metastruct.h"
54 #include "prism2mgmt.h"
56 #define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
58 #define F_STA 0x1 /* MIB is supported on stations. */
59 #define F_READ 0x2 /* MIB may be read. */
60 #define F_WRITE 0x4 /* MIB may be written. */
68 int (*func)(struct mibrec *mib,
70 struct wlandevice *wlandev,
72 struct p80211msg_dot11req_mibset *msg, void *data);
75 static int prism2mib_bytearea2pstr(struct mibrec *mib,
77 struct wlandevice *wlandev,
79 struct p80211msg_dot11req_mibset *msg,
82 static int prism2mib_uint32(struct mibrec *mib,
84 struct wlandevice *wlandev,
86 struct p80211msg_dot11req_mibset *msg, void *data);
88 static int prism2mib_flag(struct mibrec *mib,
90 struct wlandevice *wlandev,
92 struct p80211msg_dot11req_mibset *msg, void *data);
94 static int prism2mib_wepdefaultkey(struct mibrec *mib,
96 struct wlandevice *wlandev,
98 struct p80211msg_dot11req_mibset *msg,
101 static int prism2mib_privacyinvoked(struct mibrec *mib,
103 struct wlandevice *wlandev,
105 struct p80211msg_dot11req_mibset *msg,
109 prism2mib_fragmentationthreshold(struct mibrec *mib,
111 struct wlandevice *wlandev,
113 struct p80211msg_dot11req_mibset *msg,
116 static int prism2mib_priv(struct mibrec *mib,
118 struct wlandevice *wlandev,
120 struct p80211msg_dot11req_mibset *msg, void *data);
122 static struct mibrec mibtab[] = {
124 {didmib_dot11smt_wepdefaultkeystable_key(1),
126 HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
127 prism2mib_wepdefaultkey},
128 {didmib_dot11smt_wepdefaultkeystable_key(2),
130 HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
131 prism2mib_wepdefaultkey},
132 {didmib_dot11smt_wepdefaultkeystable_key(3),
134 HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
135 prism2mib_wepdefaultkey},
136 {didmib_dot11smt_wepdefaultkeystable_key(4),
138 HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
139 prism2mib_wepdefaultkey},
140 {DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
141 F_STA | F_READ | F_WRITE,
142 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
143 prism2mib_privacyinvoked},
144 {DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
145 F_STA | F_READ | F_WRITE,
146 HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
148 {DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
149 F_STA | F_READ | F_WRITE,
150 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
155 {DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS,
156 F_STA | F_READ | F_WRITE,
157 HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
158 prism2mib_bytearea2pstr},
159 {DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
160 F_STA | F_READ | F_WRITE,
161 HFA384x_RID_RTSTHRESH, 0, 0,
163 {DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT,
165 HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
167 {DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT,
169 HFA384x_RID_LONGRETRYLIMIT, 0, 0,
171 {DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
172 F_STA | F_READ | F_WRITE,
173 HFA384x_RID_FRAGTHRESH, 0, 0,
174 prism2mib_fragmentationthreshold},
175 {DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME,
177 HFA384x_RID_MAXTXLIFETIME, 0, 0,
182 {DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
184 HFA384x_RID_CURRENTCHANNEL, 0, 0,
186 {DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
187 F_STA | F_READ | F_WRITE,
188 HFA384x_RID_TXPOWERMAX, 0, 0,
193 {DIDMIB_P2_STATIC_CNFPORTTYPE,
194 F_STA | F_READ | F_WRITE,
195 HFA384x_RID_CNFPORTTYPE, 0, 0,
200 {DIDMIB_P2_MAC_CURRENTTXRATE,
202 HFA384x_RID_CURRENTTXRATE, 0, 0,
205 /* And finally, lnx mibs */
206 {DIDMIB_LNX_CONFIGTABLE_RSNAIE,
207 F_STA | F_READ | F_WRITE,
208 HFA384x_RID_CNFWPADATA, 0, 0,
210 {0, 0, 0, 0, 0, NULL}
214 * prism2mgmt_mibset_mibget
216 * Set the value of a mib item.
219 * wlandev wlan device structure
220 * msgp ptr to msg buffer
224 * <0 success, but we're waiting for something to finish.
225 * >0 an error occurred while handling the message.
229 * process thread (usually)
233 int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp)
235 struct hfa384x *hw = wlandev->priv;
241 struct p80211msg_dot11req_mibset *msg = msgp;
242 struct p80211itemd *mibitem;
244 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
245 msg->resultcode.data = P80211ENUM_resultcode_success;
248 ** Determine if this is an Access Point or a station.
254 ** Find the MIB in the MIB table. Note that a MIB may be in the
255 ** table twice...once for an AP and once for a station. Make sure
256 ** to get the correct one. Note that DID=0 marks the end of the
260 mibitem = (struct p80211itemd *)msg->mibattribute.data;
262 for (mib = mibtab; mib->did != 0; mib++)
263 if (mib->did == mibitem->did && (mib->flag & which))
267 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
272 ** Determine if this is a "mibget" or a "mibset". If this is a
273 ** "mibget", then make sure that the MIB may be read. Otherwise,
274 ** this is a "mibset" so make sure that the MIB may be written.
277 isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
280 if (!(mib->flag & F_READ)) {
281 msg->resultcode.data =
282 P80211ENUM_resultcode_cant_get_writeonly_mib;
286 if (!(mib->flag & F_WRITE)) {
287 msg->resultcode.data =
288 P80211ENUM_resultcode_cant_set_readonly_mib;
294 ** Execute the MIB function. If things worked okay, then make
295 ** sure that the MIB function also worked okay. If so, and this
296 ** is a "mibget", then the status value must be set for both the
297 ** "mibattribute" parameter and the mib item within the data
298 ** portion of the "mibattribute".
301 result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data);
303 if (msg->resultcode.data == P80211ENUM_resultcode_success) {
305 pr_debug("get/set failure, result=%d\n", result);
306 msg->resultcode.data =
307 P80211ENUM_resultcode_implementation_failure;
310 msg->mibattribute.status =
311 P80211ENUM_msgitem_status_data_ok;
313 P80211ENUM_msgitem_status_data_ok;
323 * prism2mib_bytearea2pstr
325 * Get/set pstr data to/from a byte area.
327 * MIB record parameters:
328 * parm1 Prism2 RID value.
329 * parm2 Number of bytes of RID data.
334 * isget MIBGET/MIBSET flag.
335 * wlandev wlan device structure.
336 * priv "priv" structure.
338 * msg Message structure.
347 static int prism2mib_bytearea2pstr(struct mibrec *mib,
349 struct wlandevice *wlandev,
351 struct p80211msg_dot11req_mibset *msg,
355 struct p80211pstrd *pstr = data;
356 u8 bytebuf[MIB_TMP_MAXLEN];
360 hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
361 prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
363 memset(bytebuf, 0, mib->parm2);
364 memcpy(bytebuf, pstr->data, pstr->len);
366 hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
375 * Get/set uint32 data.
377 * MIB record parameters:
378 * parm1 Prism2 RID value.
384 * isget MIBGET/MIBSET flag.
385 * wlandev wlan device structure.
386 * priv "priv" structure.
388 * msg Message structure.
397 static int prism2mib_uint32(struct mibrec *mib,
399 struct wlandevice *wlandev,
401 struct p80211msg_dot11req_mibset *msg, void *data)
405 u8 bytebuf[MIB_TMP_MAXLEN];
406 u16 *wordbuf = (u16 *)bytebuf;
409 result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
413 result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
424 * MIB record parameters:
425 * parm1 Prism2 RID value.
426 * parm2 Bit to get/set.
431 * isget MIBGET/MIBSET flag.
432 * wlandev wlan device structure.
433 * priv "priv" structure.
435 * msg Message structure.
444 static int prism2mib_flag(struct mibrec *mib,
446 struct wlandevice *wlandev,
448 struct p80211msg_dot11req_mibset *msg, void *data)
452 u8 bytebuf[MIB_TMP_MAXLEN];
453 u16 *wordbuf = (u16 *)bytebuf;
456 result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
460 *uint32 = (flags & mib->parm2) ?
461 P80211ENUM_truth_true : P80211ENUM_truth_false;
463 if ((*uint32) == P80211ENUM_truth_true)
466 flags &= ~mib->parm2;
469 hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
477 * prism2mib_wepdefaultkey
479 * Get/set WEP default keys.
481 * MIB record parameters:
482 * parm1 Prism2 RID value.
483 * parm2 Number of bytes of RID data.
488 * isget MIBGET/MIBSET flag.
489 * wlandev wlan device structure.
490 * priv "priv" structure.
492 * msg Message structure.
501 static int prism2mib_wepdefaultkey(struct mibrec *mib,
503 struct wlandevice *wlandev,
505 struct p80211msg_dot11req_mibset *msg,
509 struct p80211pstrd *pstr = data;
510 u8 bytebuf[MIB_TMP_MAXLEN];
514 result = 0; /* Should never happen. */
516 len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
517 HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
518 memset(bytebuf, 0, len);
519 memcpy(bytebuf, pstr->data, pstr->len);
520 result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
527 * prism2mib_privacyinvoked
529 * Get/set the dot11PrivacyInvoked value.
531 * MIB record parameters:
532 * parm1 Prism2 RID value.
533 * parm2 Bit value for PrivacyInvoked flag.
538 * isget MIBGET/MIBSET flag.
539 * wlandev wlan device structure.
540 * priv "priv" structure.
542 * msg Message structure.
551 static int prism2mib_privacyinvoked(struct mibrec *mib,
553 struct wlandevice *wlandev,
555 struct p80211msg_dot11req_mibset *msg,
558 if (wlandev->hostwep & HOSTWEP_DECRYPT) {
559 if (wlandev->hostwep & HOSTWEP_DECRYPT)
560 mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
561 if (wlandev->hostwep & HOSTWEP_ENCRYPT)
562 mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT;
565 return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
569 * prism2mib_fragmentationthreshold
571 * Get/set the fragmentation threshold.
573 * MIB record parameters:
574 * parm1 Prism2 RID value.
580 * isget MIBGET/MIBSET flag.
581 * wlandev wlan device structure.
582 * priv "priv" structure.
584 * msg Message structure.
594 prism2mib_fragmentationthreshold(struct mibrec *mib,
596 struct wlandevice *wlandev,
598 struct p80211msg_dot11req_mibset *msg,
605 netdev_warn(wlandev->netdev,
606 "Attempt to set odd number FragmentationThreshold\n");
607 msg->resultcode.data =
608 P80211ENUM_resultcode_not_supported;
612 return prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
618 * Get/set values in the "priv" data structure.
620 * MIB record parameters:
627 * isget MIBGET/MIBSET flag.
628 * wlandev wlan device structure.
629 * priv "priv" structure.
631 * msg Message structure.
640 static int prism2mib_priv(struct mibrec *mib,
642 struct wlandevice *wlandev,
644 struct p80211msg_dot11req_mibset *msg, void *data)
646 struct p80211pstrd *pstr = data;
649 case DIDMIB_LNX_CONFIGTABLE_RSNAIE: {
651 * This can never work: wpa is on the stack
652 * and has no bytes allocated in wpa.data.
654 struct hfa384x_wpa_data wpa;
657 hfa384x_drvr_getconfig(hw,
658 HFA384x_RID_CNFWPADATA,
665 hfa384x_drvr_setconfig(hw,
666 HFA384x_RID_CNFWPADATA,
673 netdev_err(wlandev->netdev, "Unhandled DID 0x%08x\n", mib->did);
680 * prism2mgmt_pstr2bytestr
682 * Convert the pstr data in the WLAN message structure into an hfa384x
683 * byte string format.
686 * bytestr hfa384x byte string data type
687 * pstr wlan message data
694 void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
695 struct p80211pstrd *pstr)
697 bytestr->len = cpu_to_le16((u16)(pstr->len));
698 memcpy(bytestr->data, pstr->data, pstr->len);
702 * prism2mgmt_bytestr2pstr
704 * Convert the data in an hfa384x byte string format into a
705 * pstr in the WLAN message.
708 * bytestr hfa384x byte string data type
716 void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
717 struct p80211pstrd *pstr)
719 pstr->len = (u8)(le16_to_cpu(bytestr->len));
720 memcpy(pstr->data, bytestr->data, pstr->len);
724 * prism2mgmt_bytearea2pstr
726 * Convert the data in an hfa384x byte area format into a pstr
727 * in the WLAN message.
730 * bytearea hfa384x byte area data type
738 void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len)
741 memcpy(pstr->data, bytearea, len);