Esempio n. 1
0
/*----------------------------------------------------------------
 * prism2mgmt_scan_results
 *
 * Retrieve the BSS description for one of the BSSs identified in
 * a scan.
 *
 * Arguments:
 *	wlandev		wlan device structure
 *	msgp		ptr to msg buffer
 *
 * Returns:
 *	0	success and done
 *	<0	success, but we're waiting for something to finish.
 *	>0	an error occurred while handling the message.
 * Side effects:
 *
 * Call context:
 *	process thread  (usually)
 *	interrupt
 *----------------------------------------------------------------
 */
int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp)
{
	int result = 0;
	struct p80211msg_dot11req_scan_results *req;
	struct hfa384x *hw = wlandev->priv;
	struct hfa384x_hscan_result_sub *item = NULL;

	int count;

	req = msgp;

	req->resultcode.status = P80211ENUM_msgitem_status_data_ok;

	if (!hw->scanresults) {
		netdev_err(wlandev->netdev,
			   "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
		result = 2;
		req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
		goto exit;
	}

	count = (hw->scanresults->framelen - 3) / 32;
	if (count > HFA384x_SCANRESULT_MAX)
		count = HFA384x_SCANRESULT_MAX;

	if (req->bssindex.data >= count) {
		netdev_dbg(wlandev->netdev,
			   "requested index (%d) out of range (%d)\n",
			   req->bssindex.data, count);
		result = 2;
		req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
		goto exit;
	}

	item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
	/* signal and noise */
	req->signal.status = P80211ENUM_msgitem_status_data_ok;
	req->noise.status = P80211ENUM_msgitem_status_data_ok;
	req->signal.data = le16_to_cpu(item->sl);
	req->noise.data = le16_to_cpu(item->anl);

	/* BSSID */
	req->bssid.status = P80211ENUM_msgitem_status_data_ok;
	req->bssid.data.len = WLAN_BSSID_LEN;
	memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);

	/* SSID */
	req->ssid.status = P80211ENUM_msgitem_status_data_ok;
	req->ssid.data.len = le16_to_cpu(item->ssid.len);
	req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN);
	memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);

	/* supported rates */
	for (count = 0; count < 10; count++)
		if (item->supprates[count] == 0)
			break;

#define REQBASICRATE(N) \
	do { \
		if ((count >= N) && DOT11_RATE5_ISBASIC_GET( \
			item->supprates[(N) - 1])) { \
			req->basicrate ## N .data = item->supprates[(N) - 1]; \
			req->basicrate ## N .status = \
				P80211ENUM_msgitem_status_data_ok; \
		} \
	} while (0)

	REQBASICRATE(1);
	REQBASICRATE(2);
	REQBASICRATE(3);
	REQBASICRATE(4);
	REQBASICRATE(5);
	REQBASICRATE(6);
	REQBASICRATE(7);
	REQBASICRATE(8);

#define REQSUPPRATE(N) \
	do { \
		if (count >= N) { \
			req->supprate ## N .data = item->supprates[(N) - 1]; \
			req->supprate ## N .status = \
				P80211ENUM_msgitem_status_data_ok; \
		} \
	} while (0)

	REQSUPPRATE(1);
	REQSUPPRATE(2);
	REQSUPPRATE(3);
	REQSUPPRATE(4);
	REQSUPPRATE(5);
	REQSUPPRATE(6);
	REQSUPPRATE(7);
	REQSUPPRATE(8);

	/* beacon period */
	req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
	req->beaconperiod.data = le16_to_cpu(item->bcnint);

	/* timestamps */
	req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
	req->timestamp.data = jiffies;
	req->localtime.status = P80211ENUM_msgitem_status_data_ok;
	req->localtime.data = jiffies;

	/* atim window */
	req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
	req->ibssatimwindow.data = le16_to_cpu(item->atim);

	/* Channel */
	req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
	req->dschannel.data = le16_to_cpu(item->chid);

	/* capinfo bits */
	count = le16_to_cpu(item->capinfo);
	req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
	req->capinfo.data = count;

	/* privacy flag */
	req->privacy.status = P80211ENUM_msgitem_status_data_ok;
	req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);

	/* cfpollable */
	req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
	req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);

	/* cfpollreq */
	req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
	req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);

	/* bsstype */
	req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
	req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
	    P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;

	result = 0;
	req->resultcode.data = P80211ENUM_resultcode_success;

