void* wl_android_prealloc(int section, unsigned long size) { void *alloc_ptr = NULL; if (wifi_control_data && wifi_control_data->mem_prealloc) { alloc_ptr = wifi_control_data->mem_prealloc(section, size); if (alloc_ptr) { DHD_INFO(("success alloc section %d\n", section)); if (size != 0L) bzero(alloc_ptr, size); return alloc_ptr; } } DHD_ERROR(("can't alloc section %d\n", section)); return NULL; }
/** * Local (static) function definitions */ static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len) { int link_speed; int bytes_written; int error; error = wldev_get_link_speed(net, &link_speed); if (error) return -1; /* Convert Kbps to Android Mbps */ link_speed = link_speed / 1000; bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); return bytes_written; }
static int wl_android_set_ssid(struct net_device *dev, const char* hapd_ssid) { wlc_ssid_t ssid; s32 ret; ssid.SSID_len = strlen(hapd_ssid); bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len); DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__, ssid.SSID)); ret = wldev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t), true); if (ret < 0) { DHD_ERROR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__, ret)); } return 1; }
static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len) { int ret = 0; int suspend_flag; suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0'; if (suspend_flag != 0) suspend_flag = 1; if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__, suspend_flag)); else DHD_ERROR(("%s: failed %d\n",__FUNCTION__,ret)); return ret; }
int dhd_write_macaddr(char *addr) { struct file *fp = NULL; char filepath[40] = {0}; char macbuffer[18]= {0}; int ret = 0; mm_segment_t oldfs= {0}; strcpy(filepath, "/data/.mac.info"); fp = filp_open(filepath, O_RDONLY, 0); if(IS_ERR(fp)) { /* File Doesn't Exist. Create and write mac addr.*/ fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); if(IS_ERR(fp)) { fp = NULL; DHD_ERROR(("[WIFI] %s: File open error \n", filepath)); return -1; } oldfs = get_fs(); set_fs(get_ds()); sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n", addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]); if(fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos); DHD_INFO(("[WIFI] Mac address [%s] written into File:%s \n", macbuffer, filepath)); } set_fs(oldfs); } if(fp) filp_close(fp, NULL); return 0; }
void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size) { void *alloc_ptr = NULL; struct wifi_platform_data *plat_data; if (!adapter || !adapter->wifi_plat_data) return NULL; plat_data = adapter->wifi_plat_data; if (plat_data->mem_prealloc) { alloc_ptr = plat_data->mem_prealloc(section, size); if (alloc_ptr) { DHD_INFO(("success alloc section %d\n", section)); if (size != 0L) bzero(alloc_ptr, size); return alloc_ptr; } } return NULL; }
/* Deinit Flow Ring specific data structures */ void dhd_flow_rings_deinit(dhd_pub_t *dhdp) { uint16 idx; uint32 flow_ring_table_sz; uint32 if_flow_lkup_sz; flow_ring_table_t *flow_ring_table; DHD_INFO(("dhd_flow_rings_deinit\n")); if (dhdp->flow_ring_table != NULL) { ASSERT(dhdp->num_flow_rings > 0); flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; for (idx = 0; idx < dhdp->num_flow_rings; idx++) { if (flow_ring_table[idx].active) { dhd_bus_clean_flow_ring(dhdp->bus, idx); } ASSERT(flow_queue_empty(&flow_ring_table[idx].queue)); /* Deinit flow ring queue locks before destroying flow ring table */ dhd_os_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].queue.lock); flow_ring_table[idx].queue.lock = NULL; } /* Destruct the flow ring table */ flow_ring_table_sz = dhdp->num_flow_rings * sizeof(flow_ring_table_t); MFREE(dhdp->osh, dhdp->flow_ring_table, flow_ring_table_sz); dhdp->flow_ring_table = NULL; } /* Destruct the per interface flow lkup table */ if (dhdp->if_flow_lkup != NULL) { if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS; MFREE(dhdp->osh, dhdp->if_flow_lkup, if_flow_lkup_sz); dhdp->if_flow_lkup = NULL; } /* Destruct the flowid allocator */ if (dhdp->flowid_allocator != NULL) dhdp->flowid_allocator = id16_map_fini(dhdp->osh, dhdp->flowid_allocator); dhdp->num_flow_rings = 0U; }
/** * Schedules a tasklet to run when receiving an interrupt on the * <code>HOST_WAKE</code> GPIO pin. * @param irq Not used. * @param dev_id Not used. */ static irqreturn_t dhd_hostwakeup_isr(int irq, void *dev_id) { int gpio = 0; gpio = gpio_get_value(GPIO_WLAN_HOST_WAKE); printk(KERN_ERR "[%s] HostWakeup Get GPIO %d: %d\n", __func__, GPIO_WLAN_HOST_WAKE, gpio); #if !defined(CONFIG_LGE_BCM432X_PATCH) set_irq_type(dhd_wifi_sleep->host_wake_irq, gpio ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); #endif /* CONFIG_LGE_BCM432X_PATCH */ if (!gpio) { DHD_INFO(("[WiFi] complete on host-wakeup \n")); return IRQ_HANDLED; } /* schedule a tasklet to handle the change in the host wake line */ return IRQ_HANDLED; }
/* Handle a STA interface link status update */ int dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex, uint8 status) { if_flow_lkup_t *if_flow_lkup; ASSERT(ifindex < DHD_MAX_IFS); if (ifindex >= DHD_MAX_IFS) return BCME_BADARG; if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; DHD_INFO(("%s: ifindex %d status %d\n", __FUNCTION__, ifindex, status)); if (if_flow_lkup[ifindex].role == WLC_E_IF_ROLE_STA) { if (status) if_flow_lkup[ifindex].status = TRUE; else if_flow_lkup[ifindex].status = FALSE; } return BCME_OK; }
static int wl_android_get_country_rev( struct net_device *dev, char *command, int total_len) { int error; int bytes_written; char smbuf[WLC_IOCTL_SMLEN]; wl_country_t cspec; error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), smbuf, sizeof(smbuf), NULL); if (error) { DHD_ERROR(("%s: get country failed code %d\n", __func__, error)); return -1; } else { DHD_INFO(("%s: get country '%s %d'\n", __func__, smbuf, smbuf[WLC_CNTRY_BUF_SZ])); } bytes_written = snprintf(command, total_len, "%s %s %d", CMD_COUNTRYREV_GET, smbuf, smbuf[WLC_CNTRY_BUF_SZ]); return bytes_written; }
static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len) { int suspend_flag; int ret_now; int ret = 0; suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; if (suspend_flag != 0) suspend_flag = 1; ret_now = net_os_set_suspend_disable(dev, suspend_flag); if (ret_now != suspend_flag) { if (!(ret = net_os_set_suspend(dev, ret_now))) DHD_INFO(("%s: Suspend Flag %d -> %d\n", __FUNCTION__, ret_now, suspend_flag)); else DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); } return ret; }
/* Delete all Flow rings assocaited with the given Interface */ void dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex) { uint32 id; flow_ring_table_t *flow_ring_table; DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex)); ASSERT(ifindex < DHD_MAX_IFS); if (!dhdp->flow_ring_table) return; flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; for (id = 0; id < dhdp->num_flow_rings; id++) { if (flow_ring_table[id].active && (flow_ring_table[id].flow_info.ifindex == ifindex)) { dhd_bus_flow_ring_delete_request(dhdp->bus, (void *) &flow_ring_table[id]); } } }
static int wl_android_get_full_roam_scan_period( struct net_device *dev, char *command, int total_len) { int error; int bytes_written; int full_roam_scan_period = 0; error = wldev_iovar_getint(dev, "fullroamperiod", &full_roam_scan_period); if (error) { DHD_ERROR(("%s: get full roam scan period failed code %d\n", __func__, error)); return -1; } else { DHD_INFO(("%s: get full roam scan period %d\n", __func__, full_roam_scan_period)); } bytes_written = snprintf(command, total_len, "%s %d", CMD_FULLROAMSCANPERIOD_GET, full_roam_scan_period); return bytes_written; }
int WriteRDWR_Macaddr(struct ether_addr *mac) { char* filepath = "/data/.mac.info"; struct file *fp_mac = NULL; char buf[18] = {0}; mm_segment_t oldfs = {0}; int ret = -1; if ((g_iMacFlag != MACADDR_COB) && (g_iMacFlag != MACADDR_MOD)) return 0; sprintf(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]); fp_mac = filp_open(filepath, O_RDWR | O_CREAT, 0666); // File is always created. if(IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); return -1; } else { oldfs = get_fs(); set_fs(get_ds()); if(fp_mac->f_mode & FMODE_WRITE) { ret = fp_mac->f_op->write(fp_mac, (const char *)buf, sizeof(buf), &fp_mac->f_pos); if(ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", buf, filepath)); else DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", buf, filepath)); } set_fs(oldfs); filp_close(fp_mac, NULL); } return 0; }
static int wl_android_get_rssi(struct net_device *net, char *command, int total_len) { wlc_ssid_t ssid = {0}; int rssi; int bytes_written = 0; int error; error = wldev_get_rssi(net, &rssi); if (error) return -1; error = wldev_get_ssid(net, &ssid); if (error) return -1; if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); } else { memcpy(command, ssid.SSID, ssid.SSID_len); bytes_written = ssid.SSID_len; } bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi); DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); return bytes_written; }
pkt_frag_t pkt_frag_info(osl_t *osh, void *p) { uint8 *frame; int length; uint8 *pt; /* Pointer to type field */ uint16 ethertype; struct ipv4_hdr *iph; /* IP frame pointer */ int ipl; /* IP frame length */ uint16 iph_frag; ASSERT(osh && p); frame = PKTDATA(osh, p); length = PKTLEN(osh, p); /* Process Ethernet II or SNAP-encapsulated 802.3 frames */ if (length < ETHER_HDR_LEN) { DHD_INFO(("%s: short eth frame (%d)\n", __FUNCTION__, length)); return DHD_PKT_FRAG_NONE; } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) { /* Frame is Ethernet II */ pt = frame + ETHER_TYPE_OFFSET; } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN && !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) { pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN; } else { DHD_INFO(("%s: non-SNAP 802.3 frame\n", __FUNCTION__)); return DHD_PKT_FRAG_NONE; } ethertype = ntoh16(*(uint16 *)pt); /* Skip VLAN tag, if any */ if (ethertype == ETHER_TYPE_8021Q) { pt += VLAN_TAG_LEN; if (pt + ETHER_TYPE_LEN > frame + length) { DHD_INFO(("%s: short VLAN frame (%d)\n", __FUNCTION__, length)); return DHD_PKT_FRAG_NONE; } ethertype = ntoh16(*(uint16 *)pt); } if (ethertype != ETHER_TYPE_IP) { DHD_INFO(("%s: non-IP frame (ethertype 0x%x, length %d)\n", __FUNCTION__, ethertype, length)); return DHD_PKT_FRAG_NONE; } iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN); ipl = (uint)(length - (pt + ETHER_TYPE_LEN - frame)); /* We support IPv4 only */ if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) { DHD_INFO(("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl)); return DHD_PKT_FRAG_NONE; } iph_frag = ntoh16(iph->frag); if (iph_frag & IPV4_FRAG_DONT) { return DHD_PKT_FRAG_NONE; } else if ((iph_frag & IPV4_FRAG_MORE) == 0) { return DHD_PKT_FRAG_LAST; } else { return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST; } }
int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac) { struct file *fp = NULL; char macbuffer[18] = {0}; mm_segment_t oldfs = {0}; char randommac[3] = {0}; char buf[18] = {0}; char *filepath_efs = MACINFO_EFS; int is_zeromac = 0; int ret = 0; /* MAC address copied from efs/wifi.mac.info */ fp = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp)) { /* File Doesn't Exist. Create and write mac addr. */ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } oldfs = get_fs(); set_fs(get_ds()); /* Generating the Random Bytes for * 3 last octects of the MAC address */ get_random_bytes(randommac, 3); sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n", 0x60, 0xd0, 0xa9, randommac[0], randommac[1], randommac[2]); DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer)); if (fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s]" " Failed to write into File:" " %s\n", macbuffer, filepath_efs)); else DHD_ERROR(("[WIFI] Mac address [%s]" " written into File: %s\n", macbuffer, filepath_efs)); } set_fs(oldfs); } else { /* Reading the MAC Address from .mac.info file * (the existed file or just created file) */ ret = kernel_read(fp, 0, buf, 18); /* to prevent abnormal string display when mac address * is displayed on the screen. */ buf[17] = '\0'; /* Remove security log */ /* DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf, * strncmp(buf, "00:00:00:00:00:00", 17))); */ if ((buf[0] == '\0') || (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) { is_zeromac = 1; } } if (ret) sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); else DHD_INFO(("dhd_bus_start: Reading from the" " '%s' returns 0 bytes\n", filepath_efs)); if (fp) filp_close(fp, NULL); if (!is_zeromac) { /* Writing Newly generated MAC ID to the Dongle */ if (_dhd_set_mac_address(dhd, 0, mac) == 0) DHD_INFO(("dhd_bus_start: MACID is overwritten\n")); else DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() " "failed\n")); } else { DHD_ERROR(("dhd_bus_start:Is ZeroMAC BypassWrite.mac.info!\n")); } return 0; }
int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac) { struct file *fp_mac = NULL; struct file *fp_nvm = NULL; char macbuffer[18] = {0}; char randommac[3] = {0}; char buf[18] = {0}; char *filepath_data = MACINFO; char *filepath_efs = MACINFO_EFS; #ifdef CONFIG_TARGET_LOCALE_NA char *nvfilepath = "/data/misc/wifi/.nvmac.info"; #else char *nvfilepath = "/efs/wifi/.nvmac.info"; #endif char cur_mac[128] = {0}; char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38}; char cur_macbuffer[18] = {0}; int ret = -1; g_imac_flag = MACADDR_NONE; fp_nvm = filp_open(nvfilepath, O_RDONLY, 0); if (IS_ERR(fp_nvm)) { /* file does not exist */ /* read MAC Address */ strcpy(cur_mac, "cur_etheraddr"); ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac, sizeof(cur_mac), 0, 0); if (ret < 0) { DHD_ERROR(("Current READ MAC error \r\n")); memset(cur_mac, 0, ETHER_ADDR_LEN); return -1; } else { DHD_ERROR(("MAC (OTP) : " "[%02X:%02X:%02X:%02X:%02X:%02X] \r\n", cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3], cur_mac[4], cur_mac[5])); } sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n", cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3], cur_mac[4], cur_mac[5]); fp_mac = filp_open(filepath_data, O_RDONLY, 0); if (IS_ERR(fp_mac)) { /* file does not exist */ /* read mac is the dummy mac (00:90:4C:C5:12:38) */ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0) g_imac_flag = MACADDR_MOD_RANDOM; else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0) g_imac_flag = MACADDR_MOD_RANDOM; else g_imac_flag = MACADDR_MOD; } else { int is_zeromac; ret = kernel_read(fp_mac, 0, buf, 18); filp_close(fp_mac, NULL); buf[17] = '\0'; is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17); DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n", buf, is_zeromac)); if (is_zeromac == 0) { DHD_ERROR(("Zero MAC detected." " Trying Random MAC.\n")); g_imac_flag = MACADDR_MOD_RANDOM; } else { sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); /* current MAC address is same as previous one */ if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) { g_imac_flag = MACADDR_NONE; } else { /* change MAC address */ if (_dhd_set_mac_address(dhd, 0, mac) == 0) { DHD_INFO(("%s: MACID is" " overwritten\n", __FUNCTION__)); g_imac_flag = MACADDR_MOD; } else { DHD_ERROR(("%s: " "_dhd_set_mac_address()" " failed\n", __FUNCTION__)); g_imac_flag = MACADDR_NONE; } } } } fp_mac = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp_mac)) { /* file does not exist */ /* read mac is the dummy mac (00:90:4C:C5:12:38) */ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0) g_imac_flag = MACADDR_MOD_RANDOM; else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0) g_imac_flag = MACADDR_MOD_RANDOM; else g_imac_flag = MACADDR_MOD; } else { int is_zeromac; ret = kernel_read(fp_mac, 0, buf, 18); filp_close(fp_mac, NULL); buf[17] = '\0'; is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17); DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n", buf, is_zeromac)); if (is_zeromac == 0) { DHD_ERROR(("Zero MAC detected." " Trying Random MAC.\n")); g_imac_flag = MACADDR_MOD_RANDOM; } else { sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); /* current MAC address is same as previous one */ if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) { g_imac_flag = MACADDR_NONE; } else { /* change MAC address */ if (_dhd_set_mac_address(dhd, 0, mac) == 0) { DHD_INFO(("%s: MACID is" " overwritten\n", __FUNCTION__)); g_imac_flag = MACADDR_MOD; } else { DHD_ERROR(("%s: " "_dhd_set_mac_address()" " failed\n", __FUNCTION__)); g_imac_flag = MACADDR_NONE; } } } } } else { /* COB type. only COB. */ /* Reading the MAC Address from .nvmac.info file * (the existed file or just created file) */ ret = kernel_read(fp_nvm, 0, buf, 18); /* to prevent abnormal string display when mac address * is displayed on the screen. */ buf[17] = '\0'; DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf, strncmp(buf, "00:00:00:00:00:00", 17))); if ((buf[0] == '\0') || (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) { g_imac_flag = MACADDR_COB_RANDOM; } else { sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); /* Writing Newly generated MAC ID to the Dongle */ if (_dhd_set_mac_address(dhd, 0, mac) == 0) { DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__)); g_imac_flag = MACADDR_COB; } else { DHD_ERROR(("%s: _dhd_set_mac_address()" " failed\n", __FUNCTION__)); } } filp_close(fp_nvm, NULL); } if ((g_imac_flag == MACADDR_COB_RANDOM) || (g_imac_flag == MACADDR_MOD_RANDOM)) { get_random_bytes(randommac, 3); sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n", 0x60, 0xd0, 0xa9, randommac[0], randommac[1], randommac[2]); DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer)); sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); if (_dhd_set_mac_address(dhd, 0, mac) == 0) { DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__)); g_imac_flag = MACADDR_COB; } else { DHD_ERROR(("%s: _dhd_set_mac_address() failed\n", __FUNCTION__)); } } return 0; }
int dhd_write_rdwr_macaddr(struct ether_addr *mac) { char *filepath_data = MACINFO; char *filepath_efs = MACINFO_EFS; struct file *fp_mac = NULL; char buf[18] = {0}; mm_segment_t oldfs = {0}; int ret = -1; if ((g_imac_flag != MACADDR_COB) && (g_imac_flag != MACADDR_MOD)) return 0; sprintf(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]); /* /efs/wifi/.mac.info will be created */ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data)); return -1; } else { oldfs = get_fs(); set_fs(get_ds()); if (fp_mac->f_mode & FMODE_WRITE) { ret = fp_mac->f_op->write(fp_mac, (const char *)buf, sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed" " to write into File: %s\n", buf, filepath_data)); else DHD_INFO(("[WIFI] Mac address [%s] written" " into File: %s\n", buf, filepath_data)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* /data/.mac.info will be created */ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } else { oldfs = get_fs(); set_fs(get_ds()); if (fp_mac->f_mode & FMODE_WRITE) { ret = fp_mac->f_op->write(fp_mac, (const char *)buf, sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed" " to write into File: %s\n", buf, filepath_efs)); else DHD_INFO(("[WIFI] Mac address [%s] written" " into File: %s\n", buf, filepath_efs)); } set_fs(oldfs); filp_close(fp_mac, NULL); } return 0; }
int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac) { struct file *fp = NULL; char macbuffer[18] = {0}; mm_segment_t oldfs = {0}; char randommac[3] = {0}; char buf[18] = {0}; char *filepath_efs = MACINFO_EFS; int ret = 0; fp = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp)) { start_readmac: /* File Doesn't Exist. Create and write mac addr. */ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } oldfs = get_fs(); set_fs(get_ds()); /* Generating the Random Bytes for 3 last octects of the MAC address */ get_random_bytes(randommac, 3); sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n", 0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]); DHD_ERROR(("[WIFI]The Random Generated MAC ID: %s\n", macbuffer)); if (fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos); if (ret < 0) DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath_efs)); else DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath_efs)); } set_fs(oldfs); /* Reading the MAC Address from .mac.info file ( the existed file or just created file) */ ret = kernel_read(fp, 0, buf, 18); } else { /* Reading the MAC Address from .mac.info file( the existed file or just created file) */ ret = kernel_read(fp, 0, buf, 18); /* to prevent abnormal string display * when mac address is displayed on the screen. */ buf[17] = '\0'; if (strncmp(buf, "00:00:00:00:00:00", 17) < 1) { DHD_ERROR(("goto start_readmac \r\n")); filp_close(fp, NULL); goto start_readmac; } } if (ret) sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]), (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); else DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs)); if (fp) filp_close(fp, NULL); /* Writing Newly generated MAC ID to the Dongle */ if (_dhd_set_mac_address(dhd, 0, mac) == 0) DHD_INFO(("dhd_bus_start: MACID is overwritten\n")); else DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n")); return 0; }
uint32 sec_save_wlinfo(char* firm_ver, char* dhd_ver, char* nvram_p) { struct file *fp = NULL; struct file *nvfp = NULL; char *filepath = "/data/.wifiver.info"; int min_len, str_len = 0; int ret = 0; char* nvram_buf; char temp_buf[256]; DHD_TRACE(("[WIFI] %s: Entered.\n", __FUNCTION__)); DHD_INFO(("[WIFI] firmware version : %s\n", firm_ver)); DHD_INFO(("[WIFI] dhd driver version : %s\n", dhd_ver)); DHD_INFO(("[WIFI] nvram path : %s\n", nvram_p)); memset(version_info,0,sizeof(version_info)); if(strlen(dhd_ver)){ min_len = min(strlen(dhd_ver) , max_len(temp_buf, DHD_prefix)); min_len += strlen(DHD_prefix) + 3; DHD_INFO(("[WIFI] DHD ver length : %d\n", min_len)); snprintf(version_info+str_len, min_len, DHD_prefix " %s\n",dhd_ver); str_len = strlen(version_info); DHD_INFO(("[WIFI] version_info len : %d\n", str_len)); DHD_INFO(("[WIFI] version_info : %s\n", version_info)); }else{ DHD_ERROR(("[WIFI] Driver version is missing.\n")); } if(strlen(firm_ver)){ min_len = min(strlen(firm_ver) , max_len(temp_buf, Firm_prefix)); min_len += strlen(Firm_prefix) + 3; DHD_INFO(("[WIFI] firmware ver length : %d\n", min_len)); snprintf(version_info+str_len, min_len, Firm_prefix " %s\n",firm_ver); str_len = strlen(version_info); DHD_INFO(("[WIFI] version_info len : %d\n", str_len)); DHD_INFO(("[WIFI] version_info : %s\n", version_info)); }else{ DHD_ERROR(("[WIFI] Firmware version is missing.\n")); } if(nvram_p){ memset(temp_buf,0,sizeof(temp_buf)); nvfp = filp_open(nvram_p, O_RDONLY, 0); if (IS_ERR(nvfp) || (nvfp == NULL)) { DHD_ERROR(("[WIFI] %s: Nvarm File open failed.\n", __FUNCTION__)); return -1; } else { ret = kernel_read(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf)); filp_close(nvfp, NULL); } if(strlen(temp_buf)){ nvram_buf = temp_buf; bcmstrtok(&nvram_buf, "\n", 0); DHD_INFO(("[WIFI] nvram tolkening : %s(%d) \n", temp_buf, strlen(temp_buf))); snprintf(version_info+str_len, tstr_len(temp_buf, Nv_prefix), Nv_prefix " %s\n", temp_buf); str_len = strlen(version_info); DHD_INFO(("[WIFI] version_info : %s\n", version_info)); DHD_INFO(("[WIFI] version_info len : %d, nvram len : %d\n", str_len, strlen(temp_buf))); }else{ DHD_ERROR(("[WIFI] No info is missing.\n")); } }else{ DHD_ERROR(("[WIFI] No nvram path\n")); } DHD_INFO(("[WIFI] version_info : %s, strlen : %d\n", version_info,strlen(version_info))); fp = filp_open(filepath, O_RDONLY, 0); if (fp != NULL) { if (IS_ERR(fp) || (fp == NULL)) { DHD_INFO(("[WIFI] %s: File open failed.\n", __FUNCTION__)); } else { memset(version_old_info, 0, sizeof(version_old_info)); ret = kernel_read(fp, fp->f_pos, version_old_info, sizeof(version_info)); filp_close(fp, NULL); DHD_INFO(("[WIFI] kernel_read ret : %d.\n", ret)); if(strcmp(version_info,version_old_info) == 0){ DHD_ERROR(("[WIFI] %s: : already saved.\n", __FUNCTION__)); return 0; } } } fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("[WIFI] %s: File open failed.\n", __FUNCTION__)); } else { ret = write_filesystem(fp, fp->f_pos, version_info, sizeof(version_info)); DHD_INFO(("[WIFI] sec_save_wlinfo done. ret : %d\n",ret)); DHD_ERROR(("[WIFI] save .wifiver.info file.\n")); filp_close(fp, NULL); } return ret; }
int sec_get_param(dhd_pub_t *dhd, int mode) { struct file *fp = NULL; char *filepath = NULL; int val, ret = 0; if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) || (mode >= PARAM_LAST_VALUE)) { DHD_ERROR(("[WIFI] %s: invalid argument\n", __FUNCTION__)); return -EINVAL; } switch (mode) { case SET_PARAM_BUS_TXGLOM_MODE: filepath = "/data/.bustxglom.info"; break; case SET_PARAM_ROAMOFF: filepath = "/data/.roamoff.info"; break; #ifdef USE_WL_FRAMEBURST case SET_PARAM_FRAMEBURST: filepath = "/data/.frameburst.info"; break; #endif /* USE_WL_FRAMEBURST */ #ifdef USE_WL_TXBF case SET_PARAM_TXBF: filepath = "/data/.txbf.info"; break; #endif /* USE_WL_TXBF */ default: return -EINVAL; } fp = filp_open(filepath, O_RDONLY, 0); if (IS_ERR(fp) || (fp == NULL)) { ret = -EIO; } else { ret = kernel_read(fp, fp->f_pos, (char *)&val, 4); filp_close(fp, NULL); } if (ret < 0) { /* File operation is failed so we will return default value */ switch (mode) { case SET_PARAM_BUS_TXGLOM_MODE: val = CUSTOM_GLOM_SETTING; break; case SET_PARAM_ROAMOFF: #ifdef ROAM_ENABLE val = 0; #elif defined(DISABLE_BUILTIN_ROAM) val = 1; #else val = 0; #endif /* ROAM_ENABLE */ break; #ifdef USE_WL_FRAMEBURST case SET_PARAM_FRAMEBURST: val = 1; break; #endif /* USE_WL_FRAMEBURST */ #ifdef USE_WL_TXBF case SET_PARAM_TXBF: val = 1; break; #endif /* USE_WL_TXBF */ } DHD_INFO(("[WIFI] %s: File open failed, file path=%s," " default value=%d\n", __FUNCTION__, filepath, val)); return val; } val = bcm_atoi((char *)&val); DHD_INFO(("[WIFI] %s: %s = %d\n", __FUNCTION__, filepath, val)); switch (mode) { case SET_PARAM_ROAMOFF: #ifdef USE_WL_FRAMEBURST case SET_PARAM_FRAMEBURST: #endif /* USE_WL_FRAMEBURST */ #ifdef USE_WL_TXBF case SET_PARAM_TXBF: #endif /* USE_WL_TXBF */ val = val ? 1 : 0; break; } return val; }
int dhd_write_macaddr(struct ether_addr *mac) { char *filepath_data = MACINFO; char *filepath_efs = MACINFO_EFS; struct file *fp_mac = NULL; char buf[18] = {0}; mm_segment_t oldfs = {0}; int ret = -1; int retry_count = 0; startwrite: sprintf(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]); /* File will be created /data/.mac.info. */ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data)); return -1; } else { oldfs = get_fs(); set_fs(get_ds()); if (fp_mac->f_mode & FMODE_WRITE) { ret = fp_mac->f_op->write(fp_mac, (const char *)buf, sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to" " write into File: %s\n", buf, filepath_data)); else DHD_INFO(("[WIFI] Mac address [%s] written" " into File: %s\n", buf, filepath_data)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* check .mac.info file is 0 byte */ fp_mac = filp_open(filepath_data, O_RDONLY, 0); ret = kernel_read(fp_mac, 0, buf, 18); if ((ret == 0) && (retry_count++ < 3)) { filp_close(fp_mac, NULL); goto startwrite; } filp_close(fp_mac, NULL); /* end of /data/.mac.info */ if (filepath_efs == NULL) { DHD_ERROR(("[WIFI]%s : no efs filepath", __func__)); return 0; } /* File will be created /efs/wifi/.mac.info. */ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } else { oldfs = get_fs(); set_fs(get_ds()); if (fp_mac->f_mode & FMODE_WRITE) { ret = fp_mac->f_op->write(fp_mac, (const char *)buf, sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to" " write into File: %s\n", buf, filepath_efs)); else DHD_INFO(("[WIFI] Mac address [%s] written" " into File: %s\n", buf, filepath_efs)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* check .mac.info file is 0 byte */ fp_mac = filp_open(filepath_efs, O_RDONLY, 0); ret = kernel_read(fp_mac, 0, buf, 18); if ((ret == 0) && (retry_count++ < 3)) { filp_close(fp_mac, NULL); goto startwrite; } filp_close(fp_mac, NULL); return 0; }
int dhd_read_macaddr(dhd_info_t *dhd) { struct file *fp = NULL; struct file *fpnv = NULL; char macbuffer[18] = {0}; mm_segment_t oldfs = {0}; char randommac[3] = {0}; char buf[18] = {0}; char* filepath = "/data/.mac.info"; char* nvfilepath = "/data/misc/wifi/.nvmac.info"; int ret; //MAC address copied from nv fpnv = filp_open(nvfilepath, O_RDONLY, 0); if (IS_ERR(fpnv)) { start_readmac: fpnv = NULL; fp = filp_open(filepath, O_RDONLY, 0); if (IS_ERR(fp)) { /* File Doesn't Exist. Create and write mac addr.*/ fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); if(IS_ERR(fp)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); return -1; } oldfs = get_fs(); set_fs(get_ds()); /* Generating the Random Bytes for 3 last octects of the MAC address */ get_random_bytes(randommac, 3); sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n", 0x60,0xd0,0xa9,randommac[0],randommac[1],randommac[2]); DHD_INFO(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer)); printk("[WIFI] The Random Generated MAC ID : %s\n", macbuffer); if(fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos); if(ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", macbuffer, filepath)); else DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", macbuffer, filepath)); } set_fs(oldfs); } /* Reading the MAC Address from .mac.info file( the existed file or just created file)*/ //rtn_value=kernel_read(fp, fp->f_pos, buf, 18); ret = kernel_read(fp, 0, buf, 18); } else { /* Reading the MAC Address from .nvmac.info file( the existed file or just created file)*/ ret = kernel_read(fpnv, 0, buf, 18); buf[17] ='\n'; // to prevent abnormal string display when mac address is displayed on the screen. printk("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17)); if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) { filp_close(fpnv, NULL); goto start_readmac; } fp = filp_open(filepath, O_RDONLY, 0); if (IS_ERR(fp)) // If you want to write MAC address to /data/.mac.info once, { fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); if(IS_ERR(fp)) { DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); return -1; } oldfs = get_fs(); set_fs(get_ds()); if(fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)buf, sizeof(buf), &fp->f_pos); if(ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", buf, filepath)); else DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", buf, filepath)); } set_fs(oldfs); } ret = kernel_read(fp, 0, buf, 18); } if(ret) sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X", &dhd->pub.mac.octet[0], &dhd->pub.mac.octet[1], &dhd->pub.mac.octet[2], &dhd->pub.mac.octet[3], &dhd->pub.mac.octet[4], &dhd->pub.mac.octet[5]); else DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath)); if (fp) filp_close(fp, NULL); if (fpnv) filp_close(fpnv, NULL); /* Writing Newly generated MAC ID to the Dongle */ if (0 == _dhd_set_mac_address(dhd, 0, &dhd->pub.mac)) DHD_INFO(("dhd_bus_start: MACID is overwritten\n")); else DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n")); return 0; }
/* Allocate Flow ID */ static INLINE uint16 dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da) { flow_hash_info_t *fl_hash_node, *cur; if_flow_lkup_t *if_flow_lkup; int hash; uint16 flowid; unsigned long flags; fl_hash_node = (flow_hash_info_t *) MALLOC(dhdp->osh, sizeof(flow_hash_info_t)); memcpy(fl_hash_node->flow_info.da, da, sizeof(fl_hash_node->flow_info.da)); DHD_FLOWID_LOCK(dhdp->flowid_lock, flags); ASSERT(dhdp->flowid_allocator != NULL); flowid = id16_map_alloc(dhdp->flowid_allocator); DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags); if (flowid == FLOWID_INVALID) { MFREE(dhdp->osh, fl_hash_node, sizeof(flow_hash_info_t)); DHD_ERROR(("%s: cannot get free flowid \n", __FUNCTION__)); return FLOWID_INVALID; } fl_hash_node->flowid = flowid; fl_hash_node->flow_info.tid = prio; fl_hash_node->flow_info.ifindex = ifindex; fl_hash_node->next = NULL; DHD_FLOWID_LOCK(dhdp->flowid_lock, flags); if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; if (DHD_IF_ROLE_STA(if_flow_lkup[ifindex].role)) { /* For STA non TDLS dest we allocate entry based on prio only */ #ifdef WLTDLS if (dhdp->peer_tbl.tdls_peer_count && (is_tdls_destination(dhdp, da))) { hash = DHD_FLOWRING_HASHINDEX(da, prio); cur = if_flow_lkup[ifindex].fl_hash[hash]; if (cur) { while (cur->next) { cur = cur->next; } cur->next = fl_hash_node; } else { if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node; } } else #endif /* WLTDLS */ if_flow_lkup[ifindex].fl_hash[prio] = fl_hash_node; } else { /* For bcast/mcast assign first slot in in interface */ hash = ETHER_ISMULTI(da) ? 0 : DHD_FLOWRING_HASHINDEX(da, prio); cur = if_flow_lkup[ifindex].fl_hash[hash]; if (cur) { while (cur->next) { cur = cur->next; } cur->next = fl_hash_node; } else if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node; } DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags); DHD_INFO(("%s: allocated flowid %d\n", __FUNCTION__, fl_hash_node->flowid)); return fl_hash_node->flowid; }
/* Init Flow Ring specific data structures */ int dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_flow_rings) { uint32 idx; uint32 flow_ring_table_sz; uint32 if_flow_lkup_sz; void * flowid_allocator; flow_ring_table_t *flow_ring_table; if_flow_lkup_t *if_flow_lkup = NULL; #ifdef PCIE_TX_DEFERRAL uint32 count; #endif void *lock = NULL; unsigned long flags; DHD_INFO(("%s\n", __FUNCTION__)); /* Construct a 16bit flow1d allocator */ flowid_allocator = id16_map_init(dhdp->osh, num_flow_rings - FLOW_RING_COMMON, FLOWID_RESERVED); if (flowid_allocator == NULL) { DHD_ERROR(("%s: flowid allocator init failure\n", __FUNCTION__)); return BCME_NOMEM; } /* Allocate a flow ring table, comprising of requested number of rings */ flow_ring_table_sz = (num_flow_rings * sizeof(flow_ring_node_t)); flow_ring_table = (flow_ring_table_t *)MALLOC(dhdp->osh, flow_ring_table_sz); if (flow_ring_table == NULL) { DHD_ERROR(("%s: flow ring table alloc failure\n", __FUNCTION__)); goto fail; } /* Initialize flow ring table state */ bzero((uchar *)flow_ring_table, flow_ring_table_sz); for (idx = 0; idx < num_flow_rings; idx++) { flow_ring_table[idx].status = FLOW_RING_STATUS_CLOSED; flow_ring_table[idx].flowid = (uint16)idx; flow_ring_table[idx].lock = dhd_os_spin_lock_init(dhdp->osh); if (flow_ring_table[idx].lock == NULL) { DHD_ERROR(("%s: Failed to init spinlock for queue!\n", __FUNCTION__)); goto fail; } dll_init(&flow_ring_table[idx].list); /* Initialize the per flow ring backup queue */ dhd_flow_queue_init(dhdp, &flow_ring_table[idx].queue, FLOW_RING_QUEUE_THRESHOLD); } /* Allocate per interface hash table */ if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS; if_flow_lkup = (if_flow_lkup_t *)DHD_OS_PREALLOC(dhdp, DHD_PREALLOC_IF_FLOW_LKUP, if_flow_lkup_sz); if (if_flow_lkup == NULL) { DHD_ERROR(("%s: if flow lkup alloc failure\n", __FUNCTION__)); goto fail; } /* Initialize per interface hash table */ bzero((uchar *)if_flow_lkup, if_flow_lkup_sz); for (idx = 0; idx < DHD_MAX_IFS; idx++) { int hash_ix; if_flow_lkup[idx].status = 0; if_flow_lkup[idx].role = 0; for (hash_ix = 0; hash_ix < DHD_FLOWRING_HASH_SIZE; hash_ix++) if_flow_lkup[idx].fl_hash[hash_ix] = NULL; } #ifdef PCIE_TX_DEFERRAL count = BITS_TO_LONGS(num_flow_rings); dhdp->bus->delete_flow_map = kzalloc(count, GFP_ATOMIC); if (!dhdp->bus->delete_flow_map) { DHD_ERROR(("%s: delete_flow_map alloc failure\n", __FUNCTION__)); goto fail; } #endif lock = dhd_os_spin_lock_init(dhdp->osh); if (lock == NULL) goto fail; dhdp->flow_prio_map_type = DHD_FLOW_PRIO_AC_MAP; bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO); /* Now populate into dhd pub */ DHD_FLOWID_LOCK(lock, flags); dhdp->num_flow_rings = num_flow_rings; dhdp->flowid_allocator = (void *)flowid_allocator; dhdp->flow_ring_table = (void *)flow_ring_table; dhdp->if_flow_lkup = (void *)if_flow_lkup; dhdp->flowid_lock = lock; DHD_FLOWID_UNLOCK(lock, flags); DHD_INFO(("%s done\n", __FUNCTION__)); return BCME_OK; fail: #ifdef PCIE_TX_DEFERRAL if (dhdp->bus->delete_flow_map) kfree(dhdp->bus->delete_flow_map); #endif /* Destruct the per interface flow lkup table */ if (dhdp->if_flow_lkup != NULL) { DHD_OS_PREFREE(dhdp, if_flow_lkup, if_flow_lkup_sz); } if (flow_ring_table != NULL) { for (idx = 0; idx < num_flow_rings; idx++) { if (flow_ring_table[idx].lock != NULL) dhd_os_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].lock); } MFREE(dhdp->osh, flow_ring_table, flow_ring_table_sz); } id16_map_fini(dhdp->osh, flowid_allocator); return BCME_NOMEM; }
/* Deinit Flow Ring specific data structures */ void dhd_flow_rings_deinit(dhd_pub_t *dhdp) { uint16 idx; uint32 flow_ring_table_sz; uint32 if_flow_lkup_sz; flow_ring_table_t *flow_ring_table; unsigned long flags; void *lock; DHD_INFO(("dhd_flow_rings_deinit\n")); if (dhdp->flow_ring_table != NULL) { ASSERT(dhdp->num_flow_rings > 0); DHD_FLOWID_LOCK(dhdp->flowid_lock, flags); flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; dhdp->flow_ring_table = NULL; DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags); for (idx = 0; idx < dhdp->num_flow_rings; idx++) { if (flow_ring_table[idx].active) { dhd_bus_clean_flow_ring(dhdp->bus, &flow_ring_table[idx]); } ASSERT(flow_queue_empty(&flow_ring_table[idx].queue)); /* Deinit flow ring queue locks before destroying flow ring table */ dhd_os_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].lock); flow_ring_table[idx].lock = NULL; } /* Destruct the flow ring table */ flow_ring_table_sz = dhdp->num_flow_rings * sizeof(flow_ring_table_t); MFREE(dhdp->osh, flow_ring_table, flow_ring_table_sz); } DHD_FLOWID_LOCK(dhdp->flowid_lock, flags); /* Destruct the per interface flow lkup table */ if (dhdp->if_flow_lkup != NULL) { if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS; bzero(dhdp->if_flow_lkup, sizeof(if_flow_lkup_sz)); DHD_OS_PREFREE(dhdp, dhdp->if_flow_lkup, if_flow_lkup_sz); dhdp->if_flow_lkup = NULL; } #ifdef PCIE_TX_DEFERRAL if (dhdp->bus->delete_flow_map) kfree(dhdp->bus->delete_flow_map); #endif /* Destruct the flowid allocator */ if (dhdp->flowid_allocator != NULL) dhdp->flowid_allocator = id16_map_fini(dhdp->osh, dhdp->flowid_allocator); dhdp->num_flow_rings = 0U; lock = dhdp->flowid_lock; dhdp->flowid_lock = NULL; DHD_FLOWID_UNLOCK(lock, flags); dhd_os_spin_lock_deinit(dhdp->osh, lock); }
static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) { wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; int res = -1; int nssid = 0; cmd_tlv_t *cmd_tlv_temp; char *str_ptr; int tlv_size_left; int pno_time = 0; int pno_repeat = 0; int pno_freq_expo_max = 0; #ifdef PNO_SET_DEBUG int i; char pno_in_example[] = { 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', 'S', '1', '2', '0', 'S', 0x05, 'd', 'l', 'i', 'n', 'k', 'S', 0x04, 'G', 'O', 'O', 'G', 'T', '0', 'B', 'R', '2', 'M', '2', 0x00 }; #endif /* PNO_SET_DEBUG */ DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); goto exit_proc; } #ifdef PNO_SET_DEBUG memcpy(command, pno_in_example, sizeof(pno_in_example)); for (i = 0; i < sizeof(pno_in_example); i++) printf("%02X ", command[i]); printf("\n"); total_len = sizeof(pno_in_example); #endif str_ptr = command + strlen(CMD_PNOSETUP_SET); tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); cmd_tlv_temp = (cmd_tlv_t *)str_ptr; memset(ssids_local, 0, sizeof(ssids_local)); if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && (cmd_tlv_temp->version == PNO_TLV_VERSION) && (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { str_ptr += sizeof(cmd_tlv_t); tlv_size_left -= sizeof(cmd_tlv_t); if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); goto exit_proc; } else { if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { DHD_ERROR(("%s scan duration corrupted field size %d\n", __FUNCTION__, tlv_size_left)); goto exit_proc; } str_ptr++; pno_time = simple_strtoul(str_ptr, &str_ptr, 16); DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); if (str_ptr[0] != 0) { if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { DHD_ERROR(("%s pno repeat : corrupted field\n", __FUNCTION__)); goto exit_proc; } str_ptr++; pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", __FUNCTION__)); goto exit_proc; } str_ptr++; pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); DHD_INFO(("%s: pno_freq_expo_max=%d\n", __FUNCTION__, pno_freq_expo_max)); } } } else { DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); goto exit_proc; } res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); exit_proc: return res; }
/* Get flow ring ID, if not present try to create one */ static INLINE int dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da, uint16 *flowid) { uint16 id; flow_ring_node_t *flow_ring_node; flow_ring_table_t *flow_ring_table; unsigned long flags; DHD_INFO(("%s\n", __FUNCTION__)); if (!dhdp->flow_ring_table) return BCME_ERROR; flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; id = dhd_flowid_find(dhdp, ifindex, prio, sa, da); if (id == FLOWID_INVALID) { if_flow_lkup_t *if_flow_lkup; if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; if (!if_flow_lkup[ifindex].status) return BCME_ERROR; id = dhd_flowid_alloc(dhdp, ifindex, prio, sa, da); if (id == FLOWID_INVALID) { DHD_ERROR(("%s: alloc flowid ifindex %u status %u\n", __FUNCTION__, ifindex, if_flow_lkup[ifindex].status)); return BCME_ERROR; } /* register this flowid in dhd_pub */ dhd_add_flowid(dhdp, ifindex, prio, da, id); } ASSERT(id < dhdp->num_flow_rings); flow_ring_node = (flow_ring_node_t *) &flow_ring_table[id]; DHD_FLOWRING_LOCK(flow_ring_node->lock, flags); if (flow_ring_node->active) { DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags); *flowid = id; return BCME_OK; } /* Init Flow info */ memcpy(flow_ring_node->flow_info.sa, sa, sizeof(flow_ring_node->flow_info.sa)); memcpy(flow_ring_node->flow_info.da, da, sizeof(flow_ring_node->flow_info.da)); flow_ring_node->flow_info.tid = prio; flow_ring_node->flow_info.ifindex = ifindex; flow_ring_node->active = TRUE; flow_ring_node->status = FLOW_RING_STATUS_PENDING; DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags); DHD_FLOWID_LOCK(dhdp->flowid_lock, flags); dll_prepend(&dhdp->bus->const_flowring, &flow_ring_node->list); DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags); /* Create and inform device about the new flow */ if (dhd_bus_flow_ring_create_request(dhdp->bus, (void *)flow_ring_node) != BCME_OK) { DHD_ERROR(("%s: create error %d\n", __FUNCTION__, id)); return BCME_ERROR; } *flowid = id; return BCME_OK; }
int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { int ret = 0; char *command = NULL; int bytes_written = 0; android_wifi_priv_cmd priv_cmd; net_os_wake_lock(net); if (!ifr->ifr_data) { ret = -EINVAL; goto exit; } if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { ret = -EFAULT; goto exit; } command = kmalloc(priv_cmd.total_len, GFP_KERNEL); if (!command) { DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); ret = -ENOMEM; goto exit; } if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { ret = -EFAULT; goto exit; } DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { DHD_INFO(("%s, Received regular START command\n", __FUNCTION__)); bytes_written = wl_android_wifi_on(net); } else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len); } if (!g_wifi_on) { DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n", __FUNCTION__, command, ifr->ifr_name)); ret = 0; goto exit; } if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) { bytes_written = wl_android_wifi_off(net); } else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) { /* TBD: SCAN-ACTIVE */ } else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) { /* TBD: SCAN-PASSIVE */ } else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) { bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) { bytes_written = net_os_set_packet_filter(net, 1); } else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) { bytes_written = net_os_set_packet_filter(net, 0); } else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) { int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); } else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) { int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); } else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) { /* TBD: BTCOEXSCAN-START */ } else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) { /* TBD: BTCOEXSCAN-STOP */ } else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; if (mode == 1) net_os_set_packet_filter(net, 0); /* DHCP starts */ else net_os_set_packet_filter(net, 1); /* DHCP ends */ #ifdef WL_CFG80211 bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); #endif } else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; bytes_written = wldev_set_band(net, band); } else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { char *country_code = command + strlen(CMD_COUNTRY) + 1; bytes_written = wldev_set_country(net, country_code); } #ifdef PNO_SUPPORT else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { bytes_written = dhd_dev_pno_reset(net); } else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; bytes_written = dhd_dev_pno_enable(net, pfn_enabled); } #endif else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) { bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) { int skip = strlen(CMD_P2P_SET_NOA) + 1; bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); } else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) { int skip = strlen(CMD_P2P_SET_PS) + 1; bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip); } #ifdef WL_CFG80211 else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3; bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); } #endif /* WL_CFG80211 */ else { DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); snprintf(command, 3, "OK"); bytes_written = strlen("OK"); } if (bytes_written > 0) { if (bytes_written > priv_cmd.total_len) { DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); bytes_written = priv_cmd.total_len; } else { bytes_written++; } priv_cmd.used_len = bytes_written; if (copy_to_user(priv_cmd.buf, command, bytes_written)) { DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); ret = -EFAULT; } } else { ret = bytes_written; } exit: net_os_wake_unlock(net); if (command) { kfree(command); } return ret; }