/** 
 *  @brief This function sets the MAC address to firmware.
 *  
 *  @param dev     A pointer to wlan_private structure
 *  @param addr    MAC address to set
 *  @return        WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int
wlan_set_mac_address(struct net_device *dev, void *addr)
{
    int ret = WLAN_STATUS_SUCCESS;
    wlan_private *priv = (wlan_private *) netdev_priv(dev);
    wlan_adapter *Adapter = priv->adapter;
    struct sockaddr *pHwAddr = (struct sockaddr *) addr;

    ENTER();

    memset(Adapter->CurrentAddr, 0, ETH_ALEN);

    /* dev->dev_addr is 8 bytes */
    HEXDUMP("dev->dev_addr:", dev->dev_addr, ETH_ALEN);

    HEXDUMP("addr:", pHwAddr->sa_data, ETH_ALEN);
    memcpy(Adapter->CurrentAddr, pHwAddr->sa_data, ETH_ALEN);

    ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
                           HostCmd_ACT_GEN_SET,
                           HostCmd_OPTION_WAITFORRSP, 0, NULL);

    if (ret) {
        PRINTM(INFO, "set mac address failed\n");
        ret = WLAN_STATUS_FAILURE;
        goto done;
    }

    HEXDUMP("Adapter->MacAddr:", Adapter->CurrentAddr, ETH_ALEN);
    memcpy(dev->dev_addr, Adapter->CurrentAddr, ETH_ALEN);

  done:
    LEAVE();
    return ret;
}
Esempio n. 2
0
/**
 *  @brief Handle the command response from the firmware if from an 11h command
 *
 *  Use the Command field to determine if the command response being
 *    is for 11h.  Call the local command response handler accordingly for:
 *
 *        - HostCmd_CMD_802_11_TPC_ADAPT_REQ
 *        - HostCmd_CMD_802_11_TPC_INFO
 *        - HostCmd_CMD_802_11_CHAN_SW_ANN
 *
 *  @param priv  Private driver information structure
 *  @param resp  HostCmd_DS_COMMAND struct returned from the firmware
 *               command
 *
 *  @return      MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
int
wlan_11h_cmdresp_process(mlan_private * priv, const HostCmd_DS_COMMAND * resp)
{
    int ret = MLAN_STATUS_SUCCESS;

    ENTER();
    switch (resp->command) {
    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
        HEXDUMP("11h: TPC REQUEST Rsp:", (t_u8 *) resp, (int) resp->size);
        memcpy(priv->adapter->curr_cmd->pdata_buf,
               &resp->params.tpc_req, sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ));
        break;

    case HostCmd_CMD_802_11_TPC_INFO:
        HEXDUMP("11h: TPC INFO Rsp Data:", (t_u8 *) resp, (int) resp->size);
        break;

    case HostCmd_CMD_802_11_CHAN_SW_ANN:
        PRINTM(MINFO, "11h: Ret ChSwAnn: Sz=%u, Seq=%u, Ret=%u\n",
               resp->size, resp->seq_num, resp->result);
        break;

    default:
        ret = MLAN_STATUS_FAILURE;
    }
    LEAVE();
    return ret;
}
Esempio n. 3
0
/**
 *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure of
 *                        command buffer
 *  @param cmd_action   Command action
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_802_11d_domain_info(mlan_private * pmpriv,
			     HostCmd_DS_COMMAND * pcmd, t_u16 cmd_action)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	HostCmd_DS_802_11D_DOMAIN_INFO *pdomain_info =
		&pcmd->params.domain_info;
	MrvlIEtypes_DomainParamSet_t *domain = &pdomain_info->domain;
	t_u8 no_of_sub_band = pmadapter->domain_reg.no_of_sub_band;

	ENTER();

	PRINTM(MINFO, "11D: number of sub-band=0x%x\n", no_of_sub_band);

	pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
	pdomain_info->action = wlan_cpu_to_le16(cmd_action);
	if (cmd_action == HostCmd_ACT_GEN_GET) {
		/* Dump domain info */
		pcmd->size =
			wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					 S_DS_GEN);
		HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
			wlan_le16_to_cpu(pcmd->size));
		LEAVE();
		return MLAN_STATUS_SUCCESS;
	}

	/* Set domain info fields */
	domain->header.type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN);
	memcpy(pmadapter, domain->country_code,
	       pmadapter->domain_reg.country_code,
	       sizeof(domain->country_code));

	domain->header.len =
		((no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t)) +
		 sizeof(domain->country_code));

	if (no_of_sub_band) {
		memcpy(pmadapter, domain->sub_band,
		       pmadapter->domain_reg.sub_band,
		       MIN(MRVDRV_MAX_SUBBAND_802_11D,
			   no_of_sub_band) * sizeof(IEEEtypes_SubbandSet_t));

		pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					      domain->header.len +
					      sizeof(MrvlIEtypesHeader_t) +
					      S_DS_GEN);
	} else {
		pcmd->size =
			wlan_cpu_to_le16(sizeof(pdomain_info->action) +
					 S_DS_GEN);
	}
	domain->header.len = wlan_cpu_to_le16(domain->header.len);

	HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
		wlan_le16_to_cpu(pcmd->size));

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}
Esempio n. 4
0
dc_status_t
atomics_cobalt_device_version (dc_device_t *abstract, unsigned char data[], unsigned int size)
{
	atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract;

	if (!ISINSTANCE (abstract))
		return DC_STATUS_INVALIDARGS;

	if (size < SZ_VERSION)
		return DC_STATUS_INVALIDARGS;

#ifdef HAVE_LIBUSB
	// Send the command to the dive computer.
	uint8_t bRequest = 0x01;
	int rc = libusb_control_transfer (device->handle,
		LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
		bRequest, 0, 0, NULL, 0, TIMEOUT);
	if (rc != LIBUSB_SUCCESS) {
		ERROR (abstract->context, "Failed to send the command.");
		return EXITCODE(rc);
	}

	HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Write", &bRequest, 1);

	// Receive the answer from the dive computer.
	int length = 0;
	unsigned char packet[SZ_VERSION + 2] = {0};
	rc = libusb_bulk_transfer (device->handle, 0x82,
		packet, sizeof (packet), &length, TIMEOUT);
	if (rc != LIBUSB_SUCCESS || length != sizeof (packet)) {
		ERROR (abstract->context, "Failed to receive the answer.");
		return EXITCODE(rc);
	}

	HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Read", packet, length);

	// Verify the checksum of the packet.
	unsigned short crc = array_uint16_le (packet + SZ_VERSION);
	unsigned short ccrc = checksum_add_uint16 (packet, SZ_VERSION, 0x0);
	if (crc != ccrc) {
		ERROR (abstract->context, "Unexpected answer checksum.");
		return DC_STATUS_PROTOCOL;
	}

	memcpy (data, packet, SZ_VERSION);

	return DC_STATUS_SUCCESS;
#else
	return DC_STATUS_UNSUPPORTED;
#endif
}
/**
 *  @brief This function sorts parsed_region_chan in ascending
 *  channel number.
 *
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
 *
 *  @return                     N/A
 */
static t_void
wlan_11d_sort_parsed_region_chan(parsed_region_chan_11d_t * parsed_region_chan)
{
    int i, j;
    chan_power_11d_t temp;
    chan_power_11d_t *pchan_power = parsed_region_chan->chan_pwr;

    ENTER();

    PRINTM(MINFO, "11D: Number of channel = %d\n",
           parsed_region_chan->no_of_chan);

    // Use insertion sort method
    for (i = 1; i < parsed_region_chan->no_of_chan; i++) {
        wlan_11d_copy_chan_power(&temp, pchan_power + i);
        for (j = i; j > 0 && (pchan_power + j - 1)->chan > temp.chan; j--)
            wlan_11d_copy_chan_power(pchan_power + j, pchan_power + j - 1);
        wlan_11d_copy_chan_power(pchan_power + j, &temp);
    }

    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
            sizeof(parsed_region_chan_11d_t));

    LEAVE();
    return;
}
Esempio n. 6
0
/**
 *  @brief Prepare CMD_802_11_TPC_INFO firmware command
 *
 *  @param priv      Private driver information structure
 *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
 *                   for the firmware
 *  @param pinfo_buf wlan_11h_tpc_info_param_t passed as void data block
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static int
wlan_11h_cmd_tpc_info(mlan_private * priv,
                      HostCmd_DS_COMMAND * pcmd_ptr, const t_void * pinfo_buf)
{
    HostCmd_DS_802_11_TPC_INFO *ptpc_info = &pcmd_ptr->params.tpc_info;
    MrvlIEtypes_LocalPowerConstraint_t *pconstraint =
        &ptpc_info->local_constraint;
    MrvlIEtypes_PowerCapability_t *pcap = &ptpc_info->power_cap;

    wlan_11h_state_t *pstate = &priv->adapter->state_11h;
    const wlan_11h_tpc_info_param_t *ptpc_info_param =
        (wlan_11h_tpc_info_param_t *) pinfo_buf;

    ENTER();

    pcap->min_power = pstate->min_tx_power_capability;
    pcap->max_power = pstate->max_tx_power_capability;
    pcap->header.len = wlan_cpu_to_le16(2);
    pcap->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CAPABILITY);

    pconstraint->chan = ptpc_info_param->chan;
    pconstraint->constraint = ptpc_info_param->power_constraint;
    pconstraint->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CONSTRAINT);
    pconstraint->header.len = wlan_cpu_to_le16(2);

    /* Converted to little endian in wlan_11h_cmd_process */
    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_INFO) + S_DS_GEN;

    HEXDUMP("11h: TPC INFO", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);

    LEAVE();

    return MLAN_STATUS_SUCCESS;
}
Esempio n. 7
0
/** 
 *  @brief This function Checks if channel txpwr is learned from AP/IBSS
 *
 *  @param pmadapter            A pointer to mlan_adapter structure
 *  @param chan                 Channel number
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
 *
 *  @return                     MTRUE or MFALSE
 */
