/* * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2 * */ static int wl_android_set_mac_address_filter(struct net_device *dev, const char* str) { int i; int ret = 0; int macnum = 0; int macmode = MACLIST_MODE_DISABLED; struct maclist *list; char eabuf[ETHER_ADDR_STR_LEN]; /* string should look like below (macmode/macnum/maclist) */ /* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */ /* get the MAC filter mode */ macmode = bcm_atoi(strsep((char**)&str, " ")); if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) { DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__, macmode)); return -1; } macnum = bcm_atoi(strsep((char**)&str, " ")); if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) { DHD_ERROR(("%s : invalid number of MAC address entries %d\n", __FUNCTION__, macnum)); return -1; } /* allocate memory for the MAC list */ list = (struct maclist*)kmalloc(sizeof(int) + sizeof(struct ether_addr) * macnum, GFP_KERNEL); if (!list) { DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__)); return -1; } /* prepare the MAC list */ list->count = htod32(macnum); bzero((char *)eabuf, ETHER_ADDR_STR_LEN); for (i = 0; i < list->count; i++) { strncpy(eabuf, strsep((char**)&str, " "), ETHER_ADDR_STR_LEN - 1); if (!(ret = bcm_ether_atoe(eabuf, &list->ea[i]))) { DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n", __FUNCTION__, i, eabuf)); list->count--; break; } DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__, i, list->count, eabuf)); } /* set the list */ if ((ret = wl_android_set_ap_mac_list(dev, macmode, list)) != 0) DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__, ret)); kfree(list); return 0; }
int wldev_get_rx_rate_stats( struct net_device *dev, char *command, int total_len) { wl_scb_rx_rate_stats_t *rstats; struct ether_addr ea; char smbuf[WLC_IOCTL_SMLEN]; char eabuf[18] = {0, }; int bytes_written = 0; int error; memcpy(eabuf, command+strlen("RXRATESTATS")+1, 17); if (!bcm_ether_atoe(eabuf, &ea)) { WLDEV_ERROR(("Invalid MAC Address\n")); return -1; } error = wldev_iovar_getbuf(dev, "rx_rate_stats", &ea, ETHER_ADDR_LEN, smbuf, sizeof(smbuf), NULL); if (error < 0) { WLDEV_ERROR(("get rx_rate_stats failed = %d\n", error)); return -1; } rstats = (wl_scb_rx_rate_stats_t *)smbuf; bytes_written = sprintf(command, "1/%d/%d,", dtoh32(rstats->rx1mbps[0]), dtoh32(rstats->rx1mbps[1])); bytes_written += sprintf(command+bytes_written, "2/%d/%d,", dtoh32(rstats->rx2mbps[0]), dtoh32(rstats->rx2mbps[1])); bytes_written += sprintf(command+bytes_written, "5.5/%d/%d,", dtoh32(rstats->rx5mbps5[0]), dtoh32(rstats->rx5mbps5[1])); bytes_written += sprintf(command+bytes_written, "6/%d/%d,", dtoh32(rstats->rx6mbps[0]), dtoh32(rstats->rx6mbps[1])); bytes_written += sprintf(command+bytes_written, "9/%d/%d,", dtoh32(rstats->rx9mbps[0]), dtoh32(rstats->rx9mbps[1])); bytes_written += sprintf(command+bytes_written, "11/%d/%d,", dtoh32(rstats->rx11mbps[0]), dtoh32(rstats->rx11mbps[1])); bytes_written += sprintf(command+bytes_written, "12/%d/%d,", dtoh32(rstats->rx12mbps[0]), dtoh32(rstats->rx12mbps[1])); bytes_written += sprintf(command+bytes_written, "18/%d/%d,", dtoh32(rstats->rx18mbps[0]), dtoh32(rstats->rx18mbps[1])); bytes_written += sprintf(command+bytes_written, "24/%d/%d,", dtoh32(rstats->rx24mbps[0]), dtoh32(rstats->rx24mbps[1])); bytes_written += sprintf(command+bytes_written, "36/%d/%d,", dtoh32(rstats->rx36mbps[0]), dtoh32(rstats->rx36mbps[1])); bytes_written += sprintf(command+bytes_written, "48/%d/%d,", dtoh32(rstats->rx48mbps[0]), dtoh32(rstats->rx48mbps[1])); bytes_written += sprintf(command+bytes_written, "54/%d/%d", dtoh32(rstats->rx54mbps[0]), dtoh32(rstats->rx54mbps[1])); return bytes_written; }
static int wl_android_sta_diassoc(struct net_device *dev, const char* straddr) { scb_val_t scbval; DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__, straddr)); /* Unspecified reason */ scbval.val = htod32(1); bcm_ether_atoe(straddr, &scbval.ea); DHD_INFO(("%s: deauth STA: %02X:%02X:%02X:%02X:%02X:%02X\n", __FUNCTION__, scbval.ea.octet[0], scbval.ea.octet[1], scbval.ea.octet[2], scbval.ea.octet[3], scbval.ea.octet[4], scbval.ea.octet[5])); wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scb_val_t), true); return 1; }
int somc_get_mac_address(unsigned char *buf) { int ret = -EINVAL; int len; unsigned char macaddr_buf[MACADDR_BUF_LEN]; void *fp = NULL; struct ether_addr eth; if (!buf) return -EINVAL; fp = dhd_os_open_image(MACADDR_PATH); if (!fp) { WL_ERROR(("%s: file open error\n", __FUNCTION__)); goto err; } len = dhd_os_get_image_block(macaddr_buf, MACADDR_BUF_LEN, fp); if (len <= 0 || MACADDR_BUF_LEN <= len) { WL_ERROR(("%s: file read error\n", __FUNCTION__)); goto err; } macaddr_buf[len] = '\0'; /* convert mac address */ ret = !bcm_ether_atoe(macaddr_buf, ð); if (ret) { WL_ERROR(("%s: convert mac value fail\n", __FUNCTION__)); goto err; } memcpy(buf, eth.octet, ETHER_ADDR_LEN); err: if (fp) dhd_os_close_image(fp); return ret; }
static int dhd_preinit_proc(dhd_pub_t *dhd, int ifidx, char *name, char *value) { int var_int; wl_country_t cspec = {{0}, -1, {0}}; char *revstr; char *endptr = NULL; int iolen; char smbuf[WLC_IOCTL_SMLEN*2]; int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL}; #ifdef ROAM_AP_ENV_DETECTION int roam_env_mode = AP_ENV_INDETERMINATE; #endif /* ROAM_AP_ENV_DETECTION */ if (!strcmp(name, "country")) { revstr = strchr(value, '/'); if (revstr) { cspec.rev = strtoul(revstr + 1, &endptr, 10); memcpy(cspec.country_abbrev, value, WLC_CNTRY_BUF_SZ); cspec.country_abbrev[2] = '\0'; memcpy(cspec.ccode, cspec.country_abbrev, WLC_CNTRY_BUF_SZ); memset(smbuf, 0, sizeof(smbuf)); printf("config country code is country : %s, rev : %d !!\n", cspec.country_abbrev, cspec.rev); iolen = bcm_mkiovar("country", (char*)&cspec, sizeof(cspec), smbuf, sizeof(smbuf)); return dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, smbuf, iolen, TRUE, 0); } return dhd_wl_ioctl_cmd(dhd, WLC_SET_COUNTRY, value, WLC_CNTRY_BUF_SZ, TRUE, 0); } else if (!strcmp(name, "roam_scan_period")) { var_int = (int)simple_strtol(value, NULL, 0); return dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_SCAN_PERIOD, &var_int, sizeof(var_int), TRUE, 0); } else if (!strcmp(name, "roam_delta")) { struct { int val; int band; } x; x.val = (int)simple_strtol(value, NULL, 0); x.band = WLC_BAND_ALL; return dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, &x, sizeof(x), TRUE, 0); } else if (!strcmp(name, "roam_trigger")) { int ret = 0; roam_trigger[0] = (int)simple_strtol(value, NULL, 0); roam_trigger[1] = WLC_BAND_ALL; ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, &roam_trigger, sizeof(roam_trigger), TRUE, 0); #ifdef ROAM_AP_ENV_DETECTION if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) { char iovbuf[128]; bcm_mkiovar("roam_env_detection", (char *)&roam_env_mode, 4, iovbuf, sizeof(iovbuf)); if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) == BCME_OK) { dhd->roam_env_detection = TRUE; } else { dhd->roam_env_detection = FALSE; } } #endif /* ROAM_AP_ENV_DETECTION */ return ret; } else if (!strcmp(name, "PM")) { int ret = 0; var_int = (int)simple_strtol(value, NULL, 0); ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, &var_int, sizeof(var_int), TRUE, 0); #if defined(CONFIG_PM_LOCK) if (var_int == 0) { g_pm_control = TRUE; printk("%s var_int=%d don't control PM\n", __func__, var_int); } else { g_pm_control = FALSE; printk("%s var_int=%d do control PM\n", __func__, var_int); } #endif /* CONFIG_PM_LOCK */ return ret; } #ifdef WLBTAMP else if (!strcmp(name, "btamp_chan")) { int btamp_chan; int iov_len = 0; char iovbuf[128]; int ret; btamp_chan = (int)simple_strtol(value, NULL, 0); iov_len = bcm_mkiovar("btamp_chan", (char *)&btamp_chan, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0) < 0)) DHD_ERROR(("%s btamp_chan=%d set failed code %d\n", __FUNCTION__, btamp_chan, ret)); else DHD_ERROR(("%s btamp_chan %d set success\n", __FUNCTION__, btamp_chan)); } #endif /* WLBTAMP */ else if (!strcmp(name, "band")) { int ret; if (!strcmp(value, "auto")) var_int = WLC_BAND_AUTO; else if (!strcmp(value, "a")) var_int = WLC_BAND_5G; else if (!strcmp(value, "b")) var_int = WLC_BAND_2G; else if (!strcmp(value, "all")) var_int = WLC_BAND_ALL; else { printk("set band value should be one of the a or b or all\n"); var_int = WLC_BAND_AUTO; } if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, &var_int, sizeof(var_int), TRUE, 0)) < 0) printk(" set band err=%d\n", ret); return ret; } else if (!strcmp(name, "cur_etheraddr")) { struct ether_addr ea; char buf[32]; uint iovlen; int ret; bcm_ether_atoe(value, &ea); ret = memcmp(&ea.octet, dhd->mac.octet, ETHER_ADDR_LEN); if (ret == 0) { DHD_ERROR(("%s: Same Macaddr\n", __FUNCTION__)); return 0; } DHD_ERROR(("%s: Change Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", __FUNCTION__, ea.octet[0], ea.octet[1], ea.octet[2], ea.octet[3], ea.octet[4], ea.octet[5])); iovlen = bcm_mkiovar("cur_etheraddr", (char*)&ea, ETHER_ADDR_LEN, buf, 32); ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, iovlen, TRUE, 0); if (ret < 0) { DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); return ret; } else { memcpy(dhd->mac.octet, (void *)&ea, ETHER_ADDR_LEN); return ret; } } else if (!strcmp(name, "lpc")) { int ret = 0; char buf[32]; uint iovlen; var_int = (int)simple_strtol(value, NULL, 0); if (dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0) < 0) { DHD_ERROR(("%s: wl down failed\n", __FUNCTION__)); } iovlen=bcm_mkiovar("lpc", (char *)&var_int, 4, buf, sizeof(buf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, iovlen, TRUE, 0)) < 0) { DHD_ERROR(("%s Set lpc failed %d\n", __FUNCTION__, ret)); } if (dhd_wl_ioctl_cmd(dhd, WLC_UP, NULL, 0, TRUE, 0) < 0) { DHD_ERROR(("%s: wl up failed\n", __FUNCTION__)); } return ret; } else if (!strcmp(name, "vht_features")) { int ret = 0; char buf[32]; uint iovlen; var_int = (int)simple_strtol(value, NULL, 0); if (dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0) < 0) { DHD_ERROR(("%s: wl down failed\n", __FUNCTION__)); } iovlen=bcm_mkiovar("vht_features", (char *)&var_int, 4, buf, sizeof(buf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, iovlen, TRUE, 0)) < 0) { DHD_ERROR(("%s Set vht_features failed %d\n", __FUNCTION__, ret)); } if (dhd_wl_ioctl_cmd(dhd, WLC_UP, NULL, 0, TRUE, 0) < 0) { DHD_ERROR(("%s: wl up failed\n", __FUNCTION__)); } return ret; } else { uint iovlen; char iovbuf[WLC_IOCTL_SMLEN]; /* wlu_iovar_setint */ var_int = (int)simple_strtol(value, NULL, 0); /* Setup timeout bcn_timeout from dhd driver 4.217.48 */ if (!strcmp(name, "roam_off")) { /* Setup timeout if Beacons are lost to report link down */ if (var_int) { uint bcn_timeout = 2; bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); } } /* Setup timeout bcm_timeout from dhd driver 4.217.48 */ DHD_INFO(("%s:[%s]=[%d]\n", __FUNCTION__, name, var_int)); iovlen = bcm_mkiovar(name, (char *)&var_int, sizeof(var_int), iovbuf, sizeof(iovbuf)); return dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iovlen, TRUE, 0); } return 0; }
static void * chipattach(etc_info_t *etc, void *osh, void *regsva) { struct bcm4xxx *ch; bcmenetregs_t *regs; char name[16]; char *var; uint boardflags, boardtype; ET_TRACE(("et%d: chipattach: regsva 0x%lx\n", etc->unit, (ulong)regsva)); if ((ch = (struct bcm4xxx *)MALLOC(osh, sizeof(struct bcm4xxx))) == NULL) { ET_ERROR(("et%d: chipattach: out of memory, malloced %d bytes\n", etc->unit, MALLOCED(osh))); return (NULL); } bzero((char *)ch, sizeof(struct bcm4xxx)); ch->etc = etc; ch->et = etc->et; ch->osh = osh; /* store the pointer to the sw mib */ etc->mib = (void *)&ch->mib; /* get si handle */ if ((ch->sih = si_attach(etc->deviceid, ch->osh, regsva, PCI_BUS, NULL, &ch->vars, &ch->vars_size)) == NULL) { ET_ERROR(("et%d: chipattach: si_attach error\n", etc->unit)); goto fail; } /* We used to have an assert here like: * si_coreid(ch->sih) == ENET_CORE_ID * but srom-less systems and simulators don't have a way to * provide a default bar0window so we were relying on nvram * variables. At some point we decided that we could do away * with that since the wireless driver was simply doing a * setcore in attach. So we need to do the same here for * the ethernet. */ if ((regs = (bcmenetregs_t *)si_setcore(ch->sih, ENET_CORE_ID, etc->unit)) == NULL) { ET_ERROR(("et%d: chipattach: Could not setcore to the ENET core\n", etc->unit)); goto fail; } ch->regs = regs; etc->chip = ch->sih->chip; etc->chiprev = ch->sih->chiprev; etc->coreid = si_coreid(ch->sih); etc->corerev = si_corerev(ch->sih); etc->nicmode = !(ch->sih->bustype == SI_BUS); etc->coreunit = si_coreunit(ch->sih); etc->boardflags = getintvar(ch->vars, "boardflags"); etc->hwrxoff = HWRXOFF; boardflags = etc->boardflags; boardtype = ch->sih->boardtype; /* Backplane clock ticks per microsecs: used by gptimer, intrecvlazy */ etc->bp_ticks_usec = si_clock(ch->sih) / 1000000; /* get our local ether addr */ sprintf(name, "et%dmacaddr", etc->coreunit); var = getvar(ch->vars, name); if (var == NULL) { ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name)); goto fail; } bcm_ether_atoe(var, &etc->perm_etheraddr); if (ETHER_ISNULLADDR(&etc->perm_etheraddr)) { ET_ERROR(("et%d: chipattach: invalid format: %s=%s\n", etc->unit, name, var)); goto fail; } bcopy((char *)&etc->perm_etheraddr, (char *)&etc->cur_etheraddr, ETHER_ADDR_LEN); /* * Too much can go wrong in scanning MDC/MDIO playing "whos my phy?" . * Instead, explicitly require the environment var "et<coreunit>phyaddr=<val>". */ /* get our phyaddr value */ sprintf(name, "et%dphyaddr", etc->coreunit); var = getvar(ch->vars, name); if (var == NULL) { ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name)); goto fail; } etc->phyaddr = bcm_atoi(var) & EPHY_MASK; /* nvram says no phy is present */ if (etc->phyaddr == EPHY_NONE) { ET_ERROR(("et%d: chipattach: phy not present\n", etc->unit)); goto fail; } /* get our mdc/mdio port number */ sprintf(name, "et%dmdcport", etc->coreunit); var = getvar(ch->vars, name); if (var == NULL) { ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name)); goto fail; } etc->mdcport = bcm_atoi(var); /* configure pci core */ si_pci_setup(ch->sih, (1 << si_coreidx(ch->sih))); /* reset the enet core */ chipreset(ch); /* dma attach */ sprintf(name, "et%d", etc->coreunit); if ((ch->di = dma_attach(osh, name, ch->sih, (void *)®s->dmaregs.xmt, (void *)®s->dmaregs.rcv, NTXD, NRXD, RXBUFSZ, -1, NRXBUFPOST, HWRXOFF, &et_msg_level)) == NULL) { ET_ERROR(("et%d: chipattach: dma_attach failed\n", etc->unit)); goto fail; } etc->txavail[TX_Q0] = (uint *)&ch->di->txavail; /* set default sofware intmask */ ch->intmask = DEF_INTMASK; /* * For the 5222 dual phy shared mdio contortion, our phy is * on someone elses mdio pins. This other enet enet * may not yet be attached so we must defer the et_phyfind(). */ /* if local phy: reset it once now */ if (etc->mdcport == etc->coreunit) chipphyreset(ch, etc->phyaddr); #ifdef ETROBO /* * Broadcom Robo ethernet switch. */ if ((boardflags & BFL_ENETROBO) && (etc->phyaddr == EPHY_NOREG)) { /* Attach to the switch */ if (!(etc->robo = bcm_robo_attach(ch->sih, ch, ch->vars, (miird_f)bcm47xx_et_chops.phyrd, (miiwr_f)bcm47xx_et_chops.phywr))) { ET_ERROR(("et%d: chipattach: robo_attach failed\n", etc->unit)); goto fail; } /* Enable the switch and set it to a known good state */ if (bcm_robo_enable_device(etc->robo)) { ET_ERROR(("et%d: chipattach: robo_enable_device failed\n", etc->unit)); goto fail; } /* Configure the switch to do VLAN */ if ((boardflags & BFL_ENETVLAN) && bcm_robo_config_vlan(etc->robo, etc->perm_etheraddr.octet)) { ET_ERROR(("et%d: chipattach: robo_config_vlan failed\n", etc->unit)); goto fail; } /* Enable switching/forwarding */ if (bcm_robo_enable_switch(etc->robo)) { ET_ERROR(("et%d: chipattach: robo_enable_switch failed\n", etc->unit)); goto fail; } } #endif /* ETROBO */ #ifdef ETADM /* * ADMtek ethernet switch. */ if (boardflags & BFL_ENETADM) { /* Attach to the device */ if (!(ch->adm = adm_attach(ch->sih, ch->vars))) { ET_ERROR(("et%d: chipattach: adm_attach failed\n", etc->unit)); goto fail; } /* Enable the external switch and set it to a known good state */ if (adm_enable_device(ch->adm)) { ET_ERROR(("et%d: chipattach: adm_enable_device failed\n", etc->unit)); goto fail; } /* Configure the switch */ if ((boardflags & BFL_ENETVLAN) && adm_config_vlan(ch->adm)) { ET_ERROR(("et%d: chipattach: adm_config_vlan failed\n", etc->unit)); goto fail; } } #endif /* ETADM */ return ((void *)ch); fail: chipdetach(ch); return (NULL); }