s32 wl_cfgnan_notify_proxd_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data) { s32 ret = BCME_OK; wl_nan_ranging_event_data_t *rdata; s32 status; u16 data_len; s32 event_type; s32 event_num; u8 *buf = NULL; u32 buf_len; u8 *ptr; u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; s32 i; if (!event || !data) { WL_ERR((" event data is NULL \n")); return -EINVAL; } status = ntoh32(event->reason); event_type = ntoh32(event->event_type); event_num = ntoh32(event->reason); data_len = ntoh32(event->datalen); WL_DBG((" proxd event: type: %d num: %d len: %d \n", event_type, event_num, data_len)); if (INVALID_PROXD_EVENT(event_num)) { WL_ERR((" unsupported event, num: %d \n", event_num)); return -EINVAL; } if (g_nan_debug) { WL_DBG((" event name: WLC_E_PROXD_NAN_EVENT \n")); WL_DBG((" event data: \n")); prhex(NULL, data, data_len); } if (data_len < sizeof(wl_nan_ranging_event_data_t)) { WL_ERR((" wrong data len \n")); return -EINVAL; } rdata = (wl_nan_ranging_event_data_t *)data; WL_DBG((" proxd event: count:%d success_count:%d mode:%d \n", rdata->count, rdata->success_count, rdata->mode)); if (g_nan_debug) { prhex(" event data: ", data, data_len); } buf_len = NAN_IOCTL_BUF_SIZE; buf = kzalloc(buf_len, kflags); if (!buf) { WL_ERR((" memory allocation failed \n")); return -ENOMEM; } for (i = 0; i < rdata->count; i++) { if (&rdata->rr[i] == NULL) { ret = -EINVAL; goto fail; } ptr = buf; WL_DBG((" ranging data for mac:"MACDBG" \n", MAC2STRDBG(rdata->rr[i].ea.octet))); ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " MAC_ADDR_PREFIX MACF " "STATUS_PREFIX"%s", EVENT_RTT_STATUS_STR, ETHER_TO_MACF(rdata->rr[i].ea), (rdata->rr[i].status == 1) ? "success" : "fail"); if (rdata->rr[i].status == 1) { /* add tsf and distance only if status is success */ ptr += sprintf(ptr, " "TIMESTAMP_PREFIX"0x%x " DISTANCE_PREFIX"%d.%04d", rdata->rr[i].timestamp, rdata->rr[i].distance >> 4, ((rdata->rr[i].distance & 0x0f) * 625)); } #ifdef WL_GENL /* send the preformatted string to the upper layer as event */ WL_DBG((" formatted string for userspace: %s, len: %zu \n", buf, strlen(buf))); wl_genl_send_msg(bcmcfg_to_prmry_ndev(cfg), 0, buf, strlen(buf), 0, 0); #endif /* WL_GENL */ }
static int wl_cfgnan_parse_args(char *buf, nan_cmd_data_t *cmd_data) { s32 ret = BCME_OK; char *token = buf; char delim[] = " "; while ((buf != NULL) && (token != NULL)) { if (!strncmp(buf, PUB_ID_PREFIX, strlen(PUB_ID_PREFIX))) { buf += strlen(PUB_ID_PREFIX); token = strsep(&buf, delim); cmd_data->pub_id = simple_strtoul(token, NULL, 10); if (INVALID_ID(cmd_data->pub_id)) { WL_ERR((" invalid publisher id, pub_id = %d \n", cmd_data->pub_id)); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, SUB_ID_PREFIX, strlen(SUB_ID_PREFIX))) { buf += strlen(SUB_ID_PREFIX); token = strsep(&buf, delim); cmd_data->sub_id = simple_strtoul(token, NULL, 10); if (INVALID_ID(cmd_data->sub_id)) { WL_ERR((" invalid subscriber id, sub_id = %d \n", cmd_data->sub_id)); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, MAC_ADDR_PREFIX, strlen(MAC_ADDR_PREFIX))) { buf += strlen(MAC_ADDR_PREFIX); token = strsep(&buf, delim); if (!wl_cfg80211_ether_atoe(token, &cmd_data->mac_addr)) { WL_ERR((" invalid mac address, mac_addr = "MACDBG "\n", MAC2STRDBG(cmd_data->mac_addr.octet))); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, SVC_HASH_PREFIX, strlen(SVC_HASH_PREFIX))) { buf += strlen(SVC_HASH_PREFIX); token = strsep(&buf, delim); cmd_data->svc_hash.data = token; cmd_data->svc_hash.dlen = WL_NAN_SVC_HASH_LEN; } else if (!strncmp(buf, SVC_INFO_PREFIX, strlen(SVC_INFO_PREFIX))) { buf += strlen(SVC_INFO_PREFIX); token = strsep(&buf, delim); cmd_data->svc_info.data = token; cmd_data->svc_info.dlen = strlen(token); } else if (!strncmp(buf, CHAN_PREFIX, strlen(CHAN_PREFIX))) { buf += strlen(CHAN_PREFIX); token = strsep(&buf, delim); cmd_data->chanspec = wf_chspec_aton(token); cmd_data->chanspec = wl_chspec_host_to_driver(cmd_data->chanspec); if (INVALID_CHANSPEC(cmd_data->chanspec)) { WL_ERR((" invalid chanspec, chanspec = 0x%04x \n", cmd_data->chanspec)); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, BITMAP_PREFIX, strlen(BITMAP_PREFIX))) { buf += strlen(BITMAP_PREFIX); token = strsep(&buf, delim); cmd_data->bmap = simple_strtoul(token, NULL, 16); } else if (!strncmp(buf, ATTR_PREFIX, strlen(ATTR_PREFIX))) { buf += strlen(ATTR_PREFIX); token = strsep(&buf, delim); if (!wl_cfgnan_config_attr(token, &cmd_data->attr)) { WL_ERR((" invalid attribute, attr = %s \n", cmd_data->attr.name)); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, ROLE_PREFIX, strlen(ROLE_PREFIX))) { buf += strlen(ROLE_PREFIX); token = strsep(&buf, delim); cmd_data->role = simple_strtoul(token, NULL, 10); if (INVALID_ROLE(cmd_data->role)) { WL_ERR((" invalid role, role = %d \n", cmd_data->role)); ret = -EINVAL; goto fail; } } else if (!strncmp(buf, MASTER_PREF_PREFIX, strlen(MASTER_PREF_PREFIX))) { buf += strlen(MASTER_PREF_PREFIX); token = strsep(&buf, delim); cmd_data->master_pref = simple_strtoul(token, NULL, 10); } else if (!strncmp(buf, PUB_PR_PREFIX, strlen(PUB_PR_PREFIX))) { buf += strlen(PUB_PR_PREFIX); token = strsep(&buf, delim); cmd_data->pub_pr = simple_strtoul(token, NULL, 10); } else if (!strncmp(buf, PUB_INT_PREFIX, strlen(PUB_INT_PREFIX))) { buf += strlen(PUB_INT_PREFIX); token = strsep(&buf, delim); cmd_data->pub_int = simple_strtoul(token, NULL, 10); } else if (!strncmp(buf, DW_LEN_PREFIX, strlen(DW_LEN_PREFIX))) { buf += strlen(DW_LEN_PREFIX); token = strsep(&buf, delim); cmd_data->dw_len = simple_strtoul(token, NULL, 10); } else if (!strncmp(buf, DEBUG_PREFIX, strlen(DEBUG_PREFIX))) { buf += strlen(DEBUG_PREFIX); token = strsep(&buf, delim); cmd_data->debug_flag = simple_strtoul(token, NULL, 10); } else { WL_ERR((" unknown token, token = %s, buf = %s \n", token, buf)); ret = -EINVAL; goto fail; } } fail: return ret; }
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac) { int ret = -1; unsigned char cis_buf[CIS_BUF_SIZE] = {0}; unsigned char mac_buf[20] = {0}; unsigned char otp_mac_buf[20] = {0}; const char *macfilepath = MACINFO_EFS; /* Try reading out from CIS */ cis_rw_t *cish = (cis_rw_t *)&cis_buf[8]; struct file *fp_mac = NULL; cish->source = 0; cish->byteoff = 0; cish->nbytes = sizeof(cis_buf); strcpy(cis_buf, "cisdump"); ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf, sizeof(cis_buf), 0, 0); if (ret < 0) { DHD_TRACE(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n", __func__, ret)); sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac->octet[0], mac->octet[1], mac->octet[2], mac->octet[3], mac->octet[4], mac->octet[5]); DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n", __FUNCTION__, MAC2STRDBG(mac->octet))); } else { bcm_tlv_t *elt = NULL; int remained_len = sizeof(cis_buf); int index = 0; uint8 *mac_addr = NULL; #ifdef DUMP_CIS dhd_dump_cis(cis_buf, 48); #endif /* Find a new tuple tag */ while (index < remained_len) { if (cis_buf[index] == CIS_TUPLE_TAG_START) { remained_len -= index; if (remained_len >= sizeof(bcm_tlv_t)) { elt = (bcm_tlv_t *)&cis_buf[index]; } break; } else { index++; } } /* Find a MAC address tuple */ while (elt && remained_len >= TLV_HDR_LEN) { int body_len = (int)elt->len; if ((elt->id == CIS_TUPLE_TAG_START) && (remained_len >= (body_len + TLV_HDR_LEN)) && (*elt->data == CIS_TUPLE_TAG_MACADDR)) { /* found MAC Address tuple and * get the MAC Address data */ mac_addr = (uint8 *)elt + CIS_TUPLE_TAG_MACADDR_OFF; break; } /* Go to next tuple if tuple value * is not MAC address type */ elt = (bcm_tlv_t *)((uint8 *)elt + (body_len + TLV_HDR_LEN)); remained_len -= (body_len + TLV_HDR_LEN); } if (mac_addr) { sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n")); } else { sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac->octet[0], mac->octet[1], mac->octet[2], mac->octet[3], mac->octet[4], mac->octet[5]); DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP," " Check module mac by initial value: " MACDBG "\n", __FUNCTION__, MAC2STRDBG(mac->octet))); } } fp_mac = filp_open(macfilepath, O_RDONLY, 0); if (!IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n")); kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf)); filp_close(fp_mac, NULL); if (strncmp(mac_buf, otp_mac_buf, 17) != 0) { DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n")); dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf)); } } return ret; }
static int wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist) { int i, j, match; int ret = 0; char mac_buf[MAX_NUM_OF_ASSOCLIST * sizeof(struct ether_addr) + sizeof(uint)] = {0}; struct maclist *assoc_maclist = (struct maclist *)mac_buf; /* set filtering mode */ if ((ret = wldev_ioctl(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode), true)) != 0) { DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__, ret)); return ret; } if (macmode != MACLIST_MODE_DISABLED) { /* set the MAC filter list */ if ((ret = wldev_ioctl(dev, WLC_SET_MACLIST, maclist, sizeof(int) + sizeof(struct ether_addr) * maclist->count, true)) != 0) { DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__, ret)); return ret; } /* get the current list of associated STAs */ assoc_maclist->count = MAX_NUM_OF_ASSOCLIST; if ((ret = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), false)) != 0) { DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__, ret)); return ret; } /* do we have any STA associated? */ if (assoc_maclist->count) { /* iterate each associated STA */ for (i = 0; i < assoc_maclist->count; i++) { match = 0; /* compare with each entry */ for (j = 0; j < maclist->count; j++) { DHD_INFO(("%s : associated="MACDBG " list="MACDBG "\n", __FUNCTION__, MAC2STRDBG(assoc_maclist->ea[i].octet), MAC2STRDBG(maclist->ea[j].octet))); if (memcmp(assoc_maclist->ea[i].octet, maclist->ea[j].octet, ETHER_ADDR_LEN) == 0) { match = 1; break; } } /* do conditional deauth */ /* "if not in the allow list" or "if in the deny list" */ if ((macmode == MACLIST_MODE_ALLOW && !match) || (macmode == MACLIST_MODE_DENY && match)) { scb_val_t scbval; scbval.val = htod32(1); memcpy(&scbval.ea, &assoc_maclist->ea[i], ETHER_ADDR_LEN); if ((ret = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scb_val_t), true)) != 0) DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n", __FUNCTION__, ret)); } } } } return ret; }
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac) { int ret = -1; unsigned char cis_buf[CIS_BUF_SIZE] = {0}; unsigned char mac_buf[20] = {0}; unsigned char otp_mac_buf[20] = {0}; const char *macfilepath = MACINFO_EFS; /* Try reading out from CIS */ cis_rw_t *cish = (cis_rw_t *)&cis_buf[8]; struct file *fp_mac = NULL; cish->source = 0; cish->byteoff = 0; cish->nbytes = sizeof(cis_buf); strcpy(cis_buf, "cisdump"); ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf, sizeof(cis_buf), 0, 0); if (ret < 0) { DHD_INFO(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n", __FUNCTION__, ret)); sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac->octet[0], mac->octet[1], mac->octet[2], mac->octet[3], mac->octet[4], mac->octet[5]); DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n", __FUNCTION__, MAC2STRDBG(mac->octet))); } else { int max, idx, macaddr_idx; #ifdef DUMP_CIS dhd_dump_cis(cis_buf, 48); #endif /* Find a new tuple tag */ max = sizeof(cis_buf) - 8; for (idx = 0; idx < max; idx++) { if (cis_buf[idx] == CIS_TUPLE_TAG_START) { if (cis_buf[idx + 2] == CIS_TUPLE_TAG_MACADDR && cis_buf[idx + 1] == 7) { macaddr_idx = idx + 3; /* found MAC Address tuple */ break; } } } if (idx < max) { sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", cis_buf[macaddr_idx], cis_buf[macaddr_idx + 1], cis_buf[macaddr_idx + 2], cis_buf[macaddr_idx + 3], cis_buf[macaddr_idx + 4], cis_buf[macaddr_idx + 5]); DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n")); } else { sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac->octet[0], mac->octet[1], mac->octet[2], mac->octet[3], mac->octet[4], mac->octet[5]); DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP," " Check module mac by initial value: " MACDBG "\n", __FUNCTION__, MAC2STRDBG(mac->octet))); } } fp_mac = filp_open(macfilepath, O_RDONLY, 0); if (!IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n")); kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf)); filp_close(fp_mac, NULL); if (strncmp(mac_buf, otp_mac_buf, 17) != 0) { DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n")); dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf)); } } return ret; }