--- sys/dev/if_ndis/if_ndis.c.orig Wed Oct 27 17:01:55 2004 +++ sys/dev/if_ndis/if_ndis.c Wed Oct 27 21:10:18 2004 @@ -2011,7 +2011,9 @@ ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct wi_apinfo *api; - int error, i, j, len, maxaps; + struct wi_scan_p2_hdr *p2; + struct wi_scan_res *res; + int error, i, j, k, len, maxaps; sc = ifp->if_softc; ifr = (struct ifreq *)data; @@ -2070,6 +2072,69 @@ api++; wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); } + free(bl, M_DEVBUF); + error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); + break; + case WI_RID_SCAN_RES: + len = 0; + error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, + NULL, &len); + if (error == 0) + tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); + len = 0; + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); + if (error != ENOSPC) + break; + bl = malloc(len, M_DEVBUF, M_WAITOK|M_ZERO); + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error) { + free(bl, M_DEVBUF); + break; + } + + k = 0; + p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; + res = (void *)&p2[1]; + wb = bl->nblx_bssid; + while ((caddr_t)(res + 1) < (caddr_t)(&wreq + 1) && k < bl->nblx_items) { + bzero(res, sizeof(*res)); + bcopy(&wb->nwbx_macaddr, &res->wi_bssid, + sizeof(res->wi_bssid)); + res->wi_ssid_len = wb->nwbx_ssid.ns_ssidlen; + bcopy(&wb->nwbx_ssid.ns_ssid, &res->wi_ssid, res->wi_ssid_len); + if (wb->nwbx_privacy) { + res->wi_capinfo |= IEEE80211_CAPINFO_PRIVACY; + } + /* XXX Where can we get noise information? */ + res->wi_signal = wb->nwbx_rssi + 149; /* XXX */ + res->wi_chan = + ieee80211_mhz2ieee(wb->nwbx_config.nc_dsconfig / + 1000, 0); + /* In "auto" infrastructure mode, this is useless. */ + if (wb->nwbx_netinfra == NDIS_80211_NET_INFRA_IBSS) + res->wi_capinfo |= IEEE80211_CAPINFO_IBSS; + if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) { + j = sizeof(ndis_80211_rates_ex); + /* handle other extended things */ + } else + j = sizeof(ndis_80211_rates); + for (i = res->wi_rate = 0; i < j; i++) + res->wi_rate = MAX(res->wi_rate, + wb->nwbx_supportedrates[i]); + memcpy(res->wi_srates, wb->nwbx_supportedrates, + MIN(j, 10)); + if (j < 10) + res->wi_srates[j] = 0; + res->wi_rsvd = 0; + res++; + wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); + k++; + } + p2->wi_rsvd = 0; + p2->wi_reason = k; + wreq.wi_len = (sizeof(*p2) + sizeof(*res) * k) / 2; + /* XXX: this is _so_ hackish, should probably be fixed in wicontrol */ + wreq.wi_len++; free(bl, M_DEVBUF); error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); break;