static t_u8
wlan_11d_channel_known(pmlan_adapter pmadapter,
                       t_u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
{
    chan_power_11d_t *pchan_pwr = parsed_region_chan->chan_pwr;
    t_u8 no_of_chan = parsed_region_chan->no_of_chan;
    t_u8 i = 0;

    ENTER();

    HEXDUMP("11D: parsed_region_chan", (t_u8 *) pchan_pwr,
            sizeof(chan_power_11d_t) * no_of_chan);

    /* Search channel */
    for (i = 0; i < no_of_chan; i++) {
        if (chan == pchan_pwr[i].chan) {
            PRINTM(MINFO, "11D: Found channel:%d\n", chan);
            LEAVE();
            return MTRUE;
        }
    }

    PRINTM(MINFO, "11D: Could not find channel:%d\n", chan);
    LEAVE();
    return MFALSE;
}
Esempio n. 8
0
/** 
 *  @brief This function sets the MAC address to firmware.
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @param pRxPD   A pointer to RxPD structure of received packet
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int
wlan_set_mac_address(struct eth_drv_sc *sc, void *addr)
{
    int ret = WLAN_STATUS_SUCCESS;
    wlan_private *priv = (wlan_private *) sc->driver_private;
    wlan_adapter *Adapter = priv->adapter;
//    struct sockaddr *pHwAddr = (struct sockaddr *) addr;

    ENTER();

    memset(Adapter->CurrentAddr, 0, MRVDRV_ETH_ADDR_LEN);

    /* dev->dev_addr is 8 bytes */
//    HEXDUMP("dev->dev_addr:", dev->dev_addr, ETH_ALEN);

    //HEXDUMP("addr:", pHwAddr->sa_data, ETH_ALEN);
    memcpy(Adapter->CurrentAddr, addr, ETH_ALEN);

    ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
                                HostCmd_ACT_SET,
                                HostCmd_OPTION_WAITFORRSP, 0, NULL);

    if (ret) {
        diag_printf("set mac address failed.\n");
        ret = WLAN_STATUS_FAILURE;
        goto done;
    }

    HEXDUMP("Adapter->MacAddr:", Adapter->CurrentAddr, ETH_ALEN);
   // memcpy(dev->dev_addr, Adapter->CurrentAddr, ETH_ALEN);

  done:
    LEAVE();
    return ret;
}
Esempio n. 9
0
void cSystemIrd2::ProcessEMM(int pid, int caid, const unsigned char *data)
{
  int prov=0; //XXX how to get provider here??

  int len=SCT_LEN(data);
  unsigned char *emm=AUTOMEM(len);

  cPlainKey *pk;
  if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_IV,0),16))) {
    PRINTF(L_SYS_EMM,"missing %04x %02x IV key",caid,prov);
    return;
    }
  unsigned char EMM_IV[16];
  pk->Get(EMM_IV);

  for(int keyno=0; keyno<2; keyno++) {
    if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_PMK,keyno),16))) {
      PRINTF(L_SYS_EMM,"missing %04x %02x MK%d key",caid,prov,keyno);
      continue;
      }
    unsigned char PMK[16];
    pk->Get(PMK);

    if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_SEED,1),16))) {
      PRINTF(L_SYS_EMM,"missing %04x %02x EMM key",caid,prov);
      return;
      }
    unsigned char EMM_Seed[16];
    pk->Get(EMM_Seed);
    PrepareSeed(EMM_Seed,PMK);

    memcpy(emm,data,len);
    Decrypt(&emm[10],EMM_IV,EMM_Seed,len-10);
    NanoDecrypt(emm,16,len-8,PMK,EMM_IV);
    memmove(emm+6,emm+7,len-7); // removing padding byte
    if(CalculateHash(EMM_Seed,EMM_IV,emm+3,len-4)) {
      HEXDUMP(L_SYS_RAWEMM,emm,len,"Irdeto2 RAWEMM");
      for(int i=15; i<len-9;) {
        int l=NANOLEN(emm[i+1]);
        switch(emm[i]) {
          case 0x10:
          case 0x50:
            if(l==0x13 && i+l<=len-9) {
              FoundKey();
              if(keys.NewKey('I',caid,KEYSET(prov,TYPE_OP,emm[i+2]>>2),&emm[i+3],16)) NewKey();
              }
            break;
          }
        i+=l;
        }
      break;
      }
Esempio n. 10
0
void cLogger::Process(cPidFilter *filter, unsigned char *data, int len)
{
  if(data && len>0) {
    if(filter==catfilt) {
      int vers=(data[5]&0x3E)>>1;
      if(data[0]==0x01 && vers!=catVers) {
        PRINTF(L_CORE_AUEXTRA,"%d: got CAT version %02x",cardNum,vers);
        catVers=vers;
        HEXDUMP(L_HEX_CAT,data,len,"CAT vers %02x",catVers);
        ClearChains();
        ProcessCat(&data[8],len-4-8);
        unsigned char buff[2048];
        if((len=overrides.GetCat(source,transponder,buff,sizeof(buff)))>0) {
          HEXDUMP(L_HEX_CAT,buff,len,"override CAT");
          ProcessCat(buff,len);
          }
        SetChains();
        if(prescan==pmStart) { prescan=pmWait; pretime.Set(2000); }
        }
      if(prescan==pmWait && pretime.TimedOut()) { prescan=pmActive; SetChains(); }
      }
    else {
Esempio n. 11
0
bool cSystemIrd2::ProcessECM(const cEcmInfo *ecm, unsigned char *data)
{
  int len=data[11];
  if(len!=0x28 || SCT_LEN(data)<len+12) {
    if(doLog) PRINTF(L_SYS_ECM,"bad ECM length");
    return false;
    }
  int prov=data[8];
  cPlainKey *pk;
  unsigned char ECM_IV[16];
  if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_IV,0),16))) {
    if(doLog) PRINTF(L_SYS_KEY,"missing %04x %02x IV key",ecm->caId,prov);
    return false;
    }
  pk->Get(ECM_IV);

  unsigned char ECM_Seed[16];
  if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_SEED,0),16))) {
    if(doLog) PRINTF(L_SYS_KEY,"missing %04x %02x ECM key",ecm->caId,prov);
    return false;
    }
  pk->Get(ECM_Seed);

  cKeySnoop ks(this,'I',ecm->caId,KEYSET(prov,TYPE_OP,data[9]));
  unsigned char key[16];
  if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_OP,data[9]),16))) return false;
  pk->Get(key);
  PrepareSeed(ECM_Seed,key);

  data+=12;
  Decrypt(data,ECM_IV,ECM_Seed,len);
  int i=(data[0]&7)+1;
  NanoDecrypt(data,i,len-8,key,ECM_IV);
  if(CalculateHash(ECM_Seed,ECM_IV,data-6,len+6)) {
    HEXDUMP(L_SYS_RAWECM,data-12,len+12,"Irdeto2 RAWECM");
    while(i<len-8) {
      int l=NANOLEN(data[i+1]);
      switch(data[i]) {
        case 0x78:
          memcpy(cw,&data[i+4],16);
          ks.OK(pk);
          return true;
        }
      i+=l;
      }
    }
  else {
    if(doLog) PRINTF(L_SYS_ECM,"hash failed");
    }
  return false;
}
Esempio n. 12
0
/**
 *  @brief Setup the Supported Channel IE sent in association requests
 *
 *  The Supported Channels IE is required to be sent when the spectrum
 *    management capability (11h) is enabled.  The element contains a
 *    starting channel and number of channels tuple for each sub-band
 *    the STA supports.  This information is based on the operating region.
 *
 *  @param priv      Private driver information structure
 *  @param psup_chan Output parameter: Pointer to the Supported Chan element
 *                   setup by this function.
 *
 *  @return
 *    - Length of the returned element in psup_chan output parameter
 *    - 0 if returned element is not setup
 */