exit:
	return result;
}
/*----------------------------------------------------------------
* prism2mgmt_scan_results
*
* Retrieve the BSS description for one of the BSSs identified in
* a scan.
*
* Arguments:
*	wlandev		wlan device structure
*	msgp		ptr to msg buffer
*
* Returns:
*	0	success and done
*	<0	success, but we're waiting for something to finish.
*	>0	an error occurred while handling the message.
* Side effects:
*
* Call context:
*	process thread  (usually)
*	interrupt
----------------------------------------------------------------*/
int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
{
    int 			result = 0;
    p80211msg_dot11req_scan_results_t       *req;
    hfa384x_t		*hw = wlandev->priv;
    hfa384x_HScanResultSub_t *item = NULL;

    int count;

    DBFENTER;

    req = (p80211msg_dot11req_scan_results_t *) msgp;

    req->resultcode.status = P80211ENUM_msgitem_status_data_ok;

    if (! hw->scanresults) {
        WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
        result = 2;
        req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
        goto exit;
    }

    count = (hw->scanresults->framelen - 3) / 32;
    if (count > 32)  count = 32;

    if (req->bssindex.data >= count) {
        WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
                       req->bssindex.data, count);
        result = 2;
        req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
        goto exit;
    }

    item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
    /* signal and noise */
    req->signal.status = P80211ENUM_msgitem_status_data_ok;
    req->noise.status = P80211ENUM_msgitem_status_data_ok;
    req->signal.data = hfa384x2host_16(item->sl);
    req->noise.data = hfa384x2host_16(item->anl);

    /* BSSID */
    req->bssid.status = P80211ENUM_msgitem_status_data_ok;
    req->bssid.data.len = WLAN_BSSID_LEN;
    memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);

    /* SSID */
    req->ssid.status = P80211ENUM_msgitem_status_data_ok;
    req->ssid.data.len = hfa384x2host_16(item->ssid.len);
    memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);

    /* supported rates */
    for (count = 0; count < 10 ; count++)
        if (item->supprates[count] == 0)
            break;

#define REQBASICRATE(N) \
	if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
		req->basicrate ## N .data = item->supprates[(N)-1]; \
		req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
	}

    REQBASICRATE(1);
    REQBASICRATE(2);
    REQBASICRATE(3);
    REQBASICRATE(4);
    REQBASICRATE(5);
    REQBASICRATE(6);
    REQBASICRATE(7);
    REQBASICRATE(8);

#define REQSUPPRATE(N) \
	if (count >= N) { \
		req->supprate ## N .data = item->supprates[(N)-1]; \
		req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
	}

    REQSUPPRATE(1);
    REQSUPPRATE(2);
    REQSUPPRATE(3);
    REQSUPPRATE(4);
    REQSUPPRATE(5);
    REQSUPPRATE(6);
    REQSUPPRATE(7);
    REQSUPPRATE(8);

    /* beacon period */
    req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
    req->beaconperiod.data = hfa384x2host_16(item->bcnint);

    /* timestamps */
    req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
    req->timestamp.data = jiffies;
    req->localtime.status = P80211ENUM_msgitem_status_data_ok;
    req->localtime.data = jiffies;

    /* atim window */
    req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
    req->ibssatimwindow.data = hfa384x2host_16(item->atim);

    /* Channel */
    req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
    req->dschannel.data = hfa384x2host_16(item->chid);

    /* capinfo bits */
    count = hfa384x2host_16(item->capinfo);

    /* privacy flag */
    req->privacy.status = P80211ENUM_msgitem_status_data_ok;
    req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);

    /* cfpollable */
    req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
    req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);

    /* cfpollreq */
    req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
    req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);

    /* bsstype */
    req->bsstype.status =  P80211ENUM_msgitem_status_data_ok;
    req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
                        P80211ENUM_bsstype_infrastructure :
                        P80211ENUM_bsstype_independent;

    // item->proberesp_rate
    /*
    	req->fhdwelltime
    	req->fhhopset
    	req->fhhoppattern
    	req->fhhopindex
            req->cfpdurremaining
    */

    result = 0;
    req->resultcode.data = P80211ENUM_resultcode_success;

exit:
    DBFEXIT;
    return result;
}