/** * @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; }
/** * @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; }
/** * @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; }
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; }
/** * @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; }
/** * @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; }
/** * @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; }
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; }
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 {
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; }
/** * @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; }
/** * @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; }
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); } }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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); }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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; }
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 }
/** * @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; }
/** * @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