static int
wlan_11h_set_supp_channels_ie(mlan_private * priv,
                              IEEEtypes_SupportedChannels_t * psup_chan)
{
    int num_subbands = 0;
    int ret_len = 0;

    ENTER();
    memset(psup_chan, 0x00, sizeof(IEEEtypes_SupportedChannels_t));

    /* 
     * Set the supported channel elements based on the region code,
     *   incrementing num_subbands for each sub-band we append to the
     *   element.
     */
    switch (priv->adapter->region_code) {
    case 0x10:                 /* USA FCC */
    case 0x20:                 /* Canada IC */
        psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band;
        psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band;
        psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band;
        psup_chan->subband[num_subbands++] = wlan_11h_unii_upper_band;
        break;
    case 0x30:                 /* Europe ETSI */
        psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band;
        psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band;
        psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band;
        break;
    default:
        break;
    }

    /* 
     * If we have setup any supported subbands in the element, return a
     *    valid IE along with its size, else return 0.
     */
    if (num_subbands) {
        psup_chan->element_id = SUPPORTED_CHANNELS;
        psup_chan->len = num_subbands * sizeof(IEEEtypes_SupportChan_Subband_t);

        ret_len = (psup_chan->len
                   + sizeof(psup_chan->len) + sizeof(psup_chan->element_id));

        HEXDUMP("11h: SupChan", (t_u8 *) psup_chan, ret_len);
    }

    LEAVE();
    return ret_len;
}
Esempio n. 13
0
/**
 *  @brief This function Checks if channel txpwr is learned from AP/IBSS
 *
 *  @param pmadapter            A pointer to mlan_adapter structure
 *  @param band                 Band number
 *  @param chan                 Channel number
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
 *
 *  @return                     MTRUE or MFALSE
 */
static t_u8
wlan_11d_channel_known(pmlan_adapter pmadapter,
		       t_u8 band,
		       t_u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
{
	chan_power_11d_t *pchan_pwr = parsed_region_chan->chan_pwr;
	t_u8 no_of_chan = parsed_region_chan->no_of_chan;
	t_u8 i = 0;
	t_u8 ret = MFALSE;
	mlan_private *pmpriv;

	ENTER();

	HEXDUMP("11D: parsed_region_chan", (t_u8 *) pchan_pwr,
		sizeof(chan_power_11d_t) * no_of_chan);

	/* Search channel */
	for (i = 0; i < no_of_chan; i++) {
		if (chan == pchan_pwr[i].chan && band == pchan_pwr[i].band) {
			PRINTM(MINFO, "11D: Found channel:%d (band:%d)\n", chan,
			       band);
			ret = MTRUE;

			if (band & BAND_A) {
				/* If chan is a DFS channel, we need to see an
				   AP on it */
				pmpriv = wlan_get_priv(pmadapter,
						       MLAN_BSS_ROLE_STA);
				if (pmpriv &&
				    wlan_11h_radar_detect_required(pmpriv,
								   chan)) {
					PRINTM(MINFO,
					       "11H: DFS channel %d, and ap_seen=%d\n",
					       chan, pchan_pwr[i].ap_seen);
					ret = pchan_pwr[i].ap_seen;
				}
			}

			LEAVE();
			return ret;
		}
	}

	PRINTM(MINFO, "11D: Could not find channel:%d (band:%d)\n", chan, band);
	LEAVE();
	return ret;
}
Esempio n. 14
0
void cHookManager::Process(cPidFilter *filter, unsigned char *data, int len)
{
  if(data && len>0) {
    HEXDUMP(L_HEX_HOOK,data,len,"HOOK pid 0x%04x",filter->Pid());
    if(SCT_LEN(data)==len) {
      cLogHook *hook=(cLogHook *)(filter->userData);
      if(hook) {
        hook->Process(filter->Pid(),data);
        if(hook->bailOut || hook->delay.TimedOut()) DelHook(hook);
        }
      }
    else PRINTF(L_CORE_HOOK,"%d: incomplete section %d != %d",cardNum,len,SCT_LEN(data));
    }
  else {
    cLogHook *hook=(cLogHook *)(filter->userData);
    if(hook && (hook->bailOut || hook->delay.TimedOut())) DelHook(hook);
    }
}
Esempio n. 15
0
/** 
 *  @brief This function handle response of CMD_802_11D_DOMAIN_INFO
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         Pointer to command response buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ret_802_11d_domain_info(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    HostCmd_DS_802_11D_DOMAIN_INFO_RSP *domain_info =
        &resp->params.domain_info_resp;
    MrvlIEtypes_DomainParamSet_t *domain = &domain_info->domain;
    t_u16 action = wlan_le16_to_cpu(domain_info->action);
    t_u8 no_of_sub_band = 0;

    ENTER();

    /* Dump domain info response data */
    HEXDUMP("11D: DOMAIN Info Rsp Data", (t_u8 *) resp, resp->size);

    no_of_sub_band =
        (t_u8) ((wlan_le16_to_cpu(domain->header.len) -
                 3) / sizeof(IEEEtypes_SubbandSet_t));
    /* Country code is 3 bytes */

    PRINTM(MINFO, "11D Domain Info Resp: number of sub-band=%d\n",
           no_of_sub_band);

    if (no_of_sub_band > MRVDRV_MAX_SUBBAND_802_11D) {
        PRINTM(MWARN, "11D: Invalid number of subbands %d returned!!\n",
               no_of_sub_band);
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    switch (action) {
    case HostCmd_ACT_GEN_SET:  /* Proc Set Action */
        break;
    case HostCmd_ACT_GEN_GET:
        break;
    default:
        PRINTM(MERROR, "11D: Invalid Action:%d\n", domain_info->action);
        ret = MLAN_STATUS_FAILURE;
        break;
    }

    LEAVE();
    return ret;
}
Esempio n. 16
0
/**
 *  @brief Prepare CMD_802_11_TPC_ADAPT_REQ firmware command
 *
 *  @param priv      Private driver information structure
 *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared
 *                   for the firmware
 *  @param pinfo_buf HostCmd_DS_802_11_TPC_ADAPT_REQ passed as void data block
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static int
wlan_11h_cmd_tpc_request(mlan_private * priv,
                         HostCmd_DS_COMMAND * pcmd_ptr,
                         const t_void * pinfo_buf)
{
    ENTER();

    memcpy(&pcmd_ptr->params.tpc_req, pinfo_buf,
           sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ));

    pcmd_ptr->params.tpc_req.req.timeout =
        wlan_cpu_to_le16(pcmd_ptr->params.tpc_req.req.timeout);

    /* Converted to little endian in wlan_11h_cmd_process */
    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ) + S_DS_GEN;

    HEXDUMP("11h: 11_TPC_ADAPT_REQ:", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);

    LEAVE();

    return MLAN_STATUS_SUCCESS;
}
Esempio n. 17
0
/** 
 *  @brief Send set MAC address request to MLAN
 *   
 *  @param priv   A pointer to moal_private structure
 *
 *  @return       MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
mlan_status
woal_request_set_mac_address(moal_private * priv)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_MAC_ADDR;
    memcpy(&bss->param.mac_addr, priv->current_addr,
           sizeof(mlan_802_11_mac_addr));
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
        HEXDUMP("priv->MacAddr:", priv->current_addr, ETH_ALEN);
    } else {
        PRINTM(MERROR, "set mac address failed! status=%d, error_code=0x%lx\n",
               status, req->status_code);
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 18
0
/**
 *  @brief This function processes received packet and forwards it
 *  to kernel/upper layer
 *  
 *  @param priv    A pointer to wlan_private
 *  @param skb     A pointer to skb which includes the received packet
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int
ProcessRxedPacket(wlan_private * priv, struct sk_buff *skb)
{
#ifdef WPRM_DRV
    wlan_adapter *Adapter = priv->adapter;
#endif
    int ret = WLAN_STATUS_SUCCESS;

    RxPacketHdr_t *pRxPkt;
    RxPD *pRxPD;

    int hdrChop;
    EthII_Hdr_t *pEthHdr;
    u32 u32SkbLen = skb->len;

    const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };

    ENTER();

    pRxPkt = (RxPacketHdr_t *) skb->data;
    pRxPD = &pRxPkt->rx_pd;

    DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, MAX_DATA_DUMP_LEN));

    if (skb->len < (ETH_HLEN + 8 + sizeof(RxPD))) {
        PRINTM(ERROR, "RX Error: FRAME RECEIVED WITH BAD LENGTH\n");
        priv->stats.rx_length_errors++;
        ret = WLAN_STATUS_SUCCESS;
        kfree_skb(skb);
        goto done;
    }

    PRINTM(INFO, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
           skb->len, sizeof(RxPD), skb->len - sizeof(RxPD));

    HEXDUMP("RX Data: Dest", pRxPkt->eth803_hdr.dest_addr,
            sizeof(pRxPkt->eth803_hdr.dest_addr));
    HEXDUMP("RX Data: Src", pRxPkt->eth803_hdr.src_addr,
            sizeof(pRxPkt->eth803_hdr.src_addr));

    if (memcmp(&pRxPkt->rfc1042_hdr,
               rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
        /* 
         *  Replace the 803 header and rfc1042 header (llc/snap) with an 
         *    EthernetII header, keep the src/dst and snap_type (ethertype)
         *
         *  The firmware only passes up SNAP frames converting
         *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
         *
         *  To create the Ethernet II, just move the src, dst address right
         *    before the snap_type.
         */
        pEthHdr = (EthII_Hdr_t *)
            ((u8 *) & pRxPkt->eth803_hdr
             + sizeof(pRxPkt->eth803_hdr) + sizeof(pRxPkt->rfc1042_hdr)
             - sizeof(pRxPkt->eth803_hdr.dest_addr)
             - sizeof(pRxPkt->eth803_hdr.src_addr)
             - sizeof(pRxPkt->rfc1042_hdr.snap_type));

        memcpy(pEthHdr->src_addr, pRxPkt->eth803_hdr.src_addr,
               sizeof(pEthHdr->src_addr));
        memcpy(pEthHdr->dest_addr, pRxPkt->eth803_hdr.dest_addr,
               sizeof(pEthHdr->dest_addr));

        /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header
         *   that was removed 
         */
        hdrChop = (u8 *) pEthHdr - (u8 *) pRxPkt;
    } else {
        HEXDUMP("RX Data: LLC/SNAP",
                (u8 *) & pRxPkt->rfc1042_hdr, sizeof(pRxPkt->rfc1042_hdr));

        /* Chop off the RxPD */
        hdrChop = (u8 *) & pRxPkt->eth803_hdr - (u8 *) pRxPkt;
    }

    /* Chop off the leading header bytes so the skb points to the start of 
     *   either the reconstructed EthII frame or the 802.2/llc/snap frame
     */
    skb_pull(skb, hdrChop);

    u32SkbLen = skb->len;
    wlan_compute_rssi(priv, pRxPD);

    if (os_upload_rx_packet(priv, skb)) {
        PRINTM(ERROR, "RX Error: os_upload_rx_packet" " returns failure\n");
        ret = WLAN_STATUS_FAILURE;
        goto done;
    }
    priv->stats.rx_bytes += u32SkbLen;
    priv->stats.rx_packets++;

    PRINTM(DATA, "Data => kernel\n");
