summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/dladm/dladm.c17
-rw-r--r--usr/src/lib/libdladm/common/libdlwlan.c368
-rw-r--r--usr/src/lib/libdladm/common/libdlwlan_impl.h13
-rw-r--r--usr/src/lib/libdladm/common/linkprop.c519
-rw-r--r--usr/src/uts/common/io/ath/ath_main.c57
-rw-r--r--usr/src/uts/common/io/iwk/iwk2.c53
-rw-r--r--usr/src/uts/common/io/net80211/net80211_impl.h5
-rw-r--r--usr/src/uts/common/io/net80211/net80211_ioctl.c1630
-rw-r--r--usr/src/uts/common/io/wpi/wpi.c53
-rw-r--r--usr/src/uts/common/sys/mac.h22
-rw-r--r--usr/src/uts/common/sys/net80211.h6
11 files changed, 1856 insertions, 887 deletions
diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c
index 62c4860594..eacd59fee5 100644
--- a/usr/src/cmd/dladm/dladm.c
+++ b/usr/src/cmd/dladm/dladm.c
@@ -4480,6 +4480,19 @@ skip:
return ("");
}
+static boolean_t
+linkprop_is_supported(datalink_id_t linkid, const char *propname,
+ show_linkprop_state_t *statep)
+{
+ dladm_status_t status;
+ uint_t valcnt = DLADM_MAX_PROP_VALCNT;
+
+ status = dladm_get_linkprop(linkid, DLADM_PROP_VAL_DEFAULT,
+ propname, statep->ls_propvals, &valcnt);
+
+ return (status != DLADM_STATUS_NOTSUP);
+}
+
static int
show_linkprop(datalink_id_t linkid, const char *propname, void *arg)
{
@@ -4496,6 +4509,9 @@ show_linkprop(datalink_id_t linkid, const char *propname, void *arg)
if (!statep->ls_parseable)
print_header(&statep->ls_print);
}
+ if (!linkprop_is_supported(linkid, propname, statep))
+ return (DLADM_WALK_CONTINUE);
+
dladm_print_output(&statep->ls_print, statep->ls_parseable,
linkprop_callback, (void *)&ls_arg);
@@ -5851,7 +5867,6 @@ show_ether_xprop(datalink_id_t linkid, void *arg)
(void) snprintf(ebuf.eth_ptype, sizeof (ebuf.eth_ptype),
"%s", "peeradv");
(void) snprintf(ebuf.eth_state, sizeof (ebuf.eth_state), "");
-
(void) dladm_get_single_mac_stat(linkid, "lp_cap_autoneg",
KSTAT_DATA_UINT32, &autoneg);
(void) snprintf(ebuf.eth_autoneg, sizeof (ebuf.eth_autoneg),
diff --git a/usr/src/lib/libdladm/common/libdlwlan.c b/usr/src/lib/libdladm/common/libdlwlan.c
index ee46fca3ee..9694c5350b 100644
--- a/usr/src/lib/libdladm/common/libdlwlan.c
+++ b/usr/src/lib/libdladm/common/libdlwlan.c
@@ -46,18 +46,18 @@
static dladm_status_t wpa_instance_create(datalink_id_t, void *);
static dladm_status_t wpa_instance_delete(datalink_id_t);
-static dladm_status_t do_get_bsstype(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_essid(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_bssid(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_signal(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_encryption(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_authmode(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_linkstatus(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_esslist(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_rate(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_mode(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_capability(datalink_id_t, wldp_t *);
-static dladm_status_t do_get_wpamode(datalink_id_t, wldp_t *);
+static dladm_status_t do_get_bsstype(datalink_id_t, void *, int);
+static dladm_status_t do_get_essid(datalink_id_t, void *, int);
+static dladm_status_t do_get_bssid(datalink_id_t, void *, int);
+static dladm_status_t do_get_signal(datalink_id_t, void *, int);
+static dladm_status_t do_get_encryption(datalink_id_t, void *, int);
+static dladm_status_t do_get_authmode(datalink_id_t, void *, int);
+static dladm_status_t do_get_linkstatus(datalink_id_t, void *, int);
+static dladm_status_t do_get_esslist(datalink_id_t, void *, int);
+static dladm_status_t do_get_rate(datalink_id_t, void *, int);
+static dladm_status_t do_get_mode(datalink_id_t, void *, int);
+static dladm_status_t do_get_capability(datalink_id_t, void *, int);
+static dladm_status_t do_get_wpamode(datalink_id_t, void *, int);
static dladm_status_t do_set_bsstype(datalink_id_t, dladm_wlan_bsstype_t *);
static dladm_status_t do_set_authmode(datalink_id_t, dladm_wlan_auth_t *);
@@ -68,10 +68,11 @@ static dladm_status_t do_set_createibss(datalink_id_t, boolean_t *);
static dladm_status_t do_set_key(datalink_id_t, dladm_wlan_key_t *, uint_t);
static dladm_status_t do_set_channel(datalink_id_t, dladm_wlan_channel_t *);
-static dladm_status_t do_scan(datalink_id_t, wldp_t *);
-static dladm_status_t do_connect(datalink_id_t, wldp_t *, dladm_wlan_attr_t *,
- boolean_t, void *, uint_t, int);
-static dladm_status_t do_disconnect(datalink_id_t, wldp_t *);
+static dladm_status_t do_scan(datalink_id_t, void *, int);
+static dladm_status_t do_connect(datalink_id_t, void *, int,
+ dladm_wlan_attr_t *, boolean_t, void *, uint_t,
+ int);
+static dladm_status_t do_disconnect(datalink_id_t, void *, int);
static boolean_t find_val_by_name(const char *, val_desc_t *,
uint_t, uint_t *);
static boolean_t find_name_by_val(uint_t, val_desc_t *, uint_t, char **);
@@ -116,8 +117,7 @@ static val_desc_t bsstype_vals[] = {
{ "any", DLADM_WLAN_BSSTYPE_ANY }
};
-#define IS_CONNECTED(gbuf) \
- ((*(wl_linkstatus_t *)((gbuf)->wldp_buf) == WL_CONNECTED))
+#define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET)
static dladm_status_t
dladm_wlan_wlresult2status(wldp_t *gbuf)
@@ -237,24 +237,20 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg,
int i;
uint32_t count;
wl_ess_conf_t *wlp;
- wldp_t *gbuf = NULL;
+ wl_ess_list_t *wls = NULL;
+ char buf[WLDP_BUFSIZE];
+ wl_linkstatus_t wl_status;
dladm_wlan_attr_t wlattr;
dladm_status_t status;
- boolean_t connected;
if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK)
goto done;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) {
- status = DLADM_STATUS_NOMEM;
- goto done;
- }
-
- if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK)
+ status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status));
+ if (status != DLADM_STATUS_OK)
goto done;
- connected = IS_CONNECTED(gbuf);
- if ((status = do_scan(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_scan(linkid, buf, sizeof (buf))) != DLADM_STATUS_OK)
goto done;
if (func == NULL) {
@@ -262,11 +258,18 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg,
goto done;
}
- if ((status = do_get_esslist(linkid, gbuf)) != DLADM_STATUS_OK)
+ wls = malloc(WLDP_BUFSIZE);
+ if (wls == NULL) {
+ status = DLADM_STATUS_NOMEM;
+ goto done;
+ }
+
+ if ((status = do_get_esslist(linkid, wls, WLDP_BUFSIZE))
+ != DLADM_STATUS_OK)
goto done;
- wlp = ((wl_ess_list_t *)gbuf->wldp_buf)->wl_ess_list_ess;
- count = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num;
+ wlp = wls->wl_ess_list_ess;
+ count = wls->wl_ess_list_num;
for (i = 0; i < count; i++, wlp++) {
fill_wlan_attr(wlp, &wlattr);
@@ -274,17 +277,18 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg,
break;
}
- if (!connected) {
- status = do_get_linkstatus(linkid, gbuf);
+ if (wl_status != WL_CONNECTED) {
+ status = do_get_linkstatus(linkid, &wl_status,
+ sizeof (&wl_status));
if (status != DLADM_STATUS_OK)
goto done;
- if (IS_CONNECTED(gbuf))
- (void) do_disconnect(linkid, gbuf);
+ if (wl_status == WL_CONNECTED)
+ (void) do_disconnect(linkid, buf, sizeof (buf));
}
status = DLADM_STATUS_OK;
done:
- free(gbuf);
+ free(wls);
return (status);
}
@@ -398,8 +402,9 @@ append:
#define IEEE80211_C_WPA 0x01800000
static dladm_status_t
-do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp,
- boolean_t create_ibss, void *keys, uint_t key_count, int timeout)
+do_connect(datalink_id_t linkid, void *buf, int bufsize,
+ dladm_wlan_attr_t *attrp, boolean_t create_ibss, void *keys,
+ uint_t key_count, int timeout)
{
dladm_wlan_secmode_t secmode;
dladm_wlan_auth_t authmode;
@@ -410,6 +415,7 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp,
dladm_wlan_channel_t channel;
hrtime_t start;
wl_capability_t *caps;
+ wl_linkstatus_t wl_status;
if ((attrp->wa_valid & DLADM_WLAN_ATTR_CHANNEL) != 0) {
channel = attrp->wa_channel;
@@ -451,10 +457,10 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp,
status = DLADM_STATUS_BADARG;
goto fail;
}
- status = do_get_capability(linkid, gbuf);
+ status = do_get_capability(linkid, buf, bufsize);
if (status != DLADM_STATUS_OK)
goto fail;
- caps = (wl_capability_t *)(gbuf->wldp_buf);
+ caps = (wl_capability_t *)buf;
if ((caps->caps & IEEE80211_C_WPA) == 0)
return (DLADM_STATUS_NOTSUP);
}
@@ -496,11 +502,12 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp,
start = gethrtime();
for (;;) {
- status = do_get_linkstatus(linkid, gbuf);
+ status = do_get_linkstatus(linkid, &wl_status,
+ sizeof (wl_status));
if (status != DLADM_STATUS_OK)
goto fail;
- if (IS_CONNECTED(gbuf))
+ if (wl_status == WL_CONNECTED)
break;
(void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE);
@@ -520,23 +527,22 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp,
int timeout, void *keys, uint_t key_count, uint_t flags)
{
int i;
- wldp_t *gbuf = NULL;
+ char buf[WLDP_BUFSIZE];
connect_state_t state = {0, NULL, NULL};
attr_node_t *nodep = NULL;
boolean_t create_ibss, set_authmode;
dladm_wlan_attr_t **wl_list = NULL;
dladm_status_t status;
+ wl_linkstatus_t wl_status;
if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK)
return (status);
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
- return (DLADM_STATUS_NOMEM);
-
- if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status)))
+ != DLADM_STATUS_OK)
goto done;
- if (IS_CONNECTED(gbuf)) {
+ if (wl_status == WL_CONNECTED) {
status = DLADM_STATUS_ISCONN;
goto done;
}
@@ -551,8 +557,8 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp,
if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0 ||
(create_ibss && attrp != NULL &&
(attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0)) {
- status = do_connect(linkid, gbuf, attrp, create_ibss, keys,
- key_count, timeout);
+ status = do_connect(linkid, buf, sizeof (buf), attrp,
+ create_ibss, keys, key_count, timeout);
goto done;
}
@@ -569,8 +575,8 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp,
status = DLADM_STATUS_NOTFOUND;
goto done;
}
- status = do_connect(linkid, gbuf, attrp, create_ibss, keys,
- key_count, timeout);
+ status = do_connect(linkid, buf, sizeof (buf),
+ attrp, create_ibss, keys, key_count, timeout);
goto done;
}
@@ -591,30 +597,29 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp,
for (i = 0; i < state.cs_count; i++) {
dladm_wlan_attr_t *ap = wl_list[i];
- status = do_connect(linkid, gbuf, ap, create_ibss, keys,
- key_count, timeout);
+ status = do_connect(linkid, buf, sizeof (buf),
+ ap, create_ibss, keys, key_count, timeout);
if (status == DLADM_STATUS_OK)
break;
if (!set_authmode) {
ap->wa_auth = DLADM_WLAN_AUTH_SHARED;
ap->wa_valid |= DLADM_WLAN_ATTR_AUTH;
- status = do_connect(linkid, gbuf, ap, create_ibss, keys,
- key_count, timeout);
+ status = do_connect(linkid, buf, sizeof (buf),
+ ap, create_ibss, keys, key_count, timeout);
if (status == DLADM_STATUS_OK)
break;
}
}
done:
if ((status != DLADM_STATUS_OK) && (status != DLADM_STATUS_ISCONN))
- (void) do_disconnect(linkid, gbuf);
+ (void) do_disconnect(linkid, buf, sizeof (buf));
while (state.cs_list != NULL) {
nodep = state.cs_list;
state.cs_list = nodep->an_next;
free(nodep);
}
- free(gbuf);
free(wl_list);
return (status);
}
@@ -622,53 +627,54 @@ done:
dladm_status_t
dladm_wlan_disconnect(datalink_id_t linkid)
{
- wldp_t *gbuf;
+ char buf[WLDP_BUFSIZE];
dladm_status_t status;
+ wl_linkstatus_t wl_status;
if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK)
return (status);
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) {
- status = DLADM_STATUS_NOMEM;
- goto done;
- }
-
- if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status)))
+ != DLADM_STATUS_OK)
goto done;
- if (!IS_CONNECTED(gbuf)) {
+ if (wl_status != WL_CONNECTED) {
status = DLADM_STATUS_NOTCONN;
goto done;
}
- if ((status = do_disconnect(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_disconnect(linkid, buf, sizeof (buf)))
+ != DLADM_STATUS_OK)
goto done;
- if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status)))
+ != DLADM_STATUS_OK)
goto done;
- if (IS_CONNECTED(gbuf)) {
+ if (wl_status == WL_CONNECTED) {
status = DLADM_STATUS_FAILED;
goto done;
}
status = DLADM_STATUS_OK;
done:
- free(gbuf);
return (status);
}
dladm_status_t
dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
{
- wldp_t *gbuf = NULL;
wl_rssi_t signal;
wl_bss_type_t bsstype;
wl_authmode_t authmode;
wl_encryption_t encryption;
- wl_rates_t *ratesp;
+ wl_rates_t *ratesp = NULL;
dladm_wlan_attr_t *wl_attrp;
dladm_status_t status;
+ char buf[WLDP_BUFSIZE];
+ wl_essid_t wls;
+ wl_phy_conf_t wl_phy_conf;
+ wl_linkstatus_t wl_status;
if (attrp == NULL)
return (DLADM_STATUS_BADARG);
@@ -676,37 +682,33 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK)
goto done;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) {
- status = DLADM_STATUS_NOMEM;
- goto done;
- }
-
(void) memset(attrp, 0, sizeof (*attrp));
wl_attrp = &attrp->la_wlan_attr;
- if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status)))
+ != DLADM_STATUS_OK)
goto done;
attrp->la_valid |= DLADM_WLAN_LINKATTR_STATUS;
- if (!IS_CONNECTED(gbuf))
+ if (wl_status != WL_CONNECTED)
attrp->la_status = DLADM_WLAN_LINK_DISCONNECTED;
else
attrp->la_status = DLADM_WLAN_LINK_CONNECTED;
- if ((status = do_get_essid(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_essid(linkid, &wls, sizeof (wls)))
+ != DLADM_STATUS_OK)
goto done;
- (void) strlcpy(wl_attrp->wa_essid.we_bytes,
- ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid,
+ (void) strlcpy(wl_attrp->wa_essid.we_bytes, wls.wl_essid_essid,
DLADM_WLAN_MAX_ESSID_LEN);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID;
- if ((status = do_get_bssid(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_bssid(linkid, buf, sizeof (buf)))
+ != DLADM_STATUS_OK)
goto done;
- (void) memcpy(wl_attrp->wa_bssid.wb_bytes, gbuf->wldp_buf,
- DLADM_WLAN_BSSID_LEN);
+ (void) memcpy(wl_attrp->wa_bssid.wb_bytes, buf, DLADM_WLAN_BSSID_LEN);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID;
@@ -716,10 +718,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
goto done;
}
- if ((status = do_get_encryption(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_encryption(linkid, &encryption,
+ sizeof (encryption))) != DLADM_STATUS_OK)
goto done;
- encryption = *(wl_encryption_t *)(gbuf->wldp_buf);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE;
switch (encryption) {
@@ -737,17 +739,23 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
break;
}
- if ((status = do_get_signal(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_signal(linkid, &signal, sizeof (signal)))
+ != DLADM_STATUS_OK)
goto done;
- signal = *(wl_rssi_t *)(gbuf->wldp_buf);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH;
wl_attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(signal);
- if ((status = do_get_rate(linkid, gbuf)) != DLADM_STATUS_OK)
+ ratesp = malloc(WLDP_BUFSIZE);
+ if (ratesp == NULL) {
+ status = DLADM_STATUS_NOMEM;
+ goto done;
+ }
+
+ if ((status = do_get_rate(linkid, ratesp, WLDP_BUFSIZE))
+ != DLADM_STATUS_OK)
goto done;
- ratesp = (wl_rates_t *)(gbuf->wldp_buf);
if (ratesp->wl_rates_num > 0) {
uint_t i, r = 0;
@@ -759,10 +767,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED;
}
- if ((status = do_get_authmode(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_authmode(linkid, &authmode,
+ sizeof (authmode))) != DLADM_STATUS_OK)
goto done;
- authmode = *(wl_authmode_t *)(gbuf->wldp_buf);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
switch (authmode) {
@@ -777,10 +785,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
break;
}
- if ((status = do_get_bsstype(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_bsstype(linkid, &bsstype,
+ sizeof (bsstype))) != DLADM_STATUS_OK)
goto done;
- bsstype = *(wl_bss_type_t *)(gbuf->wldp_buf);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE;
switch (bsstype) {
@@ -798,10 +806,11 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
break;
}
- if ((status = do_get_mode(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_mode(linkid, &wl_phy_conf,
+ sizeof (wl_phy_conf))) != DLADM_STATUS_OK)
goto done;
- wl_attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)(gbuf->wldp_buf));
+ wl_attrp->wa_mode = do_convert_mode(&wl_phy_conf);
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE;
if (wl_attrp->wa_mode != DLADM_WLAN_MODE_NONE)
wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE;
@@ -810,7 +819,7 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp)
status = DLADM_STATUS_OK;
done:
- free(gbuf);
+ free(ratesp);
return (status);
}
@@ -1047,8 +1056,8 @@ dladm_wlan_str2linkstatus(const char *str, dladm_wlan_linkstatus_t *linkstatus)
}
dladm_status_t
-i_dladm_wlan_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, size_t len,
- uint_t cmd, size_t cmdlen)
+i_dladm_wlan_legacy_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id,
+ size_t len, uint_t cmd, size_t cmdlen)
{
char linkname[MAXPATHLEN];
int fd, rc;
@@ -1105,17 +1114,8 @@ i_dladm_wlan_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, size_t len,
return (status);
}
-dladm_status_t
-i_dladm_wlan_get_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id)
-{
- (void) memset(gbuf, 0, MAX_BUF_LEN);
- return (i_dladm_wlan_ioctl(linkid, gbuf, id, MAX_BUF_LEN,
- WLAN_GET_PARAM, MAX_BUF_LEN));
-}
-
-dladm_status_t
-i_dladm_wlan_set_ioctl(datalink_id_t linkid, uint_t id, void *buf,
- uint_t buflen)
+static dladm_status_t
+do_cmd_ioctl(datalink_id_t linkid, void *buf, int buflen, uint_t cmd)
{
wldp_t *gbuf;
dladm_status_t status = DLADM_STATUS_OK;
@@ -1124,99 +1124,97 @@ i_dladm_wlan_set_ioctl(datalink_id_t linkid, uint_t id, void *buf,
return (DLADM_STATUS_NOMEM);
(void) memset(gbuf, 0, MAX_BUF_LEN);
- (void) memcpy(gbuf->wldp_buf, buf, buflen);
- buflen += WIFI_BUF_OFFSET;
- status = i_dladm_wlan_ioctl(linkid, gbuf, id, buflen,
- WLAN_SET_PARAM, buflen);
-
+ status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, cmd, WLDP_BUFSIZE,
+ WLAN_COMMAND, sizeof (wldp_t));
+ (void) memcpy(buf, gbuf->wldp_buf, buflen);
free(gbuf);
return (status);
}
static dladm_status_t
-do_cmd_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t cmd)
+do_scan(datalink_id_t linkid, void *buf, int buflen)
{
- (void) memset(gbuf, 0, MAX_BUF_LEN);
- return (i_dladm_wlan_ioctl(linkid, gbuf, cmd, sizeof (wldp_t),
- WLAN_COMMAND, sizeof (wldp_t)));
+ return (do_cmd_ioctl(linkid, buf, buflen, WL_SCAN));
}
static dladm_status_t
-do_scan(datalink_id_t linkid, wldp_t *gbuf)
+do_disconnect(datalink_id_t linkid, void *buf, int buflen)
{
- return (do_cmd_ioctl(linkid, gbuf, WL_SCAN));
-}
-
-static dladm_status_t
-do_disconnect(datalink_id_t linkid, wldp_t *gbuf)
-{
- if (do_get_wpamode(linkid, gbuf) == 0 &&
- ((wl_wpa_t *)(gbuf->wldp_buf))->wpa_flag > 0)
+ if (do_get_wpamode(linkid, buf, buflen) == 0 &&
+ ((wl_wpa_t *)(buf))->wpa_flag > 0)
(void) wpa_instance_delete(linkid);
- return (do_cmd_ioctl(linkid, gbuf, WL_DISASSOCIATE));
+ return (do_cmd_ioctl(linkid, buf, buflen, WL_DISASSOCIATE));
}
static dladm_status_t
-do_get_esslist(datalink_id_t linkid, wldp_t *gbuf)
+do_get_esslist(datalink_id_t linkid, void *buf, int buflen)
{
- (void) memset(gbuf, 0, MAX_BUF_LEN);
- return (i_dladm_wlan_ioctl(linkid, gbuf, WL_ESS_LIST, MAX_BUF_LEN,
- WLAN_GET_PARAM, sizeof (wldp_t)));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ESS_LIST, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_bssid(datalink_id_t linkid, wldp_t *gbuf)
+do_get_bssid(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_BSSID));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_BSSID, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_essid(datalink_id_t linkid, wldp_t *gbuf)
+do_get_essid(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_ESSID));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ESSID, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_bsstype(datalink_id_t linkid, wldp_t *gbuf)
+do_get_bsstype(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_BSS_TYPE));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_BSSTYPE, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_linkstatus(datalink_id_t linkid, wldp_t *gbuf)
+do_get_linkstatus(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_LINKSTATUS));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_LINKSTATUS, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_rate(datalink_id_t linkid, wldp_t *gbuf)
+do_get_rate(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_DESIRED_RATES));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_DESIRED_RATES,
+ buflen, B_FALSE));
}
static dladm_status_t
-do_get_authmode(datalink_id_t linkid, wldp_t *gbuf)
+do_get_authmode(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_AUTH_MODE));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_AUTH_MODE, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_encryption(datalink_id_t linkid, wldp_t *gbuf)
+do_get_encryption(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_ENCRYPTION));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ENCRYPTION, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_signal(datalink_id_t linkid, wldp_t *gbuf)
+do_get_signal(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_RSSI));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RSSI, buflen,
+ B_FALSE));
}
static dladm_status_t
-do_get_mode(datalink_id_t linkid, wldp_t *gbuf)
+do_get_mode(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_PHY_CONFIG));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG,
+ buflen, B_FALSE));
}
static dladm_status_t
@@ -1235,8 +1233,8 @@ do_set_bsstype(datalink_id_t linkid, dladm_wlan_bsstype_t *bsstype)
ibsstype = WL_BSS_ANY;
break;
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_BSS_TYPE, &ibsstype,
- sizeof (ibsstype)));
+ return (i_dladm_wlan_param(linkid, &ibsstype, MAC_PROP_WL_BSSTYPE,
+ sizeof (ibsstype), B_TRUE));
}
static dladm_status_t
@@ -1254,8 +1252,8 @@ do_set_authmode(datalink_id_t linkid, dladm_wlan_auth_t *auth)
default:
return (DLADM_STATUS_NOTSUP);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_AUTH_MODE, &auth_mode,
- sizeof (auth_mode)));
+ return (i_dladm_wlan_param(linkid, &auth_mode, MAC_PROP_WL_AUTH_MODE,
+ sizeof (auth_mode), B_TRUE));
}
static dladm_status_t
@@ -1275,8 +1273,8 @@ do_set_encryption(datalink_id_t linkid, dladm_wlan_secmode_t *secmode)
default:
return (DLADM_STATUS_NOTSUP);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_ENCRYPTION, &encryption,
- sizeof (encryption)));
+ return (i_dladm_wlan_param(linkid, &encryption, MAC_PROP_WL_ENCRYPTION,
+ sizeof (encryption), B_TRUE));
}
static dladm_status_t
@@ -1309,8 +1307,8 @@ do_set_key(datalink_id_t linkid, dladm_wlan_key_t *keys,
(void) memcpy(wkp->wl_wep_key, kp->wk_val, kp->wk_len);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_WEP_KEY_TAB, &wepkey_tab,
- sizeof (wepkey_tab)));
+ return (i_dladm_wlan_param(linkid, &wepkey_tab, MAC_PROP_WL_KEY_TAB,
+ sizeof (wepkey_tab), B_TRUE));
}
static dladm_status_t
@@ -1327,8 +1325,8 @@ do_set_essid(datalink_id_t linkid, dladm_wlan_essid_t *essid)
} else {
return (DLADM_STATUS_BADARG);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_ESSID, &iessid,
- sizeof (iessid)));
+ return (i_dladm_wlan_param(linkid, &iessid, MAC_PROP_WL_ESSID,
+ sizeof (iessid), B_TRUE));
}
static dladm_status_t
@@ -1342,8 +1340,8 @@ do_set_channel(datalink_id_t linkid, dladm_wlan_channel_t *channel)
(void) memset(&phy_conf, 0xff, sizeof (phy_conf));
phy_conf.wl_phy_dsss_conf.wl_dsss_channel = *channel;
- return (i_dladm_wlan_set_ioctl(linkid, WL_PHY_CONFIG, &phy_conf,
- sizeof (phy_conf)));
+ return (i_dladm_wlan_param(linkid, &phy_conf, MAC_PROP_WL_PHY_CONFIG,
+ sizeof (phy_conf), B_TRUE));
}
static dladm_status_t
@@ -1351,8 +1349,8 @@ do_set_createibss(datalink_id_t linkid, boolean_t *create_ibss)
{
wl_create_ibss_t cr = (wl_create_ibss_t)(*create_ibss);
- return (i_dladm_wlan_set_ioctl(linkid, WL_CREATE_IBSS,
- &cr, sizeof (cr)));
+ return (i_dladm_wlan_param(linkid, &cr, MAC_PROP_WL_CREATE_IBSS,
+ sizeof (cr), B_TRUE));
}
static void
@@ -1364,15 +1362,17 @@ generate_essid(dladm_wlan_essid_t *essid)
}
static dladm_status_t
-do_get_capability(datalink_id_t linkid, wldp_t *gbuf)
+do_get_capability(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_CAPABILITY));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_CAPABILITY,
+ buflen, B_FALSE));
}
static dladm_status_t
-do_get_wpamode(datalink_id_t linkid, wldp_t *gbuf)
+do_get_wpamode(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_WPA));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_WPA, buflen,
+ B_FALSE));
}
dladm_status_t
@@ -1380,17 +1380,17 @@ dladm_wlan_wpa_get_sr(datalink_id_t linkid, dladm_wlan_ess_t *sr,
uint_t escnt, uint_t *estot)
{
int i, n;
- wldp_t *gbuf;
wl_wpa_ess_t *es;
dladm_status_t status;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
+ es = malloc(WLDP_BUFSIZE);
+ if (es == NULL)
return (DLADM_STATUS_NOMEM);
- status = i_dladm_wlan_get_ioctl(linkid, gbuf, WL_SCANRESULTS);
+ status = i_dladm_wlan_param(linkid, es, MAC_PROP_WL_SCANRESULTS,
+ WLDP_BUFSIZE, B_FALSE);
if (status == DLADM_STATUS_OK) {
- es = (wl_wpa_ess_t *)(gbuf->wldp_buf);
n = (es->count > escnt) ? escnt : es->count;
for (i = 0; i < n; i ++) {
(void) memcpy(sr[i].we_bssid.wb_bytes, es->ess[i].bssid,
@@ -1406,7 +1406,7 @@ dladm_wlan_wpa_get_sr(datalink_id_t linkid, dladm_wlan_ess_t *sr,
*estot = n;
}
- free(gbuf);
+ free(es);
return (status);
}
@@ -1428,7 +1428,8 @@ dladm_wlan_wpa_set_ie(datalink_id_t linkid, uint8_t *wpa_ie, uint_t wpa_ie_len)
ie->wpa_ie_len = wpa_ie_len;
(void) memcpy(ie->wpa_ie, wpa_ie, wpa_ie_len);
- status = i_dladm_wlan_set_ioctl(linkid, WL_SETOPTIE, ie, len);
+ status = i_dladm_wlan_param(linkid, ie, MAC_PROP_WL_SETOPTIE, len,
+ B_TRUE);
free(ie);
return (status);
@@ -1440,8 +1441,8 @@ dladm_wlan_wpa_set_wpa(datalink_id_t linkid, boolean_t flag)
wl_wpa_t wpa;
wpa.wpa_flag = flag;
- return (i_dladm_wlan_set_ioctl(linkid, WL_WPA, &wpa,
- sizeof (wl_wpa_t)));
+ return (i_dladm_wlan_param(linkid, &wpa, MAC_PROP_WL_WPA,
+ sizeof (wpa), B_TRUE));
}
dladm_status_t
@@ -1455,8 +1456,8 @@ dladm_wlan_wpa_del_key(datalink_id_t linkid, uint_t key_idx,
(void) memcpy((char *)wk.idk_macaddr, addr->wb_bytes,
DLADM_WLAN_BSSID_LEN);
- return (i_dladm_wlan_set_ioctl(linkid, WL_DELKEY, &wk,
- sizeof (wl_del_key_t)));
+ return (i_dladm_wlan_param(linkid, &wk, MAC_PROP_WL_DELKEY,
+ sizeof (wk), B_TRUE));
}
dladm_status_t
@@ -1501,7 +1502,8 @@ dladm_wlan_wpa_set_key(datalink_id_t linkid, dladm_wlan_cipher_t cipher,
(void) memcpy(&wk.ik_keyrsc, &seq, 6); /* only use 48-bit of seq */
(void) memcpy(wk.ik_keydata, key, key_len);
- return (i_dladm_wlan_set_ioctl(linkid, WL_KEY, &wk, sizeof (wl_key_t)));
+ return (i_dladm_wlan_param(linkid, &wk, MAC_PROP_WL_KEY,
+ sizeof (wk), B_TRUE));
}
dladm_status_t
@@ -1526,8 +1528,8 @@ dladm_wlan_wpa_set_mlme(datalink_id_t linkid, dladm_wlan_mlme_op_t op,
(void) memcpy(mlme.im_macaddr, bssid->wb_bytes,
DLADM_WLAN_BSSID_LEN);
- return (i_dladm_wlan_set_ioctl(linkid, WL_MLME, &mlme,
- sizeof (wl_mlme_t)));
+ return (i_dladm_wlan_param(linkid, &mlme, MAC_PROP_WL_MLME,
+ sizeof (mlme), B_TRUE));
}
/*
diff --git a/usr/src/lib/libdladm/common/libdlwlan_impl.h b/usr/src/lib/libdladm/common/libdlwlan_impl.h
index 9611b5319b..256876f030 100644
--- a/usr/src/lib/libdladm/common/libdlwlan_impl.h
+++ b/usr/src/lib/libdladm/common/libdlwlan_impl.h
@@ -26,10 +26,9 @@
#ifndef _LIBDLWLAN_IMPL_H
#define _LIBDLWLAN_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <inet/wifi_ioctl.h>
+#include <sys/mac.h>
/*
* Implementation-private data structures, macros, and constants.
@@ -75,12 +74,10 @@ typedef enum {
DLADM_WLAN_PM_FAST
} dladm_wlan_powermode_t;
-extern dladm_status_t i_dladm_wlan_get_ioctl(datalink_id_t, wldp_t *,
- uint_t);
-extern dladm_status_t i_dladm_wlan_set_ioctl(datalink_id_t, uint_t,
- void *, uint_t);
-extern dladm_status_t i_dladm_wlan_ioctl(datalink_id_t, wldp_t *, uint_t,
- size_t, uint_t, size_t);
+extern dladm_status_t i_dladm_wlan_legacy_ioctl(datalink_id_t, wldp_t *,
+ uint_t, size_t, uint_t, size_t);
+extern dladm_status_t i_dladm_wlan_param(datalink_id_t, void *,
+ mac_prop_id_t, size_t, boolean_t);
extern boolean_t i_dladm_wlan_convert_chan(wl_phy_conf_t *, uint32_t *);
#ifdef __cplusplus
diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c
index 2e78907edb..dd43d9331b 100644
--- a/usr/src/lib/libdladm/common/linkprop.c
+++ b/usr/src/lib/libdladm/common/linkprop.c
@@ -48,6 +48,8 @@
#include <sys/param.h>
#include <inttypes.h>
#include <sys/ethernet.h>
+#include <net/wpa.h>
+#include <sys/sysmacros.h>
/*
* The linkprop get() callback.
@@ -98,20 +100,23 @@ typedef dladm_status_t pd_checkf_t(struct prop_desc *pd,
uint_t cnt, val_desc_t *propval,
datalink_media_t);
-typedef struct dladm_public_prop_s {
+typedef struct link_attr_s {
mac_prop_id_t pp_id;
size_t pp_valsize;
char *pp_name;
- char *pp_desc;
-} dladm_public_prop_t;
+} link_attr_t;
-static dld_ioc_macprop_t *i_dladm_buf_alloc(size_t, datalink_id_t, const char *,
- uint_t, dladm_status_t *);
+static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t,
+ const char *, uint_t, dladm_status_t *);
+static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t,
+ mac_prop_id_t, uint_t,
+ dladm_status_t *);
static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **,
uint_t, uint_t);
static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **,
uint_t *, dladm_prop_type_t, uint_t);
-static dladm_public_prop_t *dladm_name2prop(const char *);
+static link_attr_t *dladm_name2prop(const char *);
+static link_attr_t *dladm_id2prop(mac_prop_id_t);
static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t,
dladm_status_t *);
static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod,
@@ -128,6 +133,11 @@ static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate,
static dladm_status_t i_dladm_speed_get(struct prop_desc *, datalink_id_t,
char **, uint_t *, uint_t);
+static dladm_status_t i_dladm_wlan_get_legacy_ioctl(datalink_id_t, void *,
+ uint_t, uint_t);
+static dladm_status_t i_dladm_wlan_set_legacy_ioctl(datalink_id_t, void *,
+ uint_t, uint_t);
+static dladm_status_t i_dladm_macprop(void *, boolean_t);
typedef struct prop_desc {
/*
@@ -193,70 +203,104 @@ typedef struct prop_desc {
#define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1
+/*
+ * Supported link properties enumerated in the prop_table[] array are
+ * computed using the callback functions in that array. To compute the
+ * property value, multiple distinct system calls may be needed (e.g.,
+ * for wifi speed, we need to issue system calls to get desired/supported
+ * rates). The link_attr[] table enumerates the interfaces to the kernel,
+ * and the type/size of the data passed in the user-kernel interface.
+ */
+static link_attr_t link_attr[] = {
+ { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"},
+
+ { MAC_PROP_SPEED, sizeof (uint64_t), "speed"},
+
+ { MAC_PROP_STATUS, sizeof (link_state_t), "state"},
+
+ { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"},
+
+ { MAC_PROP_MTU, sizeof (uint32_t), "mtu"},
+
+ { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"},
+
+ { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"},
+
+ { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"},
+
+ { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"},
+
+ { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"},
+
+ { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"},
+
+ { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"},
+
+ { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"},
+
+ { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"},
+
+ { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"},
+
+ { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"},
+
+ { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"},
+
+ { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"},
+
+ { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"},
+
+ { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"},
-static dladm_public_prop_t dladm_prop[] = {
- { MAC_PROP_DUPLEX, sizeof (link_duplex_t),
- "duplex", "link duplex mode" },
+ { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"},
- { MAC_PROP_SPEED, sizeof (uint64_t),
- "speed", "link speed (bps)" },
+ { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"},
- { MAC_PROP_STATUS, sizeof (link_state_t),
- "state", "link up/down" },
+ { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"},
- { MAC_PROP_AUTONEG, sizeof (uint8_t),
- "adv_autoneg_cap", "Advertised auto-negotiation" },
+ { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"},
- { MAC_PROP_MTU, sizeof (uint32_t),
- "mtu", "current link mtu" },
+ /* wl_rates_t has variable length */
+ { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"},
- { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t),
- "flowctrl", "flowcontrol" },
+ /* wl_rates_t has variable length */
+ { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"},
- { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t),
- "zone", "non-global zones" },
+ { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"},
- { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush),
- "autopush", "autopush modules" },
+ { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"},
- { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t),
- "adv_1000fdx_cap", "Adv 1000 Mbps fdx" },
+ { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"},
- { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t),
- "en_1000fdx_cap", "Enable 1000 Mbps fdx" },
+ { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"},
- { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t),
- "adv_1000hdx_cap", "Adv 1000 Mbps hdx" },
+ { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"},
- { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t),
- "en_1000hdx_cap", "Enable 1000 Mbps hdx" },
+ { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"},
- { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t),
- "adv_100fdx_cap", "Adv 100 Mbps fdx" },
+ /* wl_wpa_ess_t has variable length */
+ { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"},
- { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t),
- "en_100fdx_cap", "Enable 100 Mbps fdx" },
+ { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"},
- { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t),
- "adv_100hdx_cap", "Adv 100 Mbps hdx" },
+ { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"},
- { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t),
- "en_100hdx_cap", "Enable 100 Mbps hdx" },
+ { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"},
- { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t),
- "adv_10fdx_cap", "Adv 10 Mbps fdx" },
+ { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"},
- { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t),
- "en_10fdx_cap", "Enable 10 Mbps fdx" },
+ { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"},
- { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t),
- "adv_10hdx_cap", "Adv 10 Mbps hdx" },
+ /* wl_wpa_ie_t has variable length */
+ { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"},
- { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t),
- "en_10hdx_cap", "Enable 10 Mbps hdx" },
+ { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"},
- { MAC_PROP_PRIVATE, 0,
- "driver-private", "" }
+ { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"},
+
+ { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"},
+
+ { MAC_PROP_PRIVATE, 0, "driver-private"}
};
static val_desc_t link_duplex_vals[] = {
@@ -414,6 +458,12 @@ static prop_desc_t prop_table[] = {
#define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t))
+/*
+ * when retrieving private properties, we pass down a buffer with
+ * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value.
+ */
+#define DLADM_PROP_BUF_CHUNK 1024
+
static dladm_status_t i_dladm_set_linkprop_db(datalink_id_t, const char *,
char **, uint_t);
static dladm_status_t i_dladm_get_linkprop_db(datalink_id_t, const char *,
@@ -1244,6 +1294,8 @@ do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
return (DLADM_STATUS_OK);
}
+#define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET)
+
/* ARGSUSED */
static dladm_status_t
do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid,
@@ -1251,19 +1303,16 @@ do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid,
{
wl_rates_t *wrp;
uint_t i;
- wldp_t *gbuf = NULL;
dladm_status_t status = DLADM_STATUS_OK;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) {
- status = DLADM_STATUS_NOMEM;
- goto done;
- }
+ wrp = malloc(WLDP_BUFSIZE);
+ if (wrp == NULL)
+ return (DLADM_STATUS_NOMEM);
- status = i_dladm_wlan_get_ioctl(linkid, gbuf, id);
+ status = i_dladm_wlan_param(linkid, wrp, id, WLDP_BUFSIZE, B_FALSE);
if (status != DLADM_STATUS_OK)
goto done;
- wrp = (wl_rates_t *)gbuf->wldp_buf;
if (wrp->wl_rates_num > *val_cnt) {
status = DLADM_STATUS_TOOSMALL;
goto done;
@@ -1283,7 +1332,7 @@ do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid,
*val_cnt = wrp->wl_rates_num;
done:
- free(gbuf);
+ free(wrp);
return (status);
}
@@ -1296,7 +1345,7 @@ do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid,
val_cnt, flags));
return (do_get_rate_common(pd, linkid, prop_val, val_cnt,
- WL_DESIRED_RATES));
+ MAC_PROP_WL_DESIRED_RATES));
}
/* ARGSUSED */
@@ -1314,7 +1363,7 @@ do_get_rate_mod(struct prop_desc *pd, datalink_id_t linkid,
case DL_WIFI:
return (do_get_rate_common(pd, linkid, prop_val, val_cnt,
- WL_SUPPORTED_RATES));
+ MAC_PROP_WL_SUPPORTED_RATES));
default:
return (DLADM_STATUS_BADARG);
}
@@ -1325,26 +1374,24 @@ do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates)
{
int i;
uint_t len;
- wldp_t *gbuf;
wl_rates_t *wrp;
dladm_status_t status = DLADM_STATUS_OK;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
+ wrp = malloc(WLDP_BUFSIZE);
+ if (wrp == NULL)
return (DLADM_STATUS_NOMEM);
- (void) memset(gbuf, 0, MAX_BUF_LEN);
-
- wrp = (wl_rates_t *)gbuf->wldp_buf;
+ bzero(wrp, WLDP_BUFSIZE);
for (i = 0; i < rates->wr_cnt; i++)
wrp->wl_rates_rates[i] = rates->wr_rates[i];
wrp->wl_rates_num = rates->wr_cnt;
len = offsetof(wl_rates_t, wl_rates_rates) +
(rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET;
- status = i_dladm_wlan_ioctl(linkid, gbuf, WL_DESIRED_RATES, len,
- WLAN_SET_PARAM, len);
+ status = i_dladm_wlan_param(linkid, wrp, MAC_PROP_WL_DESIRED_RATES,
+ len, B_TRUE);
- free(gbuf);
+ free(wrp);
return (status);
}
@@ -1420,9 +1467,10 @@ done:
}
static dladm_status_t
-do_get_phyconf(datalink_id_t linkid, wldp_t *gbuf)
+do_get_phyconf(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_PHY_CONFIG));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG,
+ buflen, B_FALSE));
}
/* ARGSUSED */
@@ -1431,17 +1479,16 @@ do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
uint32_t channel;
- wldp_t *gbuf;
+ char buf[WLDP_BUFSIZE];
dladm_status_t status = DLADM_STATUS_OK;
+ wl_phy_conf_t wl_phy_conf;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
- return (DLADM_STATUS_NOMEM);
-
- if ((status = do_get_phyconf(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_phyconf(linkid, buf, sizeof (buf)))
+ != DLADM_STATUS_OK)
goto done;
- if (!i_dladm_wlan_convert_chan((wl_phy_conf_t *)gbuf->wldp_buf,
- &channel)) {
+ (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf));
+ if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) {
status = DLADM_STATUS_NOTFOUND;
goto done;
}
@@ -1450,14 +1497,14 @@ do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid,
*val_cnt = 1;
done:
- free(gbuf);
return (status);
}
static dladm_status_t
-do_get_powermode(datalink_id_t linkid, wldp_t *gbuf)
+do_get_powermode(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_POWER_MODE));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_POWER_MODE,
+ buflen, B_FALSE));
}
/* ARGSUSED */
@@ -1465,19 +1512,17 @@ static dladm_status_t
do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
- wl_ps_mode_t *mode;
+ wl_ps_mode_t mode;
const char *s;
- wldp_t *gbuf;
+ char buf[WLDP_BUFSIZE];
dladm_status_t status = DLADM_STATUS_OK;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
- return (DLADM_STATUS_NOMEM);
-
- if ((status = do_get_powermode(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_powermode(linkid, buf, sizeof (buf)))
+ != DLADM_STATUS_OK)
goto done;
- mode = (wl_ps_mode_t *)(gbuf->wldp_buf);
- switch (mode->wl_ps_mode) {
+ (void) memcpy(&mode, buf, sizeof (mode));
+ switch (mode.wl_ps_mode) {
case WL_PM_AM:
s = "off";
break;
@@ -1495,7 +1540,6 @@ do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid,
*val_cnt = 1;
done:
- free(gbuf);
return (status);
}
@@ -1519,8 +1563,8 @@ do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm)
default:
return (DLADM_STATUS_NOTSUP);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_POWER_MODE, &ps_mode,
- sizeof (ps_mode)));
+ return (i_dladm_wlan_param(linkid, &ps_mode, MAC_PROP_WL_POWER_MODE,
+ sizeof (ps_mode), B_TRUE));
}
/* ARGSUSED */
@@ -1540,9 +1584,10 @@ do_set_powermode_prop(prop_desc_t *pd, datalink_id_t linkid,
}
static dladm_status_t
-do_get_radio(datalink_id_t linkid, wldp_t *gbuf)
+do_get_radio(datalink_id_t linkid, void *buf, int buflen)
{
- return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_RADIO));
+ return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RADIO, buflen,
+ B_FALSE));
}
/* ARGSUSED */
@@ -1552,16 +1597,14 @@ do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid,
{
wl_radio_t radio;
const char *s;
- wldp_t *gbuf;
+ char buf[WLDP_BUFSIZE];
dladm_status_t status = DLADM_STATUS_OK;
- if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
- return (DLADM_STATUS_NOMEM);
-
- if ((status = do_get_radio(linkid, gbuf)) != DLADM_STATUS_OK)
+ if ((status = do_get_radio(linkid, buf, sizeof (buf)))
+ != DLADM_STATUS_OK)
goto done;
- radio = *(wl_radio_t *)(gbuf->wldp_buf);
+ (void) memcpy(&radio, buf, sizeof (radio));
switch (radio) {
case B_TRUE:
s = "on";
@@ -1577,7 +1620,6 @@ do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid,
*val_cnt = 1;
done:
- free(gbuf);
return (status);
}
@@ -1596,7 +1638,8 @@ do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio)
default:
return (DLADM_STATUS_NOTSUP);
}
- return (i_dladm_wlan_set_ioctl(linkid, WL_RADIO, &r, sizeof (r)));
+ return (i_dladm_wlan_param(linkid, &r, MAC_PROP_WL_RADIO,
+ sizeof (r), B_TRUE));
}
/* ARGSUSED */
@@ -1688,32 +1731,39 @@ done:
return (status);
}
-static dladm_public_prop_t *
+static link_attr_t *
dladm_name2prop(const char *prop_name)
{
- dladm_public_prop_t *p;
+ link_attr_t *p;
- for (p = dladm_prop; p->pp_id != MAC_PROP_PRIVATE; p++) {
+ for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) {
if (strcmp(p->pp_name, prop_name) == 0)
break;
}
return (p);
}
+static link_attr_t *
+dladm_id2prop(mac_prop_id_t propid)
+{
+ link_attr_t *p;
+
+ for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) {
+ if (p->pp_id == propid)
+ break;
+ }
+ return (p);
+}
static dld_ioc_macprop_t *
-i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name,
- uint_t flags, dladm_status_t *status)
+i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid,
+ const char *prop_name, mac_prop_id_t propid, uint_t flags,
+ dladm_status_t *status)
{
int dsize;
dld_ioc_macprop_t *dip;
- dladm_public_prop_t *p;
*status = DLADM_STATUS_OK;
- p = dladm_name2prop(prop_name);
- if (p->pp_id != MAC_PROP_PRIVATE)
- valsize = p->pp_valsize;
-
dsize = MAC_PROP_BUFSIZE(valsize);
dip = malloc(dsize);
if (dip == NULL) {
@@ -1725,25 +1775,48 @@ i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name,
(void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name));
dip->pr_version = MAC_PROP_VERSION;
dip->pr_linkid = linkid;
- dip->pr_num = p->pp_id;
+ dip->pr_num = propid;
dip->pr_flags = flags;
return (dip);
}
+static dld_ioc_macprop_t *
+i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid,
+ const char *prop_name, uint_t flags, dladm_status_t *status)
+{
+ link_attr_t *p;
+
+ p = dladm_name2prop(prop_name);
+ valsize = MAX(p->pp_valsize, valsize);
+ return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id,
+ flags, status));
+}
+
+static dld_ioc_macprop_t *
+i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid,
+ mac_prop_id_t propid, uint_t flags, dladm_status_t *status)
+{
+ link_attr_t *p;
+
+ p = dladm_id2prop(propid);
+ valsize = MAX(p->pp_valsize, valsize);
+ return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid,
+ flags, status));
+}
+
/* ARGSUSED */
static dladm_status_t
i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media)
{
dld_ioc_macprop_t *dip;
- int fd;
dladm_status_t status = DLADM_STATUS_OK;
uint8_t u8;
uint16_t u16;
uint32_t u32;
void *val;
- dip = i_dladm_buf_alloc(0, linkid, pd->pd_name, 0, &status);
+ dip = i_dladm_buf_alloc_by_name(0, linkid, pd->pd_name, 0, &status);
if (dip == NULL)
return (status);
@@ -1778,16 +1851,27 @@ i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
else
dip->pr_valsize = 0;
+ status = i_dladm_macprop(dip, B_TRUE);
+
+done:
+ free(dip);
+ return (status);
+}
+
+dladm_status_t
+i_dladm_macprop(void *dip, boolean_t set)
+{
+ int fd;
+ dladm_status_t status = DLADM_STATUS_OK;
+
if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
status = dladm_errno2status(errno);
- goto done;
+ return (status);
}
- if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0)
+ if (ioctl(fd, (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip))
status = dladm_errno2status(errno);
(void) close(fd);
-done:
- free(dip);
return (status);
}
@@ -1795,24 +1879,13 @@ static dld_ioc_macprop_t *
i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags,
dladm_status_t *status)
{
- int fd;
dld_ioc_macprop_t *dip = NULL;
- *status = DLADM_STATUS_OK;
-
- dip = i_dladm_buf_alloc(0, linkid, prop_name, flags, status);
+ dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status);
if (dip == NULL)
return (NULL);
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
- *status = dladm_errno2status(errno);
- goto done;
- }
- if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0)
- *status = dladm_errno2status(errno);
-
- (void) close(fd);
-done:
+ *status = i_dladm_macprop(dip, B_FALSE);
if (*status != DLADM_STATUS_OK) {
free(dip);
return (NULL);
@@ -1999,11 +2072,11 @@ static dladm_status_t
i_dladm_set_prop(datalink_id_t linkid, const char *prop_name,
char **prop_val, uint_t val_cnt, uint_t flags)
{
- int fd, i, slen;
+ int i, slen;
int bufsize = 0;
dld_ioc_macprop_t *dip = NULL;
uchar_t *dp;
- dladm_public_prop_t *p;
+ link_attr_t *p;
dladm_status_t status = DLADM_STATUS_OK;
if ((prop_name == NULL && prop_val != NULL) ||
@@ -2025,25 +2098,19 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name,
/*
* getting default value. so use more buffer space.
*/
- bufsize += 1024;
+ bufsize += DLADM_PROP_BUF_CHUNK;
}
- dip = i_dladm_buf_alloc(bufsize + 1, linkid, prop_name,
+ dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name,
(prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status);
if (dip == NULL)
return (status);
dp = (uchar_t *)dip->pr_val;
slen = 0;
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
- status = dladm_errno2status(errno);
- goto done;
- }
+
if (prop_val == NULL) {
- if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) {
- status = dladm_errno2status(errno);
- goto done;
- }
+ status = i_dladm_macprop(dip, B_FALSE);
} else {
for (i = 0; i < val_cnt; i++) {
int plen = 0;
@@ -2058,13 +2125,9 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name,
dp[slen++] = ',';
dp += (plen + 1);
}
+ status = i_dladm_macprop(dip, B_TRUE);
}
- if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0)
- status = dladm_errno2status(errno);
-done:
- if (fd > 0)
- (void) close(fd);
free(dip);
return (status);
}
@@ -2073,10 +2136,9 @@ static dladm_status_t
i_dladm_get_prop(datalink_id_t linkid, const char *prop_name,
char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags)
{
- int fd;
- dladm_status_t status = DLADM_STATUS_OK;
+ dladm_status_t status = DLADM_STATUS_OK;
dld_ioc_macprop_t *dip = NULL;
- dladm_public_prop_t *p;
+ link_attr_t *p;
char tmp = '\0';
if ((prop_name == NULL && prop_val != NULL) ||
@@ -2096,23 +2158,15 @@ i_dladm_get_prop(datalink_id_t linkid, const char *prop_name,
/*
* private properties: all parsing is done in the kernel.
*/
- dip = i_dladm_buf_alloc(1024, linkid, prop_name, dld_flags, &status);
+ dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name,
+ dld_flags, &status);
if (dip == NULL)
return (status);
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
- free(dip);
- return (DLADM_STATUS_BADARG);
- }
-
- if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) {
- status = dladm_errno2status(errno);
- } else {
+ if ((status = i_dladm_macprop(dip, B_FALSE)) == DLADM_STATUS_OK) {
(void) strncpy(*prop_val, dip->pr_val, DLADM_PROP_VAL_MAX);
*val_cnt = 1;
}
-
- (void) close(fd);
free(dip);
return (status);
}
@@ -2162,3 +2216,146 @@ i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid,
free(buf);
return (status);
}
+
+int
+macprop_to_wifi(mac_prop_id_t wl_prop)
+{
+ switch (wl_prop) {
+ case MAC_PROP_WL_ESSID:
+ return (WL_ESSID);
+ case MAC_PROP_WL_BSSID:
+ return (WL_BSSID);
+ case MAC_PROP_WL_BSSTYPE:
+ return (WL_BSS_TYPE);
+ case MAC_PROP_WL_LINKSTATUS:
+ return (WL_LINKSTATUS);
+ case MAC_PROP_WL_DESIRED_RATES:
+ return (WL_DESIRED_RATES);
+ case MAC_PROP_WL_SUPPORTED_RATES:
+ return (WL_SUPPORTED_RATES);
+ case MAC_PROP_WL_AUTH_MODE:
+ return (WL_AUTH_MODE);
+ case MAC_PROP_WL_ENCRYPTION:
+ return (WL_ENCRYPTION);
+ case MAC_PROP_WL_RSSI:
+ return (WL_RSSI);
+ case MAC_PROP_WL_PHY_CONFIG:
+ return (WL_PHY_CONFIG);
+ case MAC_PROP_WL_CAPABILITY:
+ return (WL_CAPABILITY);
+ case MAC_PROP_WL_WPA:
+ return (WL_WPA);
+ case MAC_PROP_WL_SCANRESULTS:
+ return (WL_SCANRESULTS);
+ case MAC_PROP_WL_POWER_MODE:
+ return (WL_POWER_MODE);
+ case MAC_PROP_WL_RADIO:
+ return (WL_RADIO);
+ case MAC_PROP_WL_ESS_LIST:
+ return (WL_ESS_LIST);
+ case MAC_PROP_WL_KEY_TAB:
+ return (WL_WEP_KEY_TAB);
+ case MAC_PROP_WL_CREATE_IBSS:
+ return (WL_CREATE_IBSS);
+ case MAC_PROP_WL_SETOPTIE:
+ return (WL_SETOPTIE);
+ case MAC_PROP_WL_DELKEY:
+ return (WL_DELKEY);
+ case MAC_PROP_WL_KEY:
+ return (WL_KEY);
+ case MAC_PROP_WL_MLME:
+ return (WL_MLME);
+ default:
+ return (-1);
+ }
+}
+
+dladm_status_t
+i_dladm_wlan_param(datalink_id_t linkid, void *buf, mac_prop_id_t cmd,
+ size_t len, boolean_t set)
+{
+ uint32_t flags;
+ dladm_status_t status;
+ uint32_t media;
+ dld_ioc_macprop_t *dip;
+ void *dp;
+
+ if ((status = dladm_datalink_id2info(linkid, &flags, NULL, &media,
+ NULL, 0)) != DLADM_STATUS_OK) {
+ return (status);
+ }
+
+ if (media != DL_WIFI)
+ return (DLADM_STATUS_BADARG);
+
+ if (!(flags & DLADM_OPT_ACTIVE))
+ return (DLADM_STATUS_TEMPONLY);
+
+ if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET))
+ len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1;
+
+ dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status);
+ if (dip == NULL)
+ return (DLADM_STATUS_NOMEM);
+
+ dp = (uchar_t *)dip->pr_val;
+ if (set)
+ (void) memcpy(dp, buf, len);
+
+ status = i_dladm_macprop(dip, set);
+ if (status == DLADM_STATUS_NOTSUP) {
+ if (set) {
+ status = i_dladm_wlan_set_legacy_ioctl(linkid,
+ buf, len, macprop_to_wifi(cmd));
+ } else {
+ status = i_dladm_wlan_get_legacy_ioctl(linkid,
+ buf, len, macprop_to_wifi(cmd));
+ }
+ } else if (status == DLADM_STATUS_OK) {
+ if (!set)
+ (void) memcpy(buf, dp, len);
+ }
+
+ free(dip);
+ return (status);
+}
+
+static dladm_status_t
+i_dladm_wlan_get_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen,
+ uint_t id)
+{
+ wldp_t *gbuf;
+ dladm_status_t status;
+
+ if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
+ return (DLADM_STATUS_NOMEM);
+
+ (void) memset(gbuf, 0, MAX_BUF_LEN);
+ status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, MAX_BUF_LEN,
+ WLAN_GET_PARAM, sizeof (wldp_t));
+ if (status == DLADM_STATUS_OK)
+ (void) memcpy(buf, gbuf->wldp_buf, buflen);
+
+ free(gbuf);
+ return (status);
+}
+
+static dladm_status_t
+i_dladm_wlan_set_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen,
+ uint_t id)
+{
+ wldp_t *gbuf;
+ dladm_status_t status = DLADM_STATUS_OK;
+
+ if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
+ return (DLADM_STATUS_NOMEM);
+
+ (void) memset(gbuf, 0, MAX_BUF_LEN);
+ (void) memcpy(gbuf->wldp_buf, buf, buflen);
+ buflen += WIFI_BUF_OFFSET;
+ status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, buflen,
+ WLAN_SET_PARAM, buflen);
+
+ free(gbuf);
+ return (status);
+}
diff --git a/usr/src/uts/common/io/ath/ath_main.c b/usr/src/uts/common/io/ath/ath_main.c
index e9a26e3c1d..034c719c5d 100644
--- a/usr/src/uts/common/io/ath/ath_main.c
+++ b/usr/src/uts/common/io/ath/ath_main.c
@@ -36,6 +36,7 @@
*
*/
+
/*
* Driver for the Atheros Wireless LAN controller.
*
@@ -218,8 +219,13 @@ static int ath_m_multicst(void *, boolean_t, const uint8_t *);
static int ath_m_unicst(void *, const uint8_t *);
static mblk_t *ath_m_tx(void *, mblk_t *);
static void ath_m_ioctl(void *, queue_t *, mblk_t *);
+static int ath_m_setprop(void *, const char *, mac_prop_id_t,
+ uint_t, const void *);
+static int ath_m_getprop(void *, const char *, mac_prop_id_t,
+ uint_t, uint_t, void *);
+
static mac_callbacks_t ath_m_callbacks = {
- MC_IOCTL,
+ MC_IOCTL | MC_SETPROP | MC_GETPROP,
ath_m_stat,
ath_m_start,
ath_m_stop,
@@ -229,7 +235,11 @@ static mac_callbacks_t ath_m_callbacks = {
ath_m_tx,
NULL, /* mc_resources; */
ath_m_ioctl,
- NULL /* mc_getcapab */
+ NULL, /* mc_getcapab */
+ NULL,
+ NULL,
+ ath_m_setprop,
+ ath_m_getprop
};
/*
@@ -1738,6 +1748,49 @@ ath_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
return (0);
}
+/*
+ * callback functions for /get/set properties
+ */
+static int
+ath_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t wldp_length, const void *wldp_buf)
+{
+ ath_t *asc = arg;
+ int err;
+
+ err = ieee80211_setprop(&asc->asc_isc, pr_name, wldp_pr_num,
+ wldp_length, wldp_buf);
+
+ ATH_LOCK(asc);
+
+ if (err == ENETRESET) {
+ if (ATH_IS_RUNNING(asc)) {
+ ATH_UNLOCK(asc);
+ (void) ath_m_start(asc);
+ (void) ieee80211_new_state(&asc->asc_isc,
+ IEEE80211_S_SCAN, -1);
+ ATH_LOCK(asc);
+ }
+ err = 0;
+ }
+
+ ATH_UNLOCK(asc);
+
+ return (err);
+}
+static int
+ath_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t pr_flags, uint_t wldp_length, void *wldp_buf)
+{
+ ath_t *asc = arg;
+ int err = 0;
+
+ err = ieee80211_getprop(&asc->asc_isc, pr_name, wldp_pr_num,
+ pr_flags, wldp_length, wldp_buf);
+
+ return (err);
+}
+
static void
ath_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
{
diff --git a/usr/src/uts/common/io/iwk/iwk2.c b/usr/src/uts/common/io/iwk/iwk2.c
index 0ccb805a4a..fe129e5d15 100644
--- a/usr/src/uts/common/io/iwk/iwk2.c
+++ b/usr/src/uts/common/io/iwk/iwk2.c
@@ -326,7 +326,11 @@ static int iwk_m_multicst(void *arg, boolean_t add, const uint8_t *m);
static int iwk_m_promisc(void *arg, boolean_t on);
static mblk_t *iwk_m_tx(void *arg, mblk_t *mp);
static void iwk_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
-
+static int iwk_m_setprop(void *arg, const char *pr_name,
+ mac_prop_id_t wldp_pr_name, uint_t wldp_length, const void *wldp_buf);
+static int iwk_m_getprop(void *arg, const char *pr_name,
+ mac_prop_id_t wldp_pr_name, uint_t pr_flags, uint_t wldp_length,
+ void *wldp_buf);
static void iwk_destroy_locks(iwk_sc_t *sc);
static int iwk_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
static void iwk_thread(iwk_sc_t *sc);
@@ -410,7 +414,7 @@ _info(struct modinfo *mip)
* Mac Call Back entries
*/
mac_callbacks_t iwk_m_callbacks = {
- MC_IOCTL,
+ MC_IOCTL | MC_SETPROP | MC_GETPROP,
iwk_m_stat,
iwk_m_start,
iwk_m_stop,
@@ -419,7 +423,12 @@ mac_callbacks_t iwk_m_callbacks = {
iwk_m_unicst,
iwk_m_tx,
NULL,
- iwk_m_ioctl
+ iwk_m_ioctl,
+ NULL,
+ NULL,
+ NULL,
+ iwk_m_setprop,
+ iwk_m_getprop
};
#ifdef DEBUG
@@ -2651,6 +2660,44 @@ iwk_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
}
}
+/*
+ * callback functions for set/get properties
+ */
+static int
+iwk_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t pr_flags, uint_t wldp_length, void *wldp_buf)
+{
+ int err = 0;
+ iwk_sc_t *sc = (iwk_sc_t *)arg;
+
+ err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
+ pr_flags, wldp_length, wldp_buf);
+
+ return (err);
+}
+static int
+iwk_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t wldp_length, const void *wldp_buf)
+{
+ int err;
+ iwk_sc_t *sc = (iwk_sc_t *)arg;
+ ieee80211com_t *ic = &sc->sc_ic;
+
+ err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length,
+ wldp_buf);
+
+ if (err == ENETRESET) {
+ if (ic->ic_des_esslen) {
+ (void) ieee80211_new_state(ic,
+ IEEE80211_S_SCAN, -1);
+ }
+
+ err = 0;
+ }
+
+ return (err);
+}
+
/*ARGSUSED*/
static int
iwk_m_stat(void *arg, uint_t stat, uint64_t *val)
diff --git a/usr/src/uts/common/io/net80211/net80211_impl.h b/usr/src/uts/common/io/net80211/net80211_impl.h
index 823f0e2365..85e5fe37d4 100644
--- a/usr/src/uts/common/io/net80211/net80211_impl.h
+++ b/usr/src/uts/common/io/net80211/net80211_impl.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,8 +35,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef _SYS_NET80211_IMPL_H
#define _SYS_NET80211_IMPL_H
@@ -186,6 +184,7 @@ extern "C" {
#define IEEE80211_MAXRSSI 127
/* Debug Flags */
+#define IEEE80211_MSG_BRUSSELS 0x80000000 /* BRUSSELS */
#define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */
#define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalant */
#define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */
diff --git a/usr/src/uts/common/io/net80211/net80211_ioctl.c b/usr/src/uts/common/io/net80211/net80211_ioctl.c
index b6d515bd36..95ed7ae672 100644
--- a/usr/src/uts/common/io/net80211/net80211_ioctl.c
+++ b/usr/src/uts/common/io/net80211/net80211_ioctl.c
@@ -31,6 +31,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
@@ -44,6 +45,34 @@
#include <inet/wifi_ioctl.h>
#include "net80211_impl.h"
+static int wl_set_essid(struct ieee80211com *, const void *);
+static void wl_get_essid(struct ieee80211com *, void *);
+static int wl_set_bssid(struct ieee80211com *, const void *);
+static void wl_get_bssid(struct ieee80211com *, void *);
+static int wl_set_bsstype(struct ieee80211com *, const void *);
+static void wl_get_bsstype(struct ieee80211com *, void *);
+static void wl_get_linkstatus(struct ieee80211com *, void *);
+static int wl_set_desrates(struct ieee80211com *, const void *);
+static void wl_get_desrates(struct ieee80211com *, void *);
+static int wl_set_authmode(struct ieee80211com *, const void *);
+static void wl_get_authmode(struct ieee80211com *, void *);
+static int wl_set_encrypt(struct ieee80211com *, const void *);
+static void wl_get_encrypt(struct ieee80211com *, void *);
+static void wl_get_rssi(struct ieee80211com *, void *);
+static int wl_set_phy(struct ieee80211com *, const void *);
+static int wl_get_phy(struct ieee80211com *, void *);
+static void wl_get_capability(struct ieee80211com *, void *);
+static int wl_set_wpa(struct ieee80211com *, const void *);
+static void wl_get_wpa(struct ieee80211com *, void *);
+static void wl_get_scanresults(struct ieee80211com *, void *);
+static void wl_get_esslist(struct ieee80211com *, void *);
+static int wl_set_wepkey(struct ieee80211com *, const void *);
+static int wl_set_optie(struct ieee80211com *, const void *);
+static int wl_set_delkey(struct ieee80211com *, const void *);
+static int wl_set_mlme(struct ieee80211com *, const void *);
+static int wl_set_wpakey(struct ieee80211com *, const void *);
+static void wl_get_suprates(struct ieee80211com *, void *);
+
static size_t
wifi_strnlen(const char *s, size_t n)
{
@@ -105,7 +134,6 @@ wifi_cfg_essid(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wl_essid_t *iw_essid = (wl_essid_t *)inp->wldp_buf;
wl_essid_t *ow_essid;
- char *essid;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, sizeof (wl_essid_t))) == NULL)
@@ -115,35 +143,10 @@ wifi_cfg_essid(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- essid = (char *)ic->ic_des_essid;
- if (essid[0] == '\0')
- essid = (char *)ic->ic_bss->in_essid;
- ow_essid->wl_essid_length = wifi_strnlen((const char *)essid,
- IEEE80211_NWID_LEN);
- bcopy(essid, ow_essid->wl_essid_essid,
- ow_essid->wl_essid_length);
+ wl_get_essid(ic, ow_essid);
break;
case WLAN_SET_PARAM:
- if (iw_essid->wl_essid_length > IEEE80211_NWID_LEN) {
- ieee80211_err("wifi_cfg_essid: "
- "essid too long, %u, max %u\n",
- iw_essid->wl_essid_length, IEEE80211_NWID_LEN);
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- }
- essid = iw_essid->wl_essid_essid;
- essid[IEEE80211_NWID_LEN] = 0;
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_essid: "
- "set essid=%s length=%d\n",
- essid, iw_essid->wl_essid_length);
-
- ic->ic_des_esslen = iw_essid->wl_essid_length;
- if (ic->ic_des_esslen != 0)
- bcopy(essid, ic->ic_des_essid, ic->ic_des_esslen);
- if (ic->ic_des_esslen < IEEE80211_NWID_LEN)
- ic->ic_des_essid[ic->ic_des_esslen] = 0;
- err = ENETRESET;
+ err = wl_set_essid(ic, iw_essid);
break;
default:
ieee80211_err("wifi_cfg_essid: unknown command %x\n", cmd);
@@ -163,7 +166,6 @@ wifi_cfg_bssid(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
mblk_t *omp;
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wldp_t *outp;
- uint8_t *bssid;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, sizeof (wl_bssid_t))) == NULL)
@@ -172,19 +174,13 @@ wifi_cfg_bssid(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- if (ic->ic_flags & IEEE80211_F_DESBSSID)
- bssid = ic->ic_des_bssid;
- else
- bssid = ic->ic_bss->in_bssid;
- bcopy(bssid, outp->wldp_buf, sizeof (wl_bssid_t));
+ wl_get_bssid(ic, outp->wldp_buf);
break;
case WLAN_SET_PARAM:
+ err = wl_set_bssid(ic, inp->wldp_buf);
ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_bssid: "
"set bssid=%s\n",
ieee80211_macaddr_sprintf(inp->wldp_buf));
- bcopy(inp->wldp_buf, ic->ic_des_bssid, sizeof (wl_bssid_t));
- ic->ic_flags |= IEEE80211_F_DESBSSID;
- err = ENETRESET;
break;
default:
ieee80211_err("wifi_cfg_bssid: unknown command %x\n", cmd);
@@ -263,7 +259,6 @@ wifi_cfg_phy(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wl_phy_conf_t *iw_phy = (wl_phy_conf_t *)inp->wldp_buf;
wl_phy_conf_t *ow_phy;
- struct ieee80211_channel *ch = ic->ic_curchan;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, sizeof (wl_phy_conf_t))) == NULL)
@@ -272,86 +267,13 @@ wifi_cfg_phy(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
ow_phy = (wl_phy_conf_t *)outp->wldp_buf;
switch (cmd) {
- case WLAN_GET_PARAM: {
- /* get current physical (FH, DS, ERP) parameters */
- if (IEEE80211_IS_CHAN_A(ch) || IEEE80211_IS_CHAN_T(ch)) {
- wl_ofdm_t *ofdm = (wl_ofdm_t *)ow_phy;
-
- ofdm->wl_ofdm_subtype = WL_OFDM;
- ofdm->wl_ofdm_frequency = ch->ich_freq;
- } else {
- switch (ic->ic_phytype) {
- case IEEE80211_T_FH: {
- wl_fhss_t *fhss = (wl_fhss_t *)ow_phy;
-
- fhss->wl_fhss_subtype = WL_FHSS;
- fhss->wl_fhss_channel =
- ieee80211_chan2ieee(ic, ch);
- break;
- }
- case IEEE80211_T_DS: {
- wl_dsss_t *dsss = (wl_dsss_t *)ow_phy;
-
- dsss->wl_dsss_subtype = WL_DSSS;
- dsss->wl_dsss_channel =
- ieee80211_chan2ieee(ic, ch);
- break;
- }
- case IEEE80211_T_OFDM: {
- wl_erp_t *erp = (wl_erp_t *)ow_phy;
-
- erp->wl_erp_subtype = WL_ERP;
- erp->wl_erp_channel =
- ieee80211_chan2ieee(ic, ch);
- break;
- }
- default:
- ieee80211_err("wifi_cfg_phy: "
- "unknown phy type, %x\n", ic->ic_phytype);
- outp->wldp_result = WL_HW_ERROR;
- err = EIO;
- break;
- } /* switch (ic->ic_phytype) */
- }
+ case WLAN_GET_PARAM:
+ err = wl_get_phy(ic, ow_phy);
break;
- }
-
- case WLAN_SET_PARAM: {
- wl_dsss_t *dsss = (wl_dsss_t *)iw_phy;
- int16_t ch = dsss->wl_dsss_channel;
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_phy: "
- "set channel=%d\n", ch);
- if (ch == 0 || ch == (int16_t)IEEE80211_CHAN_ANY) {
- ic->ic_des_chan = IEEE80211_CHAN_ANYC;
- } else if ((uint_t)ch > IEEE80211_CHAN_MAX ||
- ieee80211_isclr(ic->ic_chan_active, ch)) {
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- } else {
- ic->ic_des_chan = ic->ic_ibss_chan =
- &ic->ic_sup_channels[ch];
- }
- switch (ic->ic_state) {
- case IEEE80211_S_INIT:
- case IEEE80211_S_SCAN:
- err = ENETRESET;
- break;
- default:
- /*
- * If the desired channel has changed (to something
- * other than any) and we're not already scanning,
- * then kick the state machine.
- */
- if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
- ic->ic_bss->in_chan != ic->ic_des_chan &&
- (ic->ic_flags & IEEE80211_F_SCAN) == 0)
- err = ENETRESET;
- break;
- }
+ case WLAN_SET_PARAM:
+ err = wl_set_phy(ic, iw_phy);
break;
- }
default:
ieee80211_err("wifi_cfg_phy: unknown command %x\n", cmd);
@@ -372,9 +294,6 @@ wifi_cfg_wepkey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wldp_t *outp;
wl_wep_key_t *iw_wepkey = (wl_wep_key_t *)inp->wldp_buf;
- struct ieee80211_key *k;
- uint16_t i;
- uint32_t klen;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, 0)) == NULL)
@@ -396,50 +315,7 @@ wifi_cfg_wepkey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
break;
}
- /* set all valid keys */
- for (i = 0; i < MAX_NWEPKEYS; i++) {
- if (iw_wepkey[i].wl_wep_operation != WL_ADD)
- continue;
- klen = iw_wepkey[i].wl_wep_length;
- if (klen > IEEE80211_KEYBUF_SIZE) {
- ieee80211_err("wifi_cfg_wepkey: "
- "invalid wepkey length, %u\n", klen);
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- continue; /* continue to set other keys */
- }
- if (klen == 0)
- continue;
-
- /*
- * Set key contents. Only WEP is supported
- */
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_wepkey: "
- "set key %u, len=%u\n", i, klen);
- k = &ic->ic_nw_keys[i];
- if (ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_WEP,
- IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k) == 0) {
- ieee80211_err("wifi_cfg_wepkey: "
- "abort, create key failed. id=%u\n", i);
- outp->wldp_result = WL_HW_ERROR;
- err = EIO;
- continue;
- }
- k->wk_keyix = i;
- k->wk_keylen = (uint8_t)klen;
- k->wk_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
- bzero(k->wk_key, IEEE80211_KEYBUF_SIZE);
- bcopy(iw_wepkey[i].wl_wep_key, k->wk_key, klen);
- if (ieee80211_crypto_setkey(ic, k, ic->ic_macaddr)
- == 0) {
- ieee80211_err("wifi_cfg_wepkey: "
- "set key failed len=%u\n", klen);
- outp->wldp_result = WL_HW_ERROR;
- err = EIO;
- }
- }
- if (err == 0)
- err = ENETRESET;
+ err = wl_set_wepkey(ic, iw_wepkey);
break;
default:
ieee80211_err("wifi_cfg_wepkey: unknown command %x\n", cmd);
@@ -515,27 +391,10 @@ wifi_cfg_authmode(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- *ow_auth = ic->ic_bss->in_authmode;
+ wl_get_authmode(ic, ow_auth);
break;
case WLAN_SET_PARAM:
- if (*iw_auth == ic->ic_bss->in_authmode)
- break;
-
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_authmode: "
- "set authmode=%u\n", *iw_auth);
- switch (*iw_auth) {
- case WL_OPENSYSTEM:
- case WL_SHAREDKEY:
- ic->ic_bss->in_authmode = *iw_auth;
- err = ENETRESET;
- break;
- default:
- ieee80211_err("wifi_cfg_authmode: "
- "unknown authmode %u\n", *iw_auth);
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- }
+ err = wl_set_authmode(ic, iw_auth);
break;
default:
ieee80211_err("wifi_cfg_authmode: unknown command %x\n", cmd);
@@ -557,7 +416,6 @@ wifi_cfg_encrypt(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wl_encryption_t *iw_encryp = (wl_encryption_t *)inp->wldp_buf;
wl_encryption_t *ow_encryp;
- uint32_t flags;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, sizeof (wl_encryption_t))) == NULL)
@@ -567,23 +425,10 @@ wifi_cfg_encrypt(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- *ow_encryp = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
- if (ic->ic_flags & IEEE80211_F_WPA)
- *ow_encryp = WL_ENC_WPA;
+ wl_get_encrypt(ic, ow_encryp);
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_encrypt: "
- "set encryption=%u\n", *iw_encryp);
- flags = ic->ic_flags;
- if (*iw_encryp == WL_NOENCRYPTION)
- flags &= ~IEEE80211_F_PRIVACY;
- else
- flags |= IEEE80211_F_PRIVACY;
-
- if (ic->ic_flags != flags) {
- ic->ic_flags = flags;
- err = ENETRESET;
- }
+ err = wl_set_encrypt(ic, iw_encryp);
break;
default:
ieee80211_err("wifi_cfg_encrypt: unknown command %x\n", cmd);
@@ -614,47 +459,10 @@ wifi_cfg_bsstype(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- *ow_opmode = WL_BSS_BSS;
- break;
- case IEEE80211_M_IBSS:
- *ow_opmode = WL_BSS_IBSS;
- break;
- default:
- *ow_opmode = WL_BSS_ANY;
- break;
- }
+ wl_get_bsstype(ic, ow_opmode);
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_bsstype: "
- "set bsstype=%u\n", *iw_opmode);
- switch (*iw_opmode) {
- case WL_BSS_BSS:
- ic->ic_flags &= ~IEEE80211_F_IBSSON;
- ic->ic_opmode = IEEE80211_M_STA;
- err = ENETRESET;
- break;
- case WL_BSS_IBSS:
- if ((ic->ic_caps & IEEE80211_C_IBSS) == 0) {
- outp->wldp_result = WL_LACK_FEATURE;
- err = ENOTSUP;
- break;
- }
-
- if ((ic->ic_flags & IEEE80211_F_IBSSON) == 0) {
- ic->ic_flags |= IEEE80211_F_IBSSON;
- ic->ic_opmode = IEEE80211_M_IBSS;
- err = ENETRESET;
- }
- break;
- default:
- ieee80211_err("wifi_cfg_bsstype: "
- "unknown opmode %u\n", *iw_opmode);
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- }
+ err = wl_set_bsstype(ic, iw_opmode);
break;
default:
ieee80211_err("wifi_cfg_bsstype: unknown command %x\n", cmd);
@@ -683,12 +491,7 @@ wifi_cfg_linkstatus(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- *ow_linkstat = (ic->ic_state == IEEE80211_S_RUN) ?
- WL_CONNECTED : WL_NOTCONNECTED;
- if ((ic->ic_flags & IEEE80211_F_WPA) &&
- (ieee80211_crypto_getciphertype(ic) != WIFI_SEC_WPA)) {
- *ow_linkstat = WL_NOTCONNECTED;
- }
+ wl_get_linkstatus(ic, ow_linkstat);
break;
case WLAN_SET_PARAM:
outp->wldp_result = WL_READONLY;
@@ -712,9 +515,7 @@ wifi_cfg_suprates(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
mblk_t *omp;
wldp_t *outp;
wl_rates_t *ow_rates;
- const struct ieee80211_rateset *srs;
- uint8_t srates, *drates;
- int err, buflen, i, j, k, l;
+ int err, buflen;
err = 0;
/* rate value (wl_rates_rates) is of type char */
@@ -727,30 +528,7 @@ wifi_cfg_suprates(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- /* all rates supported by the device */
- ow_rates->wl_rates_num = 0;
- drates = (uint8_t *)ow_rates->wl_rates_rates;
- for (i = 0; i < IEEE80211_MODE_MAX; i++) {
- srs = &ic->ic_sup_rates[i];
- if (srs->ir_nrates == 0)
- continue;
-
- for (j = 0; j < srs->ir_nrates; j++) {
- srates = IEEE80211_RV(srs->ir_rates[j]);
- /* sort and skip duplicated rates */
- for (k = 0; k < ow_rates->wl_rates_num; k++) {
- if (srates <= drates[k])
- break;
- }
- if (srates == drates[k])
- continue; /* duplicate, skip */
- /* sort */
- for (l = ow_rates->wl_rates_num; l > k; l--)
- drates[l] = drates[l-1];
- drates[k] = srates;
- ow_rates->wl_rates_num++;
- }
- }
+ (void) wl_get_suprates(ic, ow_rates);
break;
case WLAN_SET_PARAM:
outp->wldp_result = WL_READONLY;
@@ -776,11 +554,7 @@ wifi_cfg_desrates(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
mblk_t *omp;
wldp_t *outp;
wl_rates_t *ow_rates;
- struct ieee80211_node *in = ic->ic_bss;
- struct ieee80211_rateset *rs = &in->in_rates;
- uint8_t drate, srate;
- int err, i, j;
- boolean_t found;
+ int err;
err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, sizeof (wl_rates_t))) == NULL)
@@ -788,86 +562,12 @@ wifi_cfg_desrates(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
outp = (wldp_t *)omp->b_rptr;
ow_rates = (wl_rates_t *)outp->wldp_buf;
- srate = rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL;
switch (cmd) {
case WLAN_GET_PARAM:
- ow_rates->wl_rates_num = 1;
- ow_rates->wl_rates_rates[0] =
- (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
- srate : ic->ic_fixed_rate;
+ wl_get_desrates(ic, ow_rates);
break;
case WLAN_SET_PARAM:
- drate = iw_rates->wl_rates_rates[0];
- if (ic->ic_fixed_rate == drate)
- break;
-
- ieee80211_dbg(IEEE80211_MSG_CONFIG, "wifi_cfg_desrates: "
- "set desired rate=%u\n", drate);
-
- if (drate == 0) { /* reset */
- ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
- if (ic->ic_state == IEEE80211_S_RUN) {
- IEEE80211_UNLOCK(ic);
- ieee80211_new_state(ic, IEEE80211_S_ASSOC, 0);
- IEEE80211_LOCK(ic);
- }
- break;
- }
-
- /*
- * Set desired rate. the desired rate is for data transfer
- * and usually is checked and used when driver changes to
- * RUN state.
- * If the driver is in AUTH | ASSOC | RUN state, desired
- * rate is checked against rates supported by current ESS.
- * If it's supported and current state is AUTH|ASSOC, nothing
- * needs to be doen by driver since the desired rate will
- * be enabled when the device changes to RUN state. And
- * when current state is RUN, Re-associate with the ESS to
- * enable the desired rate.
- */
- if (ic->ic_state != IEEE80211_S_INIT &&
- ic->ic_state != IEEE80211_S_SCAN) {
- /* check if the rate is supported by current ESS */
- for (i = 0; i < rs->ir_nrates; i++) {
- if (drate == IEEE80211_RV(rs->ir_rates[i]))
- break;
- }
- if (i < rs->ir_nrates) { /* supported */
- ic->ic_fixed_rate = drate;
- if (ic->ic_state == IEEE80211_S_RUN) {
- IEEE80211_UNLOCK(ic);
- ieee80211_new_state(ic,
- IEEE80211_S_ASSOC, 0);
- IEEE80211_LOCK(ic);
- }
- break;
- }
- }
-
- /* check the rate is supported by device */
- found = B_FALSE;
- for (i = 0; i < IEEE80211_MODE_MAX; i++) {
- rs = &ic->ic_sup_rates[i];
- for (j = 0; j < rs->ir_nrates; j++) {
- if (drate == IEEE80211_RV(rs->ir_rates[j])) {
- found = B_TRUE;
- break;
- }
- }
- if (found)
- break;
- }
- if (!found) {
- ieee80211_err("wifi_cfg_desrates: "
- "invalid rate %d\n", drate);
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- }
- ic->ic_fixed_rate = drate;
- if (ic->ic_state != IEEE80211_S_SCAN)
- err = ENETRESET; /* restart */
+ err = wl_set_desrates(ic, iw_rates);
break;
default:
ieee80211_err("wifi_cfg_desrates: unknown command %x\n", cmd);
@@ -1216,9 +916,7 @@ wifi_cfg_caps(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_caps: "
- "ic_caps = %u\n", ic->ic_caps);
- o_caps->caps = ic->ic_caps;
+ wl_get_capability(ic, o_caps);
break;
case WLAN_SET_PARAM:
outp->wldp_result = WL_READONLY;
@@ -1256,20 +954,10 @@ wifi_cfg_wpa(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
switch (cmd) {
case WLAN_GET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_wpa: "
- "get wpa=%u\n", wpa->wpa_flag);
- o_wpa->wpa_flag = ((ic->ic_flags & IEEE80211_F_WPA)? 1 : 0);
+ wl_get_wpa(ic, o_wpa);
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_wpa: "
- "set wpa=%u\n", wpa->wpa_flag);
- if (wpa->wpa_flag > 0) { /* enable WPA mode */
- ic->ic_flags |= IEEE80211_F_PRIVACY;
- ic->ic_flags |= IEEE80211_F_WPA;
- } else {
- ic->ic_flags &= ~IEEE80211_F_PRIVACY;
- ic->ic_flags &= ~IEEE80211_F_WPA;
- }
+ err = wl_set_wpa(ic, wpa);
break;
default:
ieee80211_err("wifi_cfg_wpa: unknown command %x\n", cmd);
@@ -1294,9 +982,6 @@ wifi_cfg_wpakey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wl_key_t *ik = (wl_key_t *)(inp->wldp_buf);
- struct ieee80211_node *in;
- struct ieee80211_key *wk;
- uint16_t kid;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, 0)) == NULL)
@@ -1309,62 +994,7 @@ wifi_cfg_wpakey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
err = EINVAL;
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_wpakey: "
- "idx=%d\n", ik->ik_keyix);
- /* NB: cipher support is verified by ieee80211_crypt_newkey */
- /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */
- if (ik->ik_keylen > sizeof (ik->ik_keydata)) {
- ieee80211_err("wifi_cfg_wpakey: key too long\n");
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
- }
- kid = ik->ik_keyix;
- if (kid == IEEE80211_KEYIX_NONE || kid >= IEEE80211_WEP_NKID) {
- ieee80211_err("wifi_cfg_wpakey: incorrect keyix\n");
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
-
- } else {
- wk = &ic->ic_nw_keys[kid];
- /*
- * Global slots start off w/o any assigned key index.
- * Force one here for consistency with WEPKEY.
- */
- if (wk->wk_keyix == IEEE80211_KEYIX_NONE)
- wk->wk_keyix = kid;
- /* in = ic->ic_bss; */
- in = NULL;
- }
-
- KEY_UPDATE_BEGIN(ic);
- if (ieee80211_crypto_newkey(ic, ik->ik_type,
- ik->ik_flags, wk)) {
- wk->wk_keylen = ik->ik_keylen;
- /* NB: MIC presence is implied by cipher type */
- if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE)
- wk->wk_keylen = IEEE80211_KEYBUF_SIZE;
- wk->wk_keyrsc = ik->ik_keyrsc;
- wk->wk_keytsc = 0; /* new key, reset */
- wk->wk_flags |= ik->ik_flags &
- (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV);
- (void) memset(wk->wk_key, 0, sizeof (wk->wk_key));
- (void) memcpy(wk->wk_key, ik->ik_keydata,
- ik->ik_keylen);
- if (!ieee80211_crypto_setkey(ic, wk,
- in != NULL ? in->in_macaddr : ik->ik_macaddr)) {
- err = EIO;
- outp->wldp_result = WL_HW_ERROR;
- } else if ((ik->ik_flags & IEEE80211_KEY_DEFAULT)) {
- ic->ic_def_txkey = kid;
- ieee80211_mac_update(ic);
- }
- } else {
- err = EIO;
- outp->wldp_result = WL_HW_ERROR;
- }
- KEY_UPDATE_END(ic);
+ err = wl_set_wpakey(ic, ik);
break;
default:
ieee80211_err("wifi_cfg_wpakey: unknown command %x\n", cmd);
@@ -1389,7 +1019,6 @@ wifi_cfg_delkey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wl_del_key_t *dk = (wl_del_key_t *)inp->wldp_buf;
- int kid;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, 0)) == NULL)
@@ -1402,20 +1031,7 @@ wifi_cfg_delkey(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
err = EINVAL;
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_delkey: "
- "keyix=%d\n", dk->idk_keyix);
- kid = dk->idk_keyix;
- if (kid == IEEE80211_KEYIX_NONE || kid >= IEEE80211_WEP_NKID) {
- ieee80211_err("wifi_cfg_delkey: incorrect keyix\n");
- outp->wldp_result = WL_NOTSUPPORTED;
- err = EINVAL;
- break;
-
- } else {
- (void) ieee80211_crypto_delkey(ic,
- &ic->ic_nw_keys[kid]);
- ieee80211_mac_update(ic);
- }
+ err = wl_set_delkey(ic, dk);
break;
default:
ieee80211_err("wifi_cfg_delkey: unknown command %x\n", cmd);
@@ -1439,7 +1055,6 @@ wifi_cfg_setoptie(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wl_wpa_ie_t *ie_in = (wl_wpa_ie_t *)inp->wldp_buf;
- char *ie;
int err = 0;
if ((omp = wifi_getoutmsg(*mp, cmd, 0)) == NULL)
@@ -1452,32 +1067,8 @@ wifi_cfg_setoptie(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
err = EINVAL;
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_setoptie\n");
- /*
- * NB: Doing this for ap operation could be useful (e.g. for
- * WPA and/or WME) except that it typically is worthless
- * without being able to intervene when processing
- * association response frames--so disallow it for now.
- */
- if (ic->ic_opmode != IEEE80211_M_STA) {
- ieee80211_err("wifi_cfg_setoptie: opmode err\n");
- err = EINVAL;
+ if ((err = wl_set_optie(ic, ie_in)) == EINVAL)
outp->wldp_result = WL_NOTSUPPORTED;
- break;
- }
- if (ie_in->wpa_ie_len > IEEE80211_MAX_OPT_IE) {
- ieee80211_err("wifi_cfg_setoptie: optie too long\n");
- err = EINVAL;
- outp->wldp_result = WL_NOTSUPPORTED;
- break;
- }
-
- ie = ieee80211_malloc(ie_in->wpa_ie_len);
- (void) memcpy(ie, ie_in->wpa_ie, ie_in->wpa_ie_len);
- if (ic->ic_opt_ie != NULL)
- ieee80211_free(ic->ic_opt_ie);
- ic->ic_opt_ie = ie;
- ic->ic_opt_ie_len = ie_in->wpa_ie_len;
break;
default:
ieee80211_err("wifi_cfg_setoptie: unknown command %x\n", cmd);
@@ -1573,9 +1164,7 @@ wifi_cfg_setmlme(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
wldp_t *outp;
wldp_t *inp = (wldp_t *)(*mp)->b_rptr;
wl_mlme_t *mlme = (wl_mlme_t *)inp->wldp_buf;
- ieee80211_node_t *in;
int err = 0;
- uint32_t flags;
if ((omp = wifi_getoutmsg(*mp, cmd, 0)) == NULL)
return (ENOMEM);
@@ -1587,60 +1176,7 @@ wifi_cfg_setmlme(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
err = EINVAL;
break;
case WLAN_SET_PARAM:
- ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_setmlme: "
- "op=%d\n", mlme->im_op);
- switch (mlme->im_op) {
- case IEEE80211_MLME_DISASSOC:
- case IEEE80211_MLME_DEAUTH:
- if (ic->ic_opmode == IEEE80211_M_STA) {
- /*
- * Mask ic_flags of IEEE80211_F_WPA to disable
- * ieee80211_notify temporarily.
- */
- flags = ic->ic_flags;
- ic->ic_flags &= ~IEEE80211_F_WPA;
-
- IEEE80211_UNLOCK(ic);
- ieee80211_new_state(ic, IEEE80211_S_INIT,
- mlme->im_reason);
- IEEE80211_LOCK(ic);
-
- ic->ic_flags = flags;
- }
- break;
- case IEEE80211_MLME_ASSOC:
- if (ic->ic_opmode != IEEE80211_M_STA) {
- ieee80211_err("wifi_cfg_setmlme: opmode err\n");
- err = EINVAL;
- outp->wldp_result = WL_NOTSUPPORTED;
- break;
- }
- if (ic->ic_des_esslen != 0) {
- /*
- * Desired ssid specified; must match both bssid and
- * ssid to distinguish ap advertising multiple ssid's.
- */
- in = ieee80211_find_node_with_ssid(&ic->ic_scan,
- mlme->im_macaddr,
- ic->ic_des_esslen, ic->ic_des_essid);
- } else {
- /*
- * Normal case; just match bssid.
- */
- in = ieee80211_find_node(&ic->ic_scan,
- mlme->im_macaddr);
- }
- if (in == NULL) {
- ieee80211_err("wifi_cfg_setmlme: "
- "no matched node\n");
- err = EINVAL;
- outp->wldp_result = WL_NOTSUPPORTED;
- break;
- }
- IEEE80211_UNLOCK(ic);
- ieee80211_sta_join(ic, in);
- IEEE80211_LOCK(ic);
- }
+ err = wl_set_mlme(ic, mlme);
break;
default:
ieee80211_err("wifi_cfg_delkey: unknown command %x\n", cmd);
@@ -1842,3 +1378,1055 @@ ieee80211_ioctl(struct ieee80211com *ic, queue_t *wq, mblk_t *mp)
return (err);
}
+
+/*
+ * The following routines are for brussels support
+ */
+
+/*
+ * MAC_PROP_WL_ESSID
+ */
+static int
+wl_set_essid(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ char *essid;
+ wl_essid_t *iw_essid = (wl_essid_t *)wldp_buf;
+
+ if (iw_essid->wl_essid_length > IEEE80211_NWID_LEN) {
+ ieee80211_err("wl_set_essid: "
+ "essid too long, %u, max %u\n",
+ iw_essid->wl_essid_length, IEEE80211_NWID_LEN);
+
+ err = EINVAL;
+ return (err);
+ }
+
+ essid = iw_essid->wl_essid_essid;
+ essid[IEEE80211_NWID_LEN] = 0;
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_essid: "
+ "set essid=%s length=%d\n",
+ essid, iw_essid->wl_essid_length);
+
+ ic->ic_des_esslen = iw_essid->wl_essid_length;
+ if (ic->ic_des_esslen != 0)
+ bcopy(essid, ic->ic_des_essid, ic->ic_des_esslen);
+ if (ic->ic_des_esslen < IEEE80211_NWID_LEN)
+ ic->ic_des_essid[ic->ic_des_esslen] = 0;
+
+ err = ENETRESET;
+
+ return (err);
+}
+
+static void
+wl_get_essid(struct ieee80211com *ic, void *wldp_buf)
+{
+ char *essid;
+ wl_essid_t ow_essid;
+
+ essid = (char *)ic->ic_des_essid;
+ if (essid[0] == '\0')
+ essid = (char *)ic->ic_bss->in_essid;
+
+ bzero(&ow_essid, sizeof (wl_essid_t));
+ ow_essid.wl_essid_length = wifi_strnlen((const char *)essid,
+ IEEE80211_NWID_LEN);
+ bcopy(essid, ow_essid.wl_essid_essid,
+ ow_essid.wl_essid_length);
+ bcopy(&ow_essid, wldp_buf, sizeof (wl_essid_t));
+
+}
+
+/*
+ * MAC_PROP_WL_BSSID
+ */
+static int
+wl_set_bssid(struct ieee80211com *ic, const void* wldp_buf)
+{
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_bssid: "
+ "set bssid=%s\n",
+ ieee80211_macaddr_sprintf(wldp_buf));
+
+ bcopy(wldp_buf, ic->ic_des_bssid, sizeof (wl_bssid_t));
+ ic->ic_flags |= IEEE80211_F_DESBSSID;
+
+ return (ENETRESET);
+}
+
+static void
+wl_get_bssid(struct ieee80211com *ic, void *wldp_buf)
+{
+ uint8_t *bssid;
+
+ if (ic->ic_flags & IEEE80211_F_DESBSSID)
+ bssid = ic->ic_des_bssid;
+ else
+ bssid = ic->ic_bss->in_bssid;
+ bcopy(bssid, wldp_buf, sizeof (wl_bssid_t));
+
+}
+
+/*
+ * MAC_PROP_WL_BSSTYP
+ */
+static int
+wl_set_bsstype(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ wl_bss_type_t *iw_opmode = (wl_bss_type_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_bsstype: "
+ "set bsstype=%u\n", *iw_opmode);
+
+ switch (*iw_opmode) {
+ case WL_BSS_BSS:
+ ic->ic_flags &= ~IEEE80211_F_IBSSON;
+ ic->ic_opmode = IEEE80211_M_STA;
+ err = ENETRESET;
+ break;
+ case WL_BSS_IBSS:
+ if ((ic->ic_caps & IEEE80211_C_IBSS) == 0) {
+ err = ENOTSUP;
+ break;
+ }
+ if ((ic->ic_flags & IEEE80211_F_IBSSON) == 0) {
+ ic->ic_flags |= IEEE80211_F_IBSSON;
+ ic->ic_opmode = IEEE80211_M_IBSS;
+ err = ENETRESET;
+ }
+ break;
+ default:
+ ieee80211_err("wl_set_bsstype: "
+ "unknown opmode\n");
+ err = EINVAL;
+ break;
+ }
+ return (err);
+}
+
+static void
+wl_get_bsstype(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_bss_type_t ow_opmode;
+
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_STA:
+ ow_opmode = WL_BSS_BSS;
+ break;
+ case IEEE80211_M_IBSS:
+ ow_opmode = WL_BSS_IBSS;
+ break;
+ default:
+ ow_opmode = WL_BSS_ANY;
+ break;
+ }
+
+ bcopy(&ow_opmode, wldp_buf, sizeof (wl_bss_type_t));
+}
+
+/*
+ * MAC_PROP_WL_LINKSTATUS
+ */
+static void
+wl_get_linkstatus(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_linkstatus_t ow_linkstat;
+
+ ow_linkstat = (ic->ic_state == IEEE80211_S_RUN) ?
+ WL_CONNECTED : WL_NOTCONNECTED;
+ if ((ic->ic_flags & IEEE80211_F_WPA) &&
+ (ieee80211_crypto_getciphertype(ic) != WIFI_SEC_WPA)) {
+ ow_linkstat = WL_NOTCONNECTED;
+ }
+
+ bcopy(&ow_linkstat, wldp_buf, sizeof (wl_linkstatus_t));
+}
+
+/*
+ * MAC_PROP_WL_DESIRED_RATESa
+ */
+static int
+wl_set_desrates(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ int i, j;
+ uint8_t drate;
+ boolean_t isfound;
+ wl_rates_t *iw_rates = (wl_rates_t *)wldp_buf;
+ struct ieee80211_node *in = ic->ic_bss;
+ struct ieee80211_rateset *rs = &in->in_rates;
+
+ drate = iw_rates->wl_rates_rates[0];
+ if (ic->ic_fixed_rate == drate)
+ return (err);
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_desrates: "
+ "set desired rate=%u\n", drate);
+
+ if (drate == 0) {
+ ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
+ if (ic->ic_state == IEEE80211_S_RUN) {
+ IEEE80211_UNLOCK(ic);
+ ieee80211_new_state(ic, IEEE80211_S_ASSOC, 0);
+ IEEE80211_LOCK(ic);
+ }
+ return (err);
+ }
+
+ /*
+ * Set desired rate. The desired rate is for data transfer
+ * and usally is checked and used when driver changes to
+ * RUN state.
+ * If the driver is in AUTH | ASSOC | RUN state, desired
+ * rate is checked anainst rates supported by current ESS.
+ * If it's supported and current state is AUTH|ASSOC, nothing
+ * needs to be done by driver since the desired rate will
+ * be enabled when the device changes to RUN state. And
+ * when current state is RUN, Re-associate with the ESS to
+ * enable the desired rate.
+ */
+
+ if (ic->ic_state != IEEE80211_S_INIT &&
+ ic->ic_state != IEEE80211_S_SCAN) {
+ for (i = 0; i < rs->ir_nrates; i++) {
+ if (drate == IEEE80211_RV(rs->ir_rates[i]))
+ break;
+ }
+ /* supported */
+ if (i < rs->ir_nrates) {
+ ic->ic_fixed_rate = drate;
+ if (ic->ic_state == IEEE80211_S_RUN) {
+ IEEE80211_UNLOCK(ic);
+ ieee80211_new_state(ic,
+ IEEE80211_S_ASSOC, 0);
+ IEEE80211_LOCK(ic);
+ }
+ return (err);
+ }
+ }
+
+ /*
+ * In INIT or SCAN state
+ * check if the desired rate is supported by device
+ */
+ isfound = B_FALSE;
+ for (i = 0; i < IEEE80211_MODE_MAX; i++) {
+ rs = &ic->ic_sup_rates[i];
+ for (j = 0; j < rs->ir_nrates; j++) {
+ if (drate == IEEE80211_RV(rs->ir_rates[j])) {
+ isfound = B_TRUE;
+ break;
+ }
+ }
+ if (isfound)
+ break;
+ }
+ if (!isfound) {
+ ieee80211_err("wl_set_desrates: "
+ "invald rate %d\n", drate);
+ err = EINVAL;
+ return (err);
+ }
+ ic->ic_fixed_rate = drate;
+ if (ic->ic_state != IEEE80211_S_SCAN)
+ err = ENETRESET;
+
+ return (err);
+}
+
+static void
+wl_get_desrates(struct ieee80211com *ic, void *wldp_buf)
+{
+ uint8_t srate;
+ wl_rates_t ow_rates;
+ struct ieee80211_node *in = ic->ic_bss;
+ struct ieee80211_rateset *rs = &in->in_rates;
+
+ srate = rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL;
+ ow_rates.wl_rates_num = 1;
+ ow_rates.wl_rates_rates[0] =
+ (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
+ srate : ic->ic_fixed_rate;
+ bcopy(&ow_rates, wldp_buf, sizeof (wl_rates_t));
+
+}
+
+/*
+ * MAC_PROP_AUTH_MODE
+ */
+static int
+wl_set_authmode(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ wl_authmode_t *iw_auth = (wl_authmode_t *)wldp_buf;
+
+ if (*iw_auth == ic->ic_bss->in_authmode)
+ return (err);
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_authmode: "
+ "set authmode=%u\n", *iw_auth);
+
+ switch (*iw_auth) {
+ case WL_OPENSYSTEM:
+ case WL_SHAREDKEY:
+ ic->ic_bss->in_authmode = *iw_auth;
+ err = ENETRESET;
+ break;
+ default:
+ ieee80211_err("wl_set_authmode: "
+ "unknown authmode %u\n", *iw_auth);
+ err = EINVAL;
+ break;
+ }
+
+ return (err);
+}
+
+static void
+wl_get_authmode(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_authmode_t ow_auth;
+
+ ow_auth = ic->ic_bss->in_authmode;
+ bcopy(&ow_auth, wldp_buf, sizeof (wl_authmode_t));
+
+}
+
+/*
+ * MAC_PROP_WL_ENCRYPTION
+ */
+static int
+wl_set_encrypt(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ uint32_t flags;
+ wl_encryption_t *iw_encryp = (wl_encryption_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_encrypt: "
+ "set encryption=%u\n", *iw_encryp);
+
+ flags = ic->ic_flags;
+ if (*iw_encryp == WL_NOENCRYPTION)
+ flags &= ~IEEE80211_F_PRIVACY;
+ else
+ flags |= IEEE80211_F_PRIVACY;
+
+ if (ic->ic_flags != flags) {
+ ic->ic_flags = flags;
+ err = ENETRESET;
+ }
+
+ return (err);
+}
+
+static void
+wl_get_encrypt(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_encryption_t *ow_encryp;
+
+ ow_encryp = (wl_encryption_t *)wldp_buf;
+ *ow_encryp = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
+ if (ic->ic_flags & IEEE80211_F_WPA)
+ *ow_encryp = WL_ENC_WPA;
+
+}
+
+/*
+ * MAC_PROP_WL_RSSI
+ */
+static void
+wl_get_rssi(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_rssi_t *ow_rssi;
+
+ ow_rssi = (wl_rssi_t *)wldp_buf;
+ *ow_rssi = wifi_getrssi(ic->ic_bss);
+
+}
+
+/*
+ * MAC_PROP_WL_PHY_CONFIG
+ */
+
+static int
+wl_set_phy(struct ieee80211com *ic, const void* wldp_buf)
+{
+ int err = 0;
+ int16_t ch;
+ wl_dsss_t *dsss;
+ wl_phy_conf_t *iw_phy = (wl_phy_conf_t *)wldp_buf;
+
+ dsss = (wl_dsss_t *)iw_phy;
+ ch = dsss->wl_dsss_channel;
+
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_phy: "
+ "set channel=%d\n", ch);
+
+ if (ch == 0 || ch == (int16_t)IEEE80211_CHAN_ANY) {
+ ic->ic_des_chan = IEEE80211_CHAN_ANYC;
+ } else if ((uint_t)ch > IEEE80211_CHAN_MAX ||
+ ieee80211_isclr(ic->ic_chan_active, ch)) {
+ err = EINVAL;
+ return (err);
+ } else {
+ ic->ic_des_chan = ic->ic_ibss_chan =
+ &ic->ic_sup_channels[ch];
+ }
+
+ switch (ic->ic_state) {
+ case IEEE80211_S_INIT:
+ case IEEE80211_S_SCAN:
+ err = ENETRESET;
+ break;
+ default:
+ /*
+ * If hte desired channel has changed (to something
+ * other than any) and we're not already scanning,
+ * then kick the state machine.
+ */
+ if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
+ ic->ic_bss->in_chan != ic->ic_des_chan &&
+ (ic->ic_flags & IEEE80211_F_SCAN) == 0)
+ err = ENETRESET;
+ break;
+ }
+
+ return (err);
+}
+
+static int
+wl_get_phy(struct ieee80211com *ic, void *wldp_buf)
+{
+ int err = 0;
+ wl_phy_conf_t *ow_phy;
+ struct ieee80211_channel *ch = ic->ic_curchan;
+
+ ow_phy = (wl_phy_conf_t *)wldp_buf;
+ bzero(wldp_buf, sizeof (wl_phy_conf_t));
+
+ /* get current phy parameters: FH|DS|ERP */
+ if (IEEE80211_IS_CHAN_A(ch) || IEEE80211_IS_CHAN_T(ch)) {
+ wl_ofdm_t *ofdm = (wl_ofdm_t *)ow_phy;
+ ofdm->wl_ofdm_subtype = WL_OFDM;
+ ofdm->wl_ofdm_frequency = ch->ich_freq;
+ } else {
+ switch (ic->ic_phytype) {
+ case IEEE80211_T_FH: {
+ wl_fhss_t *fhss = (wl_fhss_t *)ow_phy;
+ fhss->wl_fhss_subtype = WL_FHSS;
+ fhss->wl_fhss_channel =
+ ieee80211_chan2ieee(ic, ch);
+ break;
+ }
+ case IEEE80211_T_DS: {
+ wl_dsss_t *dsss = (wl_dsss_t *)ow_phy;
+ dsss->wl_dsss_subtype = WL_DSSS;
+ dsss->wl_dsss_channel =
+ ieee80211_chan2ieee(ic, ch);
+ break;
+ }
+ case IEEE80211_T_OFDM: {
+ wl_erp_t *erp = (wl_erp_t *)ow_phy;
+ erp->wl_erp_subtype = WL_ERP;
+ erp->wl_erp_channel =
+ ieee80211_chan2ieee(ic, ch);
+ break;
+ }
+ default:
+ ieee80211_err("wl_get_phy: "
+ "unknown phy type, %x\n", ic->ic_phytype);
+ err = EIO;
+ break;
+ }
+ }
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_CAPABILITY
+ */
+static void
+wl_get_capability(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_capability_t ow_caps;
+
+ ow_caps.caps = ic->ic_caps;
+ bcopy(&ow_caps, wldp_buf, sizeof (wl_capability_t));
+
+}
+
+/*
+ * MAC_PROP_WL_WPA
+ */
+static int
+wl_set_wpa(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ wl_wpa_t *wpa = (wl_wpa_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_BRUSSELS, "wl_set_wpa: "
+ "set wpa=%u\n", wpa->wpa_flag);
+
+ if (wpa->wpa_flag > 0) {
+ /* enable wpa mode */
+ ic->ic_flags |= IEEE80211_F_PRIVACY;
+ ic->ic_flags |= IEEE80211_F_WPA;
+ } else {
+ ic->ic_flags &= ~IEEE80211_F_PRIVACY;
+ ic->ic_flags &= ~IEEE80211_F_WPA;
+ }
+
+ return (err);
+}
+
+static void
+wl_get_wpa(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_wpa_t *wpa;
+
+ wpa = (wl_wpa_t *)wldp_buf;
+ wpa->wpa_flag = ((ic->ic_flags & IEEE80211_F_WPA) ? 1 : 0);
+
+ ieee80211_dbg(IEEE80211_MSG_BRUSSELS, "wl_get_wpa: "
+ "get wpa=%u\n", wpa->wpa_flag);
+
+}
+
+/*
+ * MAC_PROP_WL_SCANRESULTS
+ */
+
+static void
+wl_get_scanresults(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_wpa_ess_t *sr;
+ ieee80211_node_t *in;
+ ieee80211_node_table_t *nt;
+ int ap_num;
+ int len;
+
+ sr = (wl_wpa_ess_t *)wldp_buf;
+ sr->count = 0;
+ ap_num = 0;
+
+ ieee80211_dbg(IEEE80211_MSG_WPA, "wl_get_scanrelults\n");
+
+ nt = &ic->ic_scan;
+ IEEE80211_NODE_LOCK(nt);
+ in = list_head(&nt->nt_node);
+
+ while (in != NULL) {
+ /* filter out non-wpa APs */
+ if (in->in_wpa_ie == NULL) {
+ in = list_next(&nt->nt_node, in);
+ continue;
+ }
+ bcopy(in->in_bssid, sr->ess[ap_num].bssid,
+ IEEE80211_ADDR_LEN);
+ sr->ess[ap_num].ssid_len = in->in_esslen;
+ bcopy(in->in_essid, sr->ess[ap_num].ssid,
+ in->in_esslen);
+ sr->ess[ap_num].freq = in->in_chan->ich_freq;
+
+ len = in->in_wpa_ie[1] + 2;
+ bcopy(in->in_wpa_ie, sr->ess[ap_num].wpa_ie, len);
+ sr->ess[ap_num].wpa_ie_len = len;
+
+ ap_num++;
+ in = list_next(&nt->nt_node, in);
+ }
+ IEEE80211_NODE_UNLOCK(nt);
+ sr->count = ap_num;
+
+}
+
+/*
+ * MAC_PROP_WL_ESS_LIST
+ */
+static void
+wl_get_esslist(struct ieee80211com *ic, void *wldp_buf)
+{
+ wl_ess_list_t *ess_list;
+
+ ess_list = (wl_ess_list_t *)wldp_buf;
+
+ ess_list->wl_ess_list_num = 0;
+ ieee80211_iterate_nodes(&ic->ic_scan, wifi_read_ap, ess_list);
+
+}
+
+/*
+ * MAC_PROP_WL_WEP_KEY
+ */
+static int
+wl_set_wepkey(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ uint16_t i;
+ uint32_t klen;
+ struct ieee80211_key *key;
+ wl_wep_key_t *wepkey = (wl_wep_key_t *)wldp_buf;
+
+ /* set all valid keys */
+ for (i = 0; i < MAX_NWEPKEYS; i++) {
+ if (wepkey[i].wl_wep_operation != WL_ADD)
+ continue;
+ klen = wepkey[i].wl_wep_length;
+ if (klen > IEEE80211_KEYBUF_SIZE) {
+ ieee80211_err("wl_set_wepkey: "
+ "invalid wepkey length, %u\n", klen);
+ err = EINVAL;
+ continue; /* continue to set other keys */
+ }
+ if (klen == 0)
+ continue;
+
+ /*
+ * Set key contents. Only WEP is supported
+ */
+ ieee80211_dbg(IEEE80211_MSG_CONFIG, "wl_set_wepkey: "
+ "set key %u, len=%u\n", i, klen);
+ key = &ic->ic_nw_keys[i];
+ if (ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_WEP,
+ IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key) == 0) {
+ ieee80211_err("wl_set_wepkey: "
+ "abort, create key failed. id=%u\n", i);
+ err = EIO;
+ continue;
+ }
+
+ key->wk_keyix = i;
+ key->wk_keylen = (uint8_t)klen;
+ key->wk_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
+ bzero(key->wk_key, IEEE80211_KEYBUF_SIZE);
+ bcopy(wepkey[i].wl_wep_key, key->wk_key, klen);
+ if (ieee80211_crypto_setkey(ic, key, ic->ic_macaddr)
+ == 0) {
+ ieee80211_err("wl_set_wepkey: "
+ "set key failed len=%u\n", klen);
+ err = EIO;
+ }
+ }
+ if (err == 0)
+ err = ENETRESET;
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_SETOPTIE
+ */
+static int
+wl_set_optie(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ char *ie;
+ wl_wpa_ie_t *ie_in = (wl_wpa_ie_t *)wldp_buf;
+
+ if (ic->ic_opmode != IEEE80211_M_STA) {
+ ieee80211_err("wl_set_optie: opmode err\n");
+ err = EINVAL;
+ return (err);
+ }
+ if (ie_in->wpa_ie_len > IEEE80211_MAX_OPT_IE) {
+
+ ieee80211_err("wl_set_optie: optie is too long\n");
+
+ err = EINVAL;
+ return (err);
+ }
+
+ ie = ieee80211_malloc(ie_in->wpa_ie_len);
+ (void) memcpy(ie, ie_in->wpa_ie, ie_in->wpa_ie_len);
+ if (ic->ic_opt_ie != NULL) {
+ ieee80211_dbg(IEEE80211_MSG_BRUSSELS,
+ "wl_set_optie:ic_opt_ie!=NULL\n");
+ ieee80211_free(ic->ic_opt_ie);
+ }
+ ic->ic_opt_ie = ie;
+ ic->ic_opt_ie_len = ie_in->wpa_ie_len;
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_DELKEY
+ */
+static int
+wl_set_delkey(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ int kid;
+ wl_del_key_t *dk = (wl_del_key_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_BRUSSELS, "wl_set_delkey(): "
+ "keyix=%d\n", dk->idk_keyix);
+
+ kid = dk->idk_keyix;
+
+ if (kid == IEEE80211_KEYIX_NONE ||
+ kid >= IEEE80211_WEP_NKID) {
+ ieee80211_err("wl_set_delkey: incorrect keyix\n");
+ err = EINVAL;
+ return (err);
+ } else {
+ (void) ieee80211_crypto_delkey(ic,
+ &ic->ic_nw_keys[kid]);
+ ieee80211_mac_update(ic);
+ }
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_MLME
+ */
+
+static int
+wl_set_mlme(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ uint32_t flags;
+ ieee80211_node_t *in;
+ wl_mlme_t *mlme = (wl_mlme_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_WPA, "wl_set_mlme: "
+ "op=%d\n", mlme->im_op);
+
+ switch (mlme->im_op) {
+ case IEEE80211_MLME_DISASSOC:
+ case IEEE80211_MLME_DEAUTH:
+ if (ic->ic_opmode == IEEE80211_M_STA) {
+ /*
+ * Mask ic_flags of IEEE80211_F_WPA to disable
+ * ieee80211_notify temporarily.
+ */
+ flags = ic->ic_flags;
+ ic->ic_flags &= ~IEEE80211_F_WPA;
+
+ IEEE80211_UNLOCK(ic);
+ ieee80211_new_state(ic, IEEE80211_S_INIT,
+ mlme->im_reason);
+ IEEE80211_LOCK(ic);
+
+ ic->ic_flags = flags;
+ }
+ break;
+ case IEEE80211_MLME_ASSOC:
+ if (ic->ic_opmode != IEEE80211_M_STA) {
+ ieee80211_err("wifi_cfg_setmlme: opmode err\n");
+ err = EINVAL;
+ break;
+ }
+ if (ic->ic_des_esslen != 0) {
+ /*
+ * Desired ssid specified; must match both bssid and
+ * ssid to distinguish ap advertising multiple ssid's.
+ */
+ in = ieee80211_find_node_with_ssid(&ic->ic_scan,
+ mlme->im_macaddr,
+ ic->ic_des_esslen,
+ ic->ic_des_essid);
+ } else {
+ /*
+ * Normal case; just match bssid.
+ */
+ in = ieee80211_find_node(&ic->ic_scan,
+ mlme->im_macaddr);
+ }
+ if (in == NULL) {
+ ieee80211_err("wifi_cfg_setmlme: "
+ "no matched node\n");
+ err = EINVAL;
+ break;
+ }
+ IEEE80211_UNLOCK(ic);
+ ieee80211_sta_join(ic, in);
+ IEEE80211_LOCK(ic);
+ break;
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_WPA_KEY
+ */
+static int
+wl_set_wpakey(struct ieee80211com *ic, const void *wldp_buf)
+{
+ int err = 0;
+ uint16_t kid;
+ struct ieee80211_node *in;
+ struct ieee80211_key *wk;
+ wl_key_t *ik = (wl_key_t *)wldp_buf;
+
+ ieee80211_dbg(IEEE80211_MSG_BRUSSELS, "wl_set_wpakey: "
+ "idx=%d\n", ik->ik_keyix);
+
+ /*
+ * cipher support is verified by ieee80211_crypt_newkey
+ * this also checks ik->ik_keylen > sizeof(wk->wk_key)
+ */
+ if (ik->ik_keylen > sizeof (ik->ik_keydata)) {
+ ieee80211_err("wl_set_wpakey: key is too long\n");
+ err = EINVAL;
+ return (err);
+ }
+ kid = ik->ik_keyix;
+ if (kid == IEEE80211_KEYIX_NONE || kid >= IEEE80211_WEP_NKID) {
+ ieee80211_err("wl_set_wpakey: incorrect keyix\n");
+ err = EINVAL;
+ return (err);
+ } else {
+ wk = &ic->ic_nw_keys[kid];
+ /*
+ * Globle slots start off w/o any assigned key index.
+ * Force one here for consistency with WEPKEY.
+ */
+ if (wk->wk_keyix == IEEE80211_KEYIX_NONE)
+ wk->wk_keyix = kid;
+ in = NULL;
+ }
+
+ KEY_UPDATE_BEGIN(ic);
+ if (ieee80211_crypto_newkey(ic, ik->ik_type,
+ ik->ik_flags, wk)) {
+ wk->wk_keylen = ik->ik_keylen;
+ /* MIC presence is implied by cipher type */
+ if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE)
+ wk->wk_keylen = IEEE80211_KEYBUF_SIZE;
+ wk->wk_keyrsc = ik->ik_keyrsc;
+ wk->wk_keytsc = 0;
+ wk->wk_flags |= ik->ik_flags &
+ (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV);
+ (void) memset(wk->wk_key, 0, sizeof (wk->wk_key));
+ (void) memcpy(wk->wk_key, ik->ik_keydata,
+ ik->ik_keylen);
+ if (!ieee80211_crypto_setkey(ic, wk,
+ in != NULL ? in->in_macaddr : ik->ik_macaddr)) {
+ err = EIO;
+ } else if ((ik->ik_flags & IEEE80211_KEY_DEFAULT)) {
+ ic->ic_def_txkey = kid;
+ ieee80211_mac_update(ic);
+ }
+ } else {
+ err = EIO;
+ }
+ KEY_UPDATE_END(ic);
+
+ return (err);
+}
+
+/*
+ * MAC_PROP_WL_SUP_RATE
+ */
+static void
+wl_get_suprates(struct ieee80211com *ic, void *wldp_buf)
+{
+ int i, j, k, l;
+ uint8_t srates;
+ uint8_t *drates;
+ wl_rates_t *wl_rates;
+ const struct ieee80211_rateset *srs;
+
+ wl_rates = (wl_rates_t *)wldp_buf;
+
+ wl_rates->wl_rates_num = 0;
+ drates = (uint8_t *)wl_rates->wl_rates_rates;
+ for (i = 0; i < IEEE80211_MODE_MAX; i++) {
+ srs = &ic->ic_sup_rates[i];
+ if (srs->ir_nrates == 0)
+ continue;
+ for (j = 0; j < srs->ir_nrates; j++) {
+ srates = IEEE80211_RV(srs->ir_rates[j]);
+ /* sort & skip duplicated rates */
+ for (k = 0; k < wl_rates->wl_rates_num; k++) {
+ if (srates <= drates[k])
+ break;
+ }
+ if (srates == drates[k])
+ /* skip duplicated rates */
+ continue;
+ /* sort */
+ for (l = wl_rates->wl_rates_num; l > k; l--)
+ drates[l] = drates[l-1];
+ drates[k] = srates;
+ wl_rates->wl_rates_num++;
+ }
+ }
+
+}
+
+/*
+ * Typically invoked by drivers in response to request for
+ * information or to change settings from the userland.
+ *
+ * Return value should be checked by WiFI drivers. Return 0
+ * on success. Otherwise, return non-zero value to indicate
+ * the error. Driver should operate as below when the return
+ * error is:
+ * ENETRESET Reset wireless network and re-start to join a
+ * WLAN, ENETRESET is returned when a configuration
+ * parameter has been changed.
+ * When acknowledge a M_IOCTL message, this error
+ * is ignored
+ */
+/* ARGSUSED */
+int
+ieee80211_setprop(void *ic_arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t wldp_length, const void *wldp_buf)
+{
+ int err = 0;
+ struct ieee80211com *ic = ic_arg;
+
+ ASSERT(ic != NULL);
+ IEEE80211_LOCK(ic);
+
+ switch (wldp_pr_num) {
+ /* mac_prop_id */
+ case MAC_PROP_WL_ESSID:
+ err = wl_set_essid(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_BSSID:
+ err = wl_set_bssid(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_PHY_CONFIG:
+ err = wl_set_phy(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_KEY_TAB:
+ err = wl_set_wepkey(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_AUTH_MODE:
+ err = wl_set_authmode(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_ENCRYPTION:
+ err = wl_set_encrypt(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_BSSTYPE:
+ err = wl_set_bsstype(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_DESIRED_RATES:
+ err = wl_set_desrates(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_WPA:
+ err = wl_set_wpa(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_KEY:
+ err = wl_set_wpakey(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_DELKEY:
+ err = wl_set_delkey(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_SETOPTIE:
+ err = wl_set_optie(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_MLME:
+ err = wl_set_mlme(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_LINKSTATUS:
+ case MAC_PROP_WL_ESS_LIST:
+ case MAC_PROP_WL_SUPPORTED_RATES:
+ case MAC_PROP_WL_RSSI:
+ case MAC_PROP_WL_CAPABILITY:
+ case MAC_PROP_WL_SCANRESULTS:
+ ieee80211_err("ieee80211_setprop: opmode err\n");
+ err = EINVAL;
+ break;
+ default:
+ ieee80211_err("ieee80211_setprop: opmode not support\n");
+ err = ENOTSUP;
+ break;
+ }
+
+ IEEE80211_UNLOCK(ic);
+
+ return (err);
+}
+
+/* ARGSUSED */
+int
+ieee80211_getprop(void *ic_arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+ uint_t pr_flags, uint_t wldp_length, void *wldp_buf)
+{
+ int err = 0;
+ struct ieee80211com *ic = ic_arg;
+
+ if (wldp_length == 0) {
+ err = EINVAL;
+ return (err);
+ }
+ bzero(wldp_buf, wldp_length);
+
+ ASSERT(ic != NULL);
+ IEEE80211_LOCK(ic);
+
+ switch (wldp_pr_num) {
+ /* mac_prop_id */
+ case MAC_PROP_WL_ESSID:
+ wl_get_essid(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_BSSID:
+ wl_get_bssid(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_PHY_CONFIG:
+ err = wl_get_phy(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_AUTH_MODE:
+ wl_get_authmode(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_ENCRYPTION:
+ wl_get_encrypt(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_BSSTYPE:
+ wl_get_bsstype(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_DESIRED_RATES:
+ wl_get_desrates(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_LINKSTATUS:
+ wl_get_linkstatus(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_ESS_LIST:
+ wl_get_esslist(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_SUPPORTED_RATES:
+ wl_get_suprates(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_RSSI:
+ wl_get_rssi(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_CAPABILITY:
+ wl_get_capability(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_WPA:
+ wl_get_wpa(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_SCANRESULTS:
+ wl_get_scanresults(ic, wldp_buf);
+ break;
+ case MAC_PROP_WL_KEY_TAB:
+ case MAC_PROP_WL_KEY:
+ case MAC_PROP_WL_DELKEY:
+ case MAC_PROP_WL_SETOPTIE:
+ case MAC_PROP_WL_MLME:
+ ieee80211_err("ieee80211_setprop: opmode err\n");
+ err = EINVAL;
+ break;
+ default:
+ ieee80211_err("ieee80211_setprop: opmode not support\n");
+ err = ENOTSUP;
+ break;
+ }
+
+ IEEE80211_UNLOCK(ic);
+
+ return (err);
+}
diff --git a/usr/src/uts/common/io/wpi/wpi.c b/usr/src/uts/common/io/wpi/wpi.c
index 3efaf7ccad..f3e716a3be 100644
--- a/usr/src/uts/common/io/wpi/wpi.c
+++ b/usr/src/uts/common/io/wpi/wpi.c
@@ -269,7 +269,11 @@ static int wpi_m_multicst(void *arg, boolean_t add, const uint8_t *m);
static int wpi_m_promisc(void *arg, boolean_t on);
static mblk_t *wpi_m_tx(void *arg, mblk_t *mp);
static void wpi_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
-
+static int wpi_m_setprop(void *arg, const char *pr_name,
+ mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf);
+static int wpi_m_getprop(void *arg, const char *pr_name,
+ mac_prop_id_t wldp_pr_num, uint_t pr_flags, uint_t wldp_lenth,
+ void *wldp_buf);
static void wpi_destroy_locks(wpi_sc_t *sc);
static int wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
static void wpi_thread(wpi_sc_t *sc);
@@ -358,7 +362,7 @@ _info(struct modinfo *mip)
* Mac Call Back entries
*/
mac_callbacks_t wpi_m_callbacks = {
- MC_IOCTL,
+ MC_IOCTL | MC_SETPROP | MC_GETPROP,
wpi_m_stat,
wpi_m_start,
wpi_m_stop,
@@ -367,7 +371,12 @@ mac_callbacks_t wpi_m_callbacks = {
wpi_m_unicst,
wpi_m_tx,
NULL,
- wpi_m_ioctl
+ wpi_m_ioctl,
+ NULL,
+ NULL,
+ NULL,
+ wpi_m_setprop,
+ wpi_m_getprop
};
#ifdef DEBUG
@@ -2221,6 +2230,44 @@ wpi_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
}
}
+/*
+ * Callback functions for get/set properties
+ */
+static int
+wpi_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
+ uint_t pr_flags, uint_t wldp_length, void *wldp_buf)
+{
+ int err = 0;
+ wpi_sc_t *sc = (wpi_sc_t *)arg;
+
+ err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_name,
+ pr_flags, wldp_length, wldp_buf);
+
+ return (err);
+}
+static int
+wpi_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
+ uint_t wldp_length, const void *wldp_buf)
+{
+ int err;
+ wpi_sc_t *sc = (wpi_sc_t *)arg;
+ ieee80211com_t *ic = &sc->sc_ic;
+
+ err = ieee80211_setprop(ic, pr_name, wldp_pr_name,
+ wldp_length, wldp_buf);
+
+ if (err == ENETRESET) {
+ if (ic->ic_des_esslen) {
+ (void) ieee80211_new_state(ic,
+ IEEE80211_S_SCAN, -1);
+ }
+
+ err = 0;
+ }
+
+ return (err);
+}
+
/*ARGSUSED*/
static int
wpi_m_stat(void *arg, uint_t stat, uint64_t *val)
diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h
index bc930dfce2..ff57a7a1d4 100644
--- a/usr/src/uts/common/sys/mac.h
+++ b/usr/src/uts/common/sys/mac.h
@@ -131,6 +131,28 @@ typedef enum {
MAC_PROP_EN_10HDX_CAP,
MAC_PROP_ADV_100T4_CAP,
MAC_PROP_EN_100T4_CAP,
+ MAC_PROP_WL_ESSID,
+ MAC_PROP_WL_BSSID,
+ MAC_PROP_WL_BSSTYPE,
+ MAC_PROP_WL_LINKSTATUS,
+ MAC_PROP_WL_DESIRED_RATES,
+ MAC_PROP_WL_SUPPORTED_RATES,
+ MAC_PROP_WL_AUTH_MODE,
+ MAC_PROP_WL_ENCRYPTION,
+ MAC_PROP_WL_RSSI,
+ MAC_PROP_WL_PHY_CONFIG,
+ MAC_PROP_WL_CAPABILITY,
+ MAC_PROP_WL_WPA,
+ MAC_PROP_WL_SCANRESULTS,
+ MAC_PROP_WL_POWER_MODE,
+ MAC_PROP_WL_RADIO,
+ MAC_PROP_WL_ESS_LIST,
+ MAC_PROP_WL_KEY_TAB,
+ MAC_PROP_WL_CREATE_IBSS,
+ MAC_PROP_WL_SETOPTIE,
+ MAC_PROP_WL_DELKEY,
+ MAC_PROP_WL_KEY,
+ MAC_PROP_WL_MLME,
MAC_PROP_PRIVATE = -1
} mac_prop_id_t;
diff --git a/usr/src/uts/common/sys/net80211.h b/usr/src/uts/common/sys/net80211.h
index 39d6abdf6f..09619aaa77 100644
--- a/usr/src/uts/common/sys/net80211.h
+++ b/usr/src/uts/common/sys/net80211.h
@@ -38,8 +38,6 @@
#ifndef _SYS_NET80211_H
#define _SYS_NET80211_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/mac.h>
#include <sys/ethernet.h>
#include <sys/net80211_proto.h>
@@ -538,6 +536,10 @@ void ieee80211_stop_watchdog(ieee80211com_t *);
void *ieee80211_malloc(size_t);
void ieee80211_free(void *);
+int ieee80211_setprop(void *, const char *, mac_prop_id_t, uint_t,
+ const void *);
+int ieee80211_getprop(void *, const char *, mac_prop_id_t, uint_t, uint_t,
+ void *);
#ifdef __cplusplus
}