/*
 * Performs the sequence necessary to read a config/info item.
 *
 * Arguments:
 *	hw		device structure
 *	rid		config/info record id (host order)
 *	buf		host side record buffer.  Upon return it will
 *			contain the body portion of the record (minus the
 *			RID and len).
 *	len		buffer length (in bytes, should match record length)
 *
 * Returns:
 *	0		success
 */
static int hfa384x_drvr_getconfig(hfa384x_t *hw, uint16_t rid, void *buf, uint16_t len)
{
  int result = 0;
  hfa384x_rec_t	rec;

  /* Request read of RID */
  result = hfa384x_cmd_access( hw, 0, rid);
  if ( result ) {
    printf("Call to hfa384x_cmd_access failed\n");
    return -1;
  }
  /* Copy out record length */
  result = hfa384x_copy_from_bap( hw, rid, 0, &rec, sizeof(rec));
  if ( result ) {
    return -1;
  }
  /* Validate the record length */
  if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) {  /* note body len calculation in bytes */
    printf ( "RID len mismatch, rid=%#hx hlen=%d fwlen=%d\n", rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
    return -1;
  }
  /* Copy out record data */
  result = hfa384x_copy_from_bap( hw, rid, sizeof(rec), buf, len);
  return result;
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int prism2_poll(struct nic *nic, int retrieve)
{
  uint16_t reg;
  uint16_t rxfid;
  uint16_t result;
  hfa384x_rx_frame_t rxdesc;
  hfa384x_t *hw = &hw_global;

  /* Check for received packet */
  reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
  if ( ! HFA384x_EVSTAT_ISRX(reg) ) {
    /* No packet received - return 0 */
    return 0;
  }

  if ( ! retrieve ) return 1;

  /* Acknowledge RX event */
  hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), HFA384x_EVACK);
  /* Get RX FID */
  rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
  /* Get the descriptor (including headers) */
  result = hfa384x_copy_from_bap(hw, rxfid, 0, &rxdesc, sizeof(rxdesc));
  if ( result ) {
    return 0; /* fail */
  }
  /* Byte order convert once up front. */
  rxdesc.status = hfa384x2host_16(rxdesc.status);
  rxdesc.time = hfa384x2host_32(rxdesc.time);
  rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);

  /* Fill in nic->packetlen */
  nic->packetlen = rxdesc.data_len;
  if ( nic->packetlen > 0 ) {
    /* Fill in nic->packet */
    /*
     * NOTE: Packets as received have an 8-byte header (LLC+SNAP(?)) terminating with the packet type.
     * Etherboot expects a 14-byte header terminating with the packet type (it ignores the rest of the
     * header), so we use a quick hack to achieve this.
     */
    result = hfa384x_copy_from_bap(hw, rxfid, HFA384x_RX_DATA_OFF,
				   nic->packet + ETH_HLEN - sizeof(wlan_80211hdr_t), nic->packetlen);
    if ( result ) {
      return 0; /* fail */
    }
  }
  return 1; /* Packet successfully received */
}
/*
 * Performs the sequence necessary to read a 16/32 bit config/info item
 * and convert it to host order.
 *
 * Arguments:
 *	hw		device structure
 *	rid		config/info record id (in host order)
 *	val		ptr to 16/32 bit buffer to receive value (in host order)
 *
 * Returns:
 *	0		success
 */
#if 0 /* Not actually used anywhere */
static int hfa384x_drvr_getconfig16(hfa384x_t *hw, uint16_t rid, void *val)
{
  int result = 0;
  result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(uint16_t));
  if ( result == 0 ) {
    *((uint16_t*)val) = hfa384x2host_16(*((uint16_t*)val));
  }
  return result;
}
Exemple #4
0
/*
 * Performs the sequence necessary to read a 16/32 bit config/info item
 * and convert it to host order.
 *
 * Arguments:
 *	hw		device structure
 *	rid		config/info record id (in host order)
 *	val		ptr to 16/32 bit buffer to receive value (in host order)
 *
 * Returns: 
 *	0		success
 */
#if 0 /* Not actually used anywhere */
static int hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val)
{
  int result = 0;
  result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16));
  if ( result == 0 ) {
    *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val));
  }
  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;
}