#ifdef WPRM_DRV
    WPRM_DRV_TRACING_PRINT();
    /* increase traffic meter rx counter 
       and call measurement function to see 
       if we need to change FW power mode. */
    wprm_rx_packet_cnt++;
    wprm_traffic_measurement(priv, Adapter, FALSE);
#endif
    ret = WLAN_STATUS_SUCCESS;
  done:
    LEAVE();

    return (ret);
}
Esempio n. 19
0
/** 
 *  @brief This function parses country information for region channel
 *
 *  @param pmadapter            Pointer to mlan_adapter structure
 *  @param country_info         Country information
 *  @param band                 Chan band
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
 *
 *  @return                     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_parse_domain_info(pmlan_adapter pmadapter,
                           IEEEtypes_CountryInfoFullSet_t * country_info,
                           t_u8 band,
                           parsed_region_chan_11d_t * parsed_region_chan)
{
    t_u8 no_of_sub_band, no_of_chan;
    t_u8 last_chan, first_chan, cur_chan = 0;
    t_u8 idx = 0;
    t_u8 j, i;

    ENTER();

    /* 
     * Validation Rules:
     *    1. Valid Region Code
     *    2. First Chan increment
     *    3. Channel range no overlap
     *    4. Channel is valid?
     *    5. Channel is supported by Region?
     *    6. Others
     */

    HEXDUMP("country_info", (t_u8 *) country_info, 30);

    if (!(*(country_info->country_code)) ||
        (country_info->len <= COUNTRY_CODE_LEN)) {
        /* No region info or wrong region info: treat as no 11D info */
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    /* Step 1: Check region_code */
    parsed_region_chan->region =
        wlan_11d_region_2_code(pmadapter, country_info->country_code);

    PRINTM(MINFO, "11D: region code=0x%x\n", (t_u8) parsed_region_chan->region);
    HEXDUMP("11D: Country Code", (t_u8 *) country_info->country_code,
            COUNTRY_CODE_LEN);

    parsed_region_chan->band = band;

    memcpy(pmadapter, parsed_region_chan->country_code,
           country_info->country_code, COUNTRY_CODE_LEN);

    no_of_sub_band = (country_info->len - COUNTRY_CODE_LEN) /
        sizeof(IEEEtypes_SubbandSet_t);

    for (j = 0, last_chan = 0; j < no_of_sub_band; j++) {

        if (country_info->sub_band[j].first_chan <= last_chan) {
            /* Step2&3: Check First Chan Num increment and no overlap */
            PRINTM(MINFO, "11D: Chan[%d>%d] Overlap\n",
                   country_info->sub_band[j].first_chan, last_chan);
            continue;
        }

        first_chan = country_info->sub_band[j].first_chan;
        no_of_chan = country_info->sub_band[j].no_of_chan;

        for (i = 0; idx < MAX_NO_OF_CHAN && i < no_of_chan; i++) {
            /* Step 4 : Channel is supported? */
            if (wlan_11d_get_chan(pmadapter, band, first_chan, i, &cur_chan) ==
                MFALSE) {
                /* Chan is not found in UN table */
                PRINTM(MWARN, "11D: channel is not supported: %d\n", i);
                break;
            }

            last_chan = cur_chan;

            /* Step 5: We don't need to check if cur_chan is supported by mrvl
               in region */
            parsed_region_chan->chan_pwr[idx].chan = cur_chan;
            parsed_region_chan->chan_pwr[idx].pwr =
                country_info->sub_band[j].max_tx_pwr;
            idx++;
        }

        /* Step 6: Add other checking if any */
    }

    parsed_region_chan->no_of_chan = idx;

    PRINTM(MINFO, "11D: number of channel=0x%x\n",
           parsed_region_chan->no_of_chan);
    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
            2 + COUNTRY_CODE_LEN + sizeof(parsed_region_chan_11d_t) * idx);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 20
0
/** 
 *  @brief This function generates domain_info from parsed_region_chan
 *
 *  @param pmadapter            Pointer to mlan_adapter structure
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
 *  @param domain_info          Pointer to wlan_802_11d_domain_reg_t
 *
 *  @return                     MLAN_STATUS_SUCCESS
 */
static mlan_status
wlan_11d_generate_domain_info(pmlan_adapter pmadapter,
                              parsed_region_chan_11d_t * parsed_region_chan,
                              wlan_802_11d_domain_reg_t * domain_info)
{
    t_u8 no_of_sub_band = 0;
    t_u8 no_of_chan = parsed_region_chan->no_of_chan;
    t_u8 no_of_parsed_chan = 0;
    t_u8 first_chan = 0, next_chan = 0, max_pwr = 0;
    t_u8 i, flag = 0;

    ENTER();

    /* Set country code */
    memcpy(pmadapter, domain_info->country_code,
           parsed_region_chan->country_code, COUNTRY_CODE_LEN);

    PRINTM(MINFO, "11D: Number of channel = %d\n", no_of_chan);
    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
            sizeof(parsed_region_chan_11d_t));

    /* Set channel and power */
    for (i = 0; i < no_of_chan; i++) {
        if (!flag) {
            flag = 1;
            next_chan = first_chan = parsed_region_chan->chan_pwr[i].chan;
            max_pwr = parsed_region_chan->chan_pwr[i].pwr;
            no_of_parsed_chan = 1;
            continue;
        }

        if (parsed_region_chan->chan_pwr[i].chan == next_chan + 1 &&
            parsed_region_chan->chan_pwr[i].pwr == max_pwr) {
            next_chan++;
            no_of_parsed_chan++;
        } else {
            domain_info->sub_band[no_of_sub_band].first_chan = first_chan;
            domain_info->sub_band[no_of_sub_band].no_of_chan =
                no_of_parsed_chan;
            domain_info->sub_band[no_of_sub_band].max_tx_pwr = max_pwr;
            no_of_sub_band++;
            no_of_parsed_chan = 1;
            next_chan = first_chan = parsed_region_chan->chan_pwr[i].chan;
            max_pwr = parsed_region_chan->chan_pwr[i].pwr;
        }
    }

    if (flag) {
        domain_info->sub_band[no_of_sub_band].first_chan = first_chan;
        domain_info->sub_band[no_of_sub_band].no_of_chan = no_of_parsed_chan;
        domain_info->sub_band[no_of_sub_band].max_tx_pwr = max_pwr;
        no_of_sub_band++;
    }
    domain_info->no_of_sub_band = no_of_sub_band;

    PRINTM(MINFO, "11D: Number of sub-band =0x%x\n",
           domain_info->no_of_sub_band);
    HEXDUMP("11D: domain_info", (t_u8 *) domain_info,
            COUNTRY_CODE_LEN + 1 +
            sizeof(IEEEtypes_SubbandSet_t) * no_of_sub_band);
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
/**
 *  @brief This function append the 802_11N tlv
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pbss_desc    A pointer to BSSDescriptor_t structure
 *  @param ppbuffer     A Pointer to command buffer pointer
 *
 *  @return bytes added to the buffer       
 */
int
wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv,
                        IN BSSDescriptor_t * pbss_desc, OUT t_u8 ** ppbuffer)
{
    pmlan_adapter pmadapter = pmpriv->adapter;
    MrvlIETypes_HTCap_t *pht_cap;
    MrvlIETypes_HTInfo_t *pht_info;
    MrvlIEtypes_ChanListParamSet_t *pchan_list;
    MrvlIETypes_2040BSSCo_t *p2040_bss_co;
    MrvlIETypes_ExtCap_t *pext_cap;
    int ret_len = 0;

    ENTER();

    /* Null Checks */
    if (ppbuffer == 0) {
        LEAVE();
        return 0;
    }
    if (*ppbuffer == 0) {
        LEAVE();
        return 0;
    }

    if (pbss_desc->pht_cap) {
        pht_cap = (MrvlIETypes_HTCap_t *) * ppbuffer;
        memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
        pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
        pht_cap->header.len = sizeof(HTCap_t);
        memcpy(pmadapter, (t_u8 *) pht_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pht_cap + sizeof(IEEEtypes_Header_t),
               pht_cap->header.len);

        pht_cap->ht_cap.ht_cap_info =
            wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info);
        wlan_fill_cap_info(pmpriv, pht_cap);
        pht_cap->ht_cap.ht_cap_info =
            wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);

        HEXDUMP("HT_CAPABILITIES IE", (t_u8 *) pht_cap,
                sizeof(MrvlIETypes_HTCap_t));
        *ppbuffer += sizeof(MrvlIETypes_HTCap_t);
        ret_len += sizeof(MrvlIETypes_HTCap_t);
        pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
    }

    if (pbss_desc->pht_info) {
        if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
            pht_info = (MrvlIETypes_HTInfo_t *) * ppbuffer;
            memset(pmadapter, pht_info, 0, sizeof(MrvlIETypes_HTInfo_t));
            pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION);
            pht_info->header.len = sizeof(HTInfo_t);

            memcpy(pmadapter, (t_u8 *) pht_info + sizeof(MrvlIEtypesHeader_t),
                   (t_u8 *) pbss_desc->pht_info + sizeof(IEEEtypes_Header_t),
                   pht_info->header.len);

            if (!ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) ||
                !ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) {
                RESET_CHANWIDTH40(pht_info->ht_info.field2);
            }

            *ppbuffer += sizeof(MrvlIETypes_HTInfo_t);
            ret_len += sizeof(MrvlIETypes_HTInfo_t);
            pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len);
        }

        pchan_list = (MrvlIEtypes_ChanListParamSet_t *) * ppbuffer;
        memset(pmadapter, pchan_list, 0,
               sizeof(MrvlIEtypes_ChanListParamSet_t));
        pchan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
        pchan_list->header.len = sizeof(MrvlIEtypes_ChanListParamSet_t) -
            sizeof(MrvlIEtypesHeader_t);
        pchan_list->chan_scan_param[0].chan_number =
            pbss_desc->pht_info->ht_info.pri_chan;
        pchan_list->chan_scan_param[0].radio_type =
            wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);

        if ((ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) &&
             ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) &&
            ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2))
            SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type,
                              GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
                                                field2));

        HEXDUMP("ChanList", (t_u8 *) pchan_list,
                sizeof(MrvlIEtypes_ChanListParamSet_t));
        HEXDUMP("pht_info", (t_u8 *) pbss_desc->pht_info,
                sizeof(MrvlIETypes_HTInfo_t) - 2);
        *ppbuffer += sizeof(MrvlIEtypes_ChanListParamSet_t);
        ret_len += sizeof(MrvlIEtypes_ChanListParamSet_t);
        pchan_list->header.len = wlan_cpu_to_le16(pchan_list->header.len);
    }

    if (pbss_desc->pbss_co_2040) {
        p2040_bss_co = (MrvlIETypes_2040BSSCo_t *) * ppbuffer;
        memset(pmadapter, p2040_bss_co, 0, sizeof(MrvlIETypes_2040BSSCo_t));
        p2040_bss_co->header.type = wlan_cpu_to_le16(BSSCO_2040);
        p2040_bss_co->header.len = sizeof(BSSCo2040_t);

        memcpy(pmadapter, (t_u8 *) p2040_bss_co + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pbss_co_2040 + sizeof(IEEEtypes_Header_t),
               p2040_bss_co->header.len);

        HEXDUMP("20/40 BSS Coexistence IE", (t_u8 *) p2040_bss_co,
                sizeof(MrvlIETypes_2040BSSCo_t));
        *ppbuffer += sizeof(MrvlIETypes_2040BSSCo_t);
        ret_len += sizeof(MrvlIETypes_2040BSSCo_t);
        p2040_bss_co->header.len = wlan_cpu_to_le16(p2040_bss_co->header.len);
    }

    if (pbss_desc->pext_cap) {
        pext_cap = (MrvlIETypes_ExtCap_t *) * ppbuffer;
        memset(pmadapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
        pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
        pext_cap->header.len = sizeof(ExtCap_t);

        memcpy(pmadapter, (t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t),
               pext_cap->header.len);

        HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap,
                sizeof(MrvlIETypes_ExtCap_t));
        *ppbuffer += sizeof(MrvlIETypes_ExtCap_t);
        ret_len += sizeof(MrvlIETypes_ExtCap_t);
        pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len);
    }

    LEAVE();
    return ret_len;
}
Esempio n. 22
0
/**
 *  @brief This function processes received packet and forwards it
 *  		to kernel/upper layer
 *
 *  @param pmadapter A pointer to mlan_adapter
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	RxPacketHdr_t *prx_pkt;
	RxPD *prx_pd;
	int hdr_chop;
	EthII_Hdr_t *peth_hdr;
	t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] =
		{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
	t_u8 snap_oui_802_h[MLAN_MAC_ADDR_LENGTH] =
		{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
	t_u8 appletalk_aarp_type[2] = { 0x80, 0xf3 };
	t_u8 ipx_snap_type[2] = { 0x81, 0x37 };

	ENTER();

	prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
	prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);

/** Small debug type */
#define DBG_TYPE_SMALL  2
/** Size of debugging structure */
#define SIZE_OF_DBG_STRUCT 4
	if (prx_pd->rx_pkt_type == PKT_TYPE_DEBUG) {
		t_u8 dbgType;
		dbgType = *(t_u8 *) & prx_pkt->eth803_hdr;
		if (dbgType == DBG_TYPE_SMALL) {
			PRINTM(MFW_D, "\n");
			DBG_HEXDUMP(MFW_D, "FWDBG",
				    (char *)((t_u8 *) & prx_pkt->eth803_hdr +
					     SIZE_OF_DBG_STRUCT),
				    prx_pd->rx_pkt_length);
			PRINTM(MFW_D, "FWDBG::\n");
		}
		goto done;
	}

	PRINTM(MINFO,
	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
	       pmbuf->data_len, prx_pd->rx_pkt_offset,
	       pmbuf->data_len - prx_pd->rx_pkt_offset);

	HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
		sizeof(prx_pkt->eth803_hdr.dest_addr));
	HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
		sizeof(prx_pkt->eth803_hdr.src_addr));

	if ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		    snap_oui_802_h, sizeof(snap_oui_802_h)) == 0) ||
	    ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		     rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    appletalk_aarp_type, sizeof(appletalk_aarp_type)) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    ipx_snap_type, sizeof(ipx_snap_type)))) {
		/*
		 *  Replace the 803 header and rfc1042 header (llc/snap) with an
		 *    EthernetII header, keep the src/dst and snap_type (ethertype).
		 *  The firmware only passes up SNAP frames converting
		 *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
		 *  To create the Ethernet II, just move the src, dst address right
		 *    before the snap_type.
		 */
		peth_hdr = (EthII_Hdr_t *)
			((t_u8 *) & prx_pkt->eth803_hdr
			 + sizeof(prx_pkt->eth803_hdr) +
			 sizeof(prx_pkt->rfc1042_hdr)
			 - sizeof(prx_pkt->eth803_hdr.dest_addr)
			 - sizeof(prx_pkt->eth803_hdr.src_addr)
			 - sizeof(prx_pkt->rfc1042_hdr.snap_type));

		memcpy(pmadapter, peth_hdr->src_addr,
		       prx_pkt->eth803_hdr.src_addr,
		       sizeof(peth_hdr->src_addr));
		memcpy(pmadapter, peth_hdr->dest_addr,
		       prx_pkt->eth803_hdr.dest_addr,
		       sizeof(peth_hdr->dest_addr));

		/* Chop off the RxPD + the excess memory from the
		   802.2/llc/snap header that was removed. */
		hdr_chop = (t_u32) ((t_ptr) peth_hdr - (t_ptr) prx_pd);
	} else {
		HEXDUMP("RX Data: LLC/SNAP",
			(t_u8 *) & prx_pkt->rfc1042_hdr,
			sizeof(prx_pkt->rfc1042_hdr));

		/* Chop off the RxPD */
		hdr_chop =
			(t_u32) ((t_ptr) & prx_pkt->eth803_hdr -
				 (t_ptr) prx_pd);
	}

	/* Chop off the leading header bytes so the it points to the start of
	   either the reconstructed EthII frame or the 802.2/llc/snap frame */
	pmbuf->data_len -= hdr_chop;
	pmbuf->data_offset += hdr_chop;
	pmbuf->pparent = MNULL;

	DBG_HEXDUMP(MDAT_D, "RxPD", (t_u8 *) prx_pd,
		    MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
	DBG_HEXDUMP(MDAT_D, "Rx Payload",
		    ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset),
		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));

	priv->rxpd_rate = prx_pd->rx_rate;
	priv->rxpd_htinfo = prx_pd->ht_info;

	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
						  &pmbuf->out_ts_sec,
						  &pmbuf->out_ts_usec);
	PRINTM_NETINTF(MDATA, priv);
	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
	       prx_pd->priority);

	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
	if (ret == MLAN_STATUS_FAILURE) {
		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
		PRINTM(MERROR,
		       "STA Rx Error: moal_recv_packet returned error\n");
	}
done:
	if (ret != MLAN_STATUS_PENDING) {
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	}
	LEAVE();

	return ret;
}
Esempio n. 23
0
/**
 *  @brief Utility function to process a start or join to an adhoc network
 *
 *  Add the elements to the TLV buffer needed in the start/join adhoc commands:
 *       - IBSS DFS IE
 *       - Quiet IE
 *
 *  Also send the local constraint to the firmware in a TPC_INFO command.
 *
 *  @param priv          Private driver information structure
 *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer,
 *                       modified on return to point after the appended 11h TLVs
 *  @param channel       Channel on which we are starting/joining the IBSS
 *  @param p11h_bss_info Pointer to the 11h BSS information for this network
 *                       that was parsed out of the scan response.  NULL
 *                       indicates we are starting the adhoc network
 *
 *  @return              Integer number of bytes appended to the TLV output
 *                       buffer (ppbuffer)
 */
static int
wlan_11h_process_adhoc(mlan_private * priv,
                       t_u8 ** ppbuffer,
                       t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
{
    IEEEtypes_IBSS_DFS_t dfs_elem;
    int size_appended;
    int ret_len = 0;
    t_s8 local_constraint = 0;
    mlan_adapter *adapter = priv->adapter;

    ENTER();

    /* Format our own IBSS DFS Element.  Include our channel map fields */
    wlan_11h_set_ibss_dfs_ie(priv, &dfs_elem);

    if (p11h_bss_info) {
        /* 
         * Copy the DFS Owner/Recovery Interval from the BSS we are joining
         */
        memcpy(dfs_elem.dfs_owner,
               p11h_bss_info->ibss_dfs.dfs_owner, sizeof(dfs_elem.dfs_owner));
        dfs_elem.dfs_recovery_interval =
            p11h_bss_info->ibss_dfs.dfs_recovery_interval;
    }

    /* Append the dfs element to the TLV buffer */
    size_appended = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
                                                     (char *) &dfs_elem);

    HEXDUMP("11h: IBSS-DFS", (t_u8 *) * ppbuffer, size_appended);
    *ppbuffer += size_appended;
    ret_len += size_appended;

    /* 
     * Check to see if we are joining a network.  Join is indicated by the
     *   BSS Info pointer being valid (not NULL)
     */
    if (p11h_bss_info) {
        /* 
         * If there was a quiet element, include it in adhoc join command
         */
        if (p11h_bss_info->quiet.element_id == QUIET) {
            size_appended
                = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
                                                   (char *) &p11h_bss_info->
                                                   quiet);
            HEXDUMP("11h: Quiet", (t_u8 *) * ppbuffer, size_appended);
            *ppbuffer += size_appended;
            ret_len += size_appended;
        }

        /* Copy the local constraint from the network */
        local_constraint = p11h_bss_info->power_constraint.local_constraint;
    } else {
        /* 
         * If we are the adhoc starter, we can add a quiet element
         */
        if (adapter->state_11h.quiet_ie.quiet_period) {
            size_appended = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
                                                             (char *) &adapter->
                                                             state_11h.
                                                             quiet_ie);
            HEXDUMP("11h: Quiet", (t_u8 *) * ppbuffer, size_appended);
            *ppbuffer += size_appended;
            ret_len += size_appended;

            /* Use the local_constraint configured in the driver state */
            local_constraint = adapter->state_11h.usr_def_power_constraint;
        }
    }

    /* Set the local constraint configured in the firmware */
    wlan_11h_set_local_power_constraint(priv, channel, local_constraint);

    LEAVE();
    return ret_len;
}
Esempio n. 24
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer
 *
 *  @param pmadapter A pointer to mlan_adapter
 *  @param pmbuf   A pointer to mlan_buffer which includes the received packet
 *
 *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	RxPacketHdr_t *prx_pkt;
	RxPD *prx_pd;
	int hdr_chop;
	EthII_Hdr_t *peth_hdr;
	t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
	};
	t_u8 snap_oui_802_h[MLAN_MAC_ADDR_LENGTH] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
	};
	t_u8 appletalk_aarp_type[2] = { 0x80, 0xf3 };
	t_u8 ipx_snap_type[2] = { 0x81, 0x37 };
	t_u8 tdls_action_type[2] = { 0x89, 0x0d };
#ifdef DRV_EMBEDDED_SUPPLICANT
	t_u8 eapol_type[2] = { 0x88, 0x8e };
#endif
	t_u8 adj_rx_rate = 0;

	ENTER();

	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);

/** Small debug type */
#define DBG_TYPE_SMALL  2
/** Size of debugging structure */
#define SIZE_OF_DBG_STRUCT 4
	if (prx_pd->rx_pkt_type == PKT_TYPE_DEBUG) {
		t_u8 dbg_type;
		dbg_type = *(t_u8 *)&prx_pkt->eth803_hdr;
		if (dbg_type == DBG_TYPE_SMALL) {
			PRINTM(MFW_D, "\n");
			DBG_HEXDUMP(MFW_D, "FWDBG",
				    (char *)((t_u8 *)&prx_pkt->eth803_hdr +
					     SIZE_OF_DBG_STRUCT),
				    prx_pd->rx_pkt_length);
			PRINTM(MFW_D, "FWDBG::\n");
		}
		goto done;
	}

	PRINTM(MINFO,
	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
	       pmbuf->data_len, prx_pd->rx_pkt_offset,
	       pmbuf->data_len - prx_pd->rx_pkt_offset);

	HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
		sizeof(prx_pkt->eth803_hdr.dest_addr));
	HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
		sizeof(prx_pkt->eth803_hdr.src_addr));

	if ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		    snap_oui_802_h, sizeof(snap_oui_802_h)) == 0) ||
	    ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		     rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    appletalk_aarp_type, sizeof(appletalk_aarp_type)) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    ipx_snap_type, sizeof(ipx_snap_type)))) {
		/*
		 * Replace the 803 header and rfc1042 header (llc/snap) with an
		 * EthernetII header, keep the src/dst and snap_type (ethertype).
		 * The firmware only passes up SNAP frames converting
		 * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
		 * To create the Ethernet II, just move the src, dst address
		 * right before the snap_type.
		 */
		peth_hdr = (EthII_Hdr_t *)
			((t_u8 *)&prx_pkt->eth803_hdr
			 + sizeof(prx_pkt->eth803_hdr) +
			 sizeof(prx_pkt->rfc1042_hdr)
			 - sizeof(prx_pkt->eth803_hdr.dest_addr)
			 - sizeof(prx_pkt->eth803_hdr.src_addr)
			 - sizeof(prx_pkt->rfc1042_hdr.snap_type));

		memcpy(pmadapter, peth_hdr->src_addr,
		       prx_pkt->eth803_hdr.src_addr,
		       sizeof(peth_hdr->src_addr));
		memcpy(pmadapter, peth_hdr->dest_addr,
		       prx_pkt->eth803_hdr.dest_addr,
		       sizeof(peth_hdr->dest_addr));

		/* Chop off the RxPD + the excess memory from the
		   802.2/llc/snap header that was removed. */
		hdr_chop = (t_u32)((t_ptr)peth_hdr - (t_ptr)prx_pd);
	} else {
		HEXDUMP("RX Data: LLC/SNAP",
			(t_u8 *)&prx_pkt->rfc1042_hdr,
			sizeof(prx_pkt->rfc1042_hdr));
		if ((priv->hotspot_cfg & HOTSPOT_ENABLED) &&
		    discard_gratuitous_ARP_msg(prx_pkt, pmadapter)) {
			ret = MLAN_STATUS_SUCCESS;
			PRINTM(MDATA,
			       "Bypass sending Gratuitous ARP frame to Kernel.\n");
			goto done;
		}
		if (!memcmp(pmadapter, &prx_pkt->eth803_hdr.h803_len,
			    tdls_action_type, sizeof(tdls_action_type))) {
			wlan_process_tdls_action_frame(priv,
						       ((t_u8 *)prx_pd +
							prx_pd->rx_pkt_offset),
						       prx_pd->rx_pkt_length);
		}
		/* Chop off the RxPD */
		hdr_chop = (t_u32)((t_ptr)&prx_pkt->eth803_hdr - (t_ptr)prx_pd);
	}

	/* Chop off the leading header bytes so the it points to the start of
	   either the reconstructed EthII frame or the 802.2/llc/snap frame */
	pmbuf->data_len -= hdr_chop;
	pmbuf->data_offset += hdr_chop;
	pmbuf->pparent = MNULL;

	DBG_HEXDUMP(MDAT_D, "RxPD", (t_u8 *)prx_pd,
		    MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
	DBG_HEXDUMP(MDAT_D, "Rx Payload",
		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));
	priv->rxpd_rate = prx_pd->rx_rate;
	priv->rxpd_htinfo = prx_pd->ht_info;
	if (priv->bss_type == MLAN_BSS_TYPE_STA) {
		adj_rx_rate =
			wlan_adjust_data_rate(priv, priv->rxpd_rate,
					      priv->rxpd_htinfo);
		pmadapter->callbacks.moal_hist_data_add(pmadapter->pmoal_handle,
							pmbuf->bss_index,
							adj_rx_rate,
							prx_pd->snr,
							prx_pd->nf,
							prx_pd->antenna);
	}

	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
						  &pmbuf->out_ts_sec,
						  &pmbuf->out_ts_usec);
	PRINTM_NETINTF(MDATA, priv);
	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
	       prx_pd->priority);

#ifdef DRV_EMBEDDED_SUPPLICANT
	if (priv->adapter->psdio_device->driver_supplicant_auth &&
	    supplicantIsEnabled(priv->psapriv) &&
	    (!memcmp
	     (pmadapter, &prx_pkt->eth803_hdr.h803_len, eapol_type,
	      sizeof(eapol_type)))) {
		// BML_SET_OFFSET(bufDesc, offset);
		if (ProcessEAPoLPkt(priv->psapriv, pmbuf)) {
			wlan_free_mlan_buffer(pmadapter, pmbuf);
			ret = MLAN_STATUS_SUCCESS;
			PRINTM(MMSG,
			       "host supplicant eapol pkt process done.\n");

			LEAVE();
			return ret;
		}
	}
#endif

	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
	if (ret == MLAN_STATUS_FAILURE) {
		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
		PRINTM(MERROR,
		       "STA Rx Error: moal_recv_packet returned error\n");
	}
done:
	if (ret != MLAN_STATUS_PENDING)
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	LEAVE();

	return ret;
}
Esempio n. 25
0
static dc_status_t
atomics_cobalt_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc_event_progress_t *progress)
{
#ifdef HAVE_LIBUSB
	atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract;

	if (device_is_cancelled (abstract))
		return DC_STATUS_CANCELLED;

	// Erase the current contents of the buffer.
	if (!dc_buffer_clear (buffer)) {
		ERROR (abstract->context, "Insufficient buffer space available.");
		return DC_STATUS_NOMEMORY;
	}

	// Send the command to the dive computer.
	uint8_t bRequest = 0;
	if (device->simulation)
		bRequest = init ? 0x02 : 0x03;
	else
		bRequest = init ? 0x09 : 0x0A;
	int rc = libusb_control_transfer (device->handle,
		LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
		bRequest, 0, 0, NULL, 0, TIMEOUT);
	if (rc != LIBUSB_SUCCESS) {
		ERROR (abstract->context, "Failed to send the command.");
		return EXITCODE(rc);
	}

	HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Write", &bRequest, 1);

	unsigned int nbytes = 0;
	while (1) {
		// Receive the answer from the dive computer.
		int length = 0;
		unsigned char packet[8 * 1024] = {0};
		rc = libusb_bulk_transfer (device->handle, 0x82,
			packet, sizeof (packet), &length, TIMEOUT);
		if (rc != LIBUSB_SUCCESS) {
			ERROR (abstract->context, "Failed to receive the answer.");
			return EXITCODE(rc);
		}

		HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Read", packet, length);

		// Update and emit a progress event.
		if (progress) {
			progress->current += length;
			device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
		}

		// Append the packet to the output buffer.
		dc_buffer_append (buffer, packet, length);
		nbytes += length;

		// If we received fewer bytes than requested, the transfer is finished.
		if (length < sizeof (packet))
			break;
	}

	// Check for a buffer error.
	if (dc_buffer_get_size (buffer) != nbytes) {
		ERROR (abstract->context, "Insufficient buffer space available.");
		return DC_STATUS_NOMEMORY;
	}

	// Check for the minimum length.
	if (nbytes < 2) {
		ERROR (abstract->context, "Data packet is too short.");
		return DC_STATUS_PROTOCOL;
	}

	// When only two 0xFF bytes are received, there are no more dives.
	unsigned char *data = dc_buffer_get_data (buffer);
	if (nbytes == 2 && data[0] == 0xFF && data[1] == 0xFF) {
		dc_buffer_clear (buffer);
		return DC_STATUS_SUCCESS;
	}

	// Verify the checksum of the packet.
	unsigned short crc = array_uint16_le (data + nbytes - 2);
	unsigned short ccrc = checksum_add_uint16 (data, nbytes - 2, 0x0);
	if (crc != ccrc) {
		ERROR (abstract->context, "Unexpected answer checksum.");
		return DC_STATUS_PROTOCOL;
	}

	// Remove the checksum bytes.
	dc_buffer_slice (buffer, 0, nbytes - 2);

	return DC_STATUS_SUCCESS;
#else
	return DC_STATUS_UNSUPPORTED;
#endif
}
Esempio n. 26
0
/**
 *  @brief This function processes received packet and forwards it
 *  		to kernel/upper layer
 *  
 *  @param pmadapter A pointer to mlan_adapter
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    pmlan_private priv = pmadapter->priv[pmbuf->bss_num];
    RxPacketHdr_t *prx_pkt;
    RxPD *prx_pd;
    int hdr_chop;
    EthII_Hdr_t *peth_hdr;
    t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] =
        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };

    ENTER();
    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);

    prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);

    DBG_HEXDUMP(MDAT_D, "Rx", pmbuf->pbuf + pmbuf->data_offset,
                MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));

/** Rx packet type debugging */
#define RX_PKT_TYPE_DEBUG  0xEF
/** Small debug type */
#define DBG_TYPE_SMALL  2
/** Size of debugging structure */
#define SIZE_OF_DBG_STRUCT 4
    if (prx_pd->rx_pkt_type == RX_PKT_TYPE_DEBUG) {
        t_u8 dbgType;
        dbgType = *(t_u8 *) & prx_pkt->eth803_hdr;
        if (dbgType == DBG_TYPE_SMALL) {
            PRINTM(MFW_D, "\n");
            DBG_HEXDUMP(MFW_D, "FWDBG",
                        (t_s8 *) ((t_u8 *) & prx_pkt->eth803_hdr +
                                  SIZE_OF_DBG_STRUCT), prx_pd->rx_pkt_length);
            PRINTM(MFW_D, "FWDBG::\n");
        }
        goto done;
    }

    PRINTM(MINFO, "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
           pmbuf->data_len, prx_pd->rx_pkt_offset,
           pmbuf->data_len - prx_pd->rx_pkt_offset);

    HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
            sizeof(prx_pkt->eth803_hdr.dest_addr));
    HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
            sizeof(prx_pkt->eth803_hdr.src_addr));

    if (!memcmp(&prx_pkt->rfc1042_hdr,
                rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
        /* 
         *  Replace the 803 header and rfc1042 header (llc/snap) with an 
         *    EthernetII header, keep the src/dst and snap_type (ethertype).
         *  The firmware only passes up SNAP frames converting
         *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
         *  To create the Ethernet II, just move the src, dst address right
         *    before the snap_type.
         */
        peth_hdr = (EthII_Hdr_t *)
            ((t_u8 *) & prx_pkt->eth803_hdr
             + sizeof(prx_pkt->eth803_hdr) + sizeof(prx_pkt->rfc1042_hdr)
             - sizeof(prx_pkt->eth803_hdr.dest_addr)
             - sizeof(prx_pkt->eth803_hdr.src_addr)
             - sizeof(prx_pkt->rfc1042_hdr.snap_type));

        memcpy(peth_hdr->src_addr, prx_pkt->eth803_hdr.src_addr,
               sizeof(peth_hdr->src_addr));
        memcpy(peth_hdr->dest_addr, prx_pkt->eth803_hdr.dest_addr,
               sizeof(peth_hdr->dest_addr));

        /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header 
           that was removed. */
        hdr_chop = (t_u8 *) peth_hdr - (t_u8 *) prx_pd;
    } else {
        HEXDUMP("RX Data: LLC/SNAP",
                (t_u8 *) & prx_pkt->rfc1042_hdr, sizeof(prx_pkt->rfc1042_hdr));

        /* Chop off the RxPD */
        hdr_chop = (t_u8 *) & prx_pkt->eth803_hdr - (t_u8 *) prx_pd;
    }

    /* Chop off the leading header bytes so the it points to the start of
       either the reconstructed EthII frame or the 802.2/llc/snap frame */
    pmbuf->data_len -= hdr_chop;
    pmbuf->data_offset += hdr_chop;
    pmbuf->pparent = MNULL;

    priv->rxpd_rate = prx_pd->rx_rate;

    priv->rxpd_htinfo = prx_pd->ht_info;

    ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
    if (ret == MLAN_STATUS_FAILURE) {
        PRINTM(MERROR, "RX Error: moal_recv_packet" " returns failure\n");
    }

    pmadapter->callbacks.moal_get_system_time(&pmbuf->out_ts_sec,
                                              &pmbuf->out_ts_usec);
    PRINTM(MDATA, "%lu.%lu : Data => kernel\n", pmbuf->out_ts_sec,
           pmbuf->out_ts_usec);

    if (ret != MLAN_STATUS_PENDING) {
        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
                                                0, ret);
    }

  done:
    LEAVE();

    return ret;
}
Esempio n. 27
0
/**
 *  @brief This function processes received packet and forwards it
 *  		to kernel/upper layer
 *  
 *  @param pmadapter A pointer to mlan_adapter
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
    /* RxPacketHdr_t *prx_pkt; */
    RxPD *prx_pd;
#ifndef CONFIG_MLAN_WMSDK
    int hdr_chop;
    EthII_Hdr_t *peth_hdr;
    t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] =
        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
    t_u8 snap_oui_802_h[MLAN_MAC_ADDR_LENGTH] =
        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
    t_u8 appletalk_aarp_type[2] = { 0x80, 0xf3 };
    t_u8 ipx_snap_type[2] = { 0x81, 0x37 };
#endif /* CONFIG_MLAN_WMSDK */
    ENTER();

    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
 /* Note: Important. We do not have actual data @ prx_pd->rx_pkt_offset */
    /* prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset); */
    /* prx_pkt = (RxPacketHdr_t *)pmbuf->pdesc; */

/** Small debug type */
#define DBG_TYPE_SMALL  2
/** Size of debugging structure */
#define SIZE_OF_DBG_STRUCT 4
    /*
       This additional processing does not seem to be required by us for
       the moment. Let skip it for now. They seem to be doing some kind of
       ethernet header processing.
    */

#ifndef CONFIG_MLAN_WMSDK
    if (prx_pd->rx_pkt_type == PKT_TYPE_DEBUG) {
        t_u8 dbgType;
        dbgType = *(t_u8 *) & prx_pkt->eth803_hdr;
        if (dbgType == DBG_TYPE_SMALL) {
            PRINTM(MFW_D, "\n");
            DBG_HEXDUMP(MFW_D, "FWDBG",
                        (t_s8 *) ((t_u8 *) & prx_pkt->eth803_hdr +
                                  SIZE_OF_DBG_STRUCT), prx_pd->rx_pkt_length);
            PRINTM(MFW_D, "FWDBG::\n");
        }
        goto done;
    }

    PRINTM(MINFO, "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
           pmbuf->data_len, prx_pd->rx_pkt_offset,
           pmbuf->data_len - prx_pd->rx_pkt_offset);

    HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
            sizeof(prx_pkt->eth803_hdr.dest_addr));
    HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
            sizeof(prx_pkt->eth803_hdr.src_addr));

    if ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
                snap_oui_802_h, sizeof(snap_oui_802_h)) == 0) ||
        ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
                 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) &&
         memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
                appletalk_aarp_type, sizeof(appletalk_aarp_type)) &&
         memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
                ipx_snap_type, sizeof(ipx_snap_type)))) {
        /* 
         *  Replace the 803 header and rfc1042 header (llc/snap) with an 
         *    EthernetII header, keep the src/dst and snap_type (ethertype).
         *  The firmware only passes up SNAP frames converting
         *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
         *  To create the Ethernet II, just move the src, dst address right
         *    before the snap_type.
         */
        peth_hdr = (EthII_Hdr_t *)
            ((t_u8 *) & prx_pkt->eth803_hdr
             + sizeof(prx_pkt->eth803_hdr) + sizeof(prx_pkt->rfc1042_hdr)
             - sizeof(prx_pkt->eth803_hdr.dest_addr)
             - sizeof(prx_pkt->eth803_hdr.src_addr)
             - sizeof(prx_pkt->rfc1042_hdr.snap_type));

        memcpy(pmadapter, peth_hdr->src_addr, prx_pkt->eth803_hdr.src_addr,
               sizeof(peth_hdr->src_addr));
        memcpy(pmadapter, peth_hdr->dest_addr, prx_pkt->eth803_hdr.dest_addr,
               sizeof(peth_hdr->dest_addr));

        /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header 
           that was removed. */
        hdr_chop = (t_u32) ((t_ptr) peth_hdr - (t_ptr) prx_pd);
    } else {
        HEXDUMP("RX Data: LLC/SNAP",
                (t_u8 *) & prx_pkt->rfc1042_hdr, sizeof(prx_pkt->rfc1042_hdr));
        if ((priv->hotspot_cfg & HOTSPOT_ENABLED) &&
            discard_gratuitous_ARP_msg(prx_pkt, pmadapter)) {
            ret = MLAN_STATUS_SUCCESS;
            PRINTM(MDATA, "Bypass sending Gratuitous ARP frame to Kernel.\n");
            goto done;
        }

        /* Chop off the RxPD */
        hdr_chop = (t_u32) ((t_ptr) & prx_pkt->eth803_hdr - (t_ptr) prx_pd);
    }

    /* Chop off the leading header bytes so the it points to the start of
       either the reconstructed EthII frame or the 802.2/llc/snap frame */
    pmbuf->data_len -= hdr_chop;
    pmbuf->data_offset += hdr_chop;
    pmbuf->pparent = MNULL;

    DBG_HEXDUMP(MDAT_D, "RxPD", (t_u8 *) prx_pd,
                MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
    /* Note: We do not have data @ some offset of pbuf. pbuf only has RxPD */
    /* DBG_HEXDUMP(MDAT_D, "Rx Payload", ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset), */
    /*             MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN)); */
#endif /* CONFIG_MLAN_WMSDK */
    priv->rxpd_rate = prx_pd->rx_rate;

    priv->rxpd_htinfo = prx_pd->ht_info;
#ifndef CONFIG_MLAN_WMSDK 
    /* wmsdk: looks like only a debugging thing. disabling for now */
    pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
                                              &pmbuf->out_ts_sec,
                                              &pmbuf->out_ts_usec);
    PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
           pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
           prx_pd->priority);
#endif /* CONFIG_MLAN_WMSDK */

    ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
    if (ret == MLAN_STATUS_FAILURE) {
        pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
        PRINTM(MERROR, "STA Rx Error: moal_recv_packet returned error\n");
    }
  /* done: */
    if (ret != MLAN_STATUS_PENDING) {
        wlan_free_mlan_buffer(pmadapter, pmbuf);
    }
    LEAVE();

    return ret;
}
Packet*
RouteProcessor::handleRequestPacket( const RequestPacket& requestPacket,
                                     char* packetInfo )
{
   DEBUG1( cerr << "***" << endl);
   DEBUG4( cerr << "RouteProcessor::handleRequest" << endl );
   Packet* replyPacket = NULL;

   uint16 subType = requestPacket.getSubType();
      
   if ( m_packetFileName != NULL ) {
      // Use this code to write the packets to disk for later profiling
      FILE* packetFile = fopen("routePacks", "ab");
      uint32 packLen = ntohl(requestPacket.getLength());
      fwrite(&packLen, 4, 1, packetFile);
      fwrite(requestPacket.getBuf(),
             requestPacket.getLength(), 1, packetFile);
      fclose(packetFile);
   }
      
   switch (subType) {
   case Packet::PACKETTYPE_UPDATETRAFFICCOSTREQUEST : {
      DEBUG1(
             MC2INFO("RouteProcessor got UpdatetrafficCostRequestPacket"));
      const UpdateTrafficCostRequestPacket* updateTrafficCostPacket =
         static_cast<const UpdateTrafficCostRequestPacket*>(&requestPacket);
      replyPacket =
         processUpdateTrafficCostRequestPacket(updateTrafficCostPacket);
   }
      break;
         
   case Packet::PACKETTYPE_SUBROUTEREQUEST : {
      mc2dbg << "RouteProcessor got SubRouteRequestPacket - size = "
             << requestPacket.getLength() << endl;
      const RMSubRouteRequestPacket* subRoutePacket =
         static_cast<const RMSubRouteRequestPacket*>(&requestPacket);
      replyPacket = processSubRouteRequestPacket(subRoutePacket);
   }
      break;
         
   case Packet::PACKETTYPE_EDGENODESREQUEST: {
      mc2dbg << "RouteProcessor got EdgeNodesRequestPacket" << endl;
      const EdgeNodesRequestPacket* edgeNodesReq =
         static_cast<const EdgeNodesRequestPacket*>(&requestPacket);
      replyPacket = processEdgeNodesRequestPacket(edgeNodesReq);
   }
      break;
         
   case Packet::PACKETTYPE_IDTRANSLATIONREQUEST: {
      mc2dbg4 << "RouteProcessor got IDTranslationRequestPacket" << endl;
      const IDTranslationRequestPacket* levelReq =
         static_cast<const IDTranslationRequestPacket*>(&requestPacket);
      mc2dbg8 << "Incoming packet:" << endl;
      DEBUG8(
             HEXDUMP(mc2dbg8, levelReq->getBuf(), levelReq->getLength(),""));
      replyPacket = processIDTranslationRequestPacket(levelReq);
      mc2dbg8 << "Outgoing packet:" << endl;
      DEBUG8(HEXDUMP(mc2dbg8, replyPacket->getBuf(),
                     replyPacket->getLength(), ""));
   }
      break;
         
   case Packet::PACKETTYPE_DISTURBANCEPUSH: {
      mc2dbg << "RouteProcessor got DisturbancePushPacket " << endl;
      const DisturbancePushPacket* distPushReq =
         static_cast<const DisturbancePushPacket*>( &requestPacket );
      int nbrDist = processDisturbancePushPacket( distPushReq );
      replyPacket = NULL; // We cannot reply to this.
      // Add info about the number of disturbances.
      sprintf(packetInfo, "ndist = %d", nbrDist);
   }
      break;
   default : {
      mc2log << warn
             << "RouteProcessor received packet with unknown type = "
             << requestPacket.getSubTypeAsString()
             << " ip=" << requestPacket.getOriginIP()
             << ", port=" << requestPacket.getOriginPort() << endl;
      replyPacket = NULL;
   }
   }// end switch

   // If a mapload failed packets in the queue might lack the right map.
   // and need to be sent again
   if((dynamic_cast<ReplyPacket*>(replyPacket) != NULL) &&
      (static_cast<ReplyPacket*>(replyPacket)->getStatus() ==
       StringTable::MAPNOTFOUND)) {
      delete replyPacket;
      replyPacket = new AcknowledgeRequestReplyPacket(&requestPacket,
                                                      StringTable::OK,
                                                      ACKTIME_NOMAP);
   }      


   DEBUG1(cout << endl);
   
   return replyPacket;
} // handleRequest