static void wl_cfg80211_bt_setflag(struct net_device *dev, bool set) { #if defined(BT_DHCP_USE_FLAGS) char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; #endif #if defined(BT_DHCP_eSCO_FIX) /* set = 1, save & turn on 0 - off & restore prev settings */ set_btc_esco_params(dev, set); #endif #if defined(BT_DHCP_USE_FLAGS) WL_TRACE(("WI-FI priority boost via bt flags, set:%d\n", set)); if (set == TRUE) /* Forcing bt_flag7 */ dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); else /* Restoring default bt flag7 */ dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); #endif }
static void wl_cfg80211_bt_setflag(struct net_device *dev, bool set) { #if defined(BT_DHCP_USE_FLAGS) char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; #endif int bt_coex = 0; #if defined(BT_DHCP_eSCO_FIX) set_btc_esco_params(dev, set); #endif #if defined(BT_DHCP_USE_FLAGS) WL_TRACE(("WI-FI priority boost via bt flags, set:%d\n", set)); if (set == TRUE) { dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); wldev_iovar_setint(dev, "btc_mode", bt_coex); } else { dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); bt_coex = 1; wldev_iovar_setint(dev, "btc_mode", bt_coex); } #endif }
/* get named driver variable to uint register value and return error indication calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value) */ static int dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val) { char reg_addr[8]; memset(reg_addr, 0, sizeof(reg_addr)); memcpy((char *)®_addr[0], (char *)addr, 4); memcpy((char *)®_addr[4], (char *)val, 4); return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); }
/* * btc_flags[2] is to turn CTS-to-self on/off */ s32 wl_cfg80211_set_btc_cts(struct net_device *dev, bool flag) { char buf[8]; memset(buf, 0, sizeof(buf)); buf[0] = 2; buf[4] = flag; dev_wlc_bufvar_set(dev, "btc_flags", (char *)buf, sizeof(buf)); return 0; }
/* get named driver variable to uint register value and return error indication calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value) */ static int dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val) { char reg_addr[8]; DHD_MYTRACE(("%s-%s\n", __FILE__, __FUNCTION__)); memset(reg_addr, 0, sizeof(reg_addr)); memcpy((char *)®_addr[0], (char *)addr, 4); memcpy((char *)®_addr[4], (char *)val, 4); return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); }
int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) { struct wl_priv *wl = wlcfg_drv_priv; char powermode_val = 0; char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; uint32 regaddr; static uint32 saved_reg66; static uint32 saved_reg41; static uint32 saved_reg68; static bool saved_status = FALSE; #ifdef COEX_DHCP char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; struct btcoex_info *btco_inf = wl->btcoex_info; #endif /* COEX_DHCP */ #ifdef PKT_FILTER_SUPPORT dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); #endif /* Figure out powermode 1 or o command */ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { WL_TRACE_HW4(("DHCP session starts\n")); #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 1; if (dhd->early_suspended) { WL_TRACE_HW4(("DHCP in progressing , disable packet filter!!!\n")); dhd_enable_packet_filter(0, dhd); } #endif /* Retrieve and saved orig regs value */ if ((saved_status == FALSE) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { saved_status = TRUE; WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); /* Disable PM mode during dhpc session */ /* Disable PM mode during dhpc session */ #ifdef COEX_DHCP /* Start BT timer only for SCO connection */ if (btcoex_is_sco_active(dev)) { /* btc_params 66 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on)); /* btc_params 41 0x33 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on)); /* btc_params 68 0x190 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on)); saved_status = TRUE; btco_inf->bt_state = BT_DHCP_START; btco_inf->timer_on = 1; mod_timer(&btco_inf->timer, btco_inf->timer.expires); WL_TRACE(("enable BT DHCP Timer\n")); } #endif /* COEX_DHCP */ } else if (saved_status == TRUE) { WL_ERR(("was called w/o DHCP OFF. Continue\n")); } } else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 0; WL_TRACE_HW4(("DHCP is complete \n")); /* Enable packet filtering */ if (dhd->early_suspended) { WL_TRACE_HW4(("DHCP is complete , enable packet filter!!!\n")); dhd_enable_packet_filter(1, dhd); } #endif /* PKT_FILTER_SUPPORT */ /* Restoring PM mode */ #ifdef COEX_DHCP /* Stop any bt timer because DHCP session is done */ WL_TRACE(("disable BT DHCP Timer\n")); if (btco_inf->timer_on) { btco_inf->timer_on = 0; del_timer_sync(&btco_inf->timer); if (btco_inf->bt_state != BT_DHCP_IDLE) { /* need to restore original btc flags & extra btc params */ WL_TRACE(("bt->bt_state:%d\n", btco_inf->bt_state)); /* wake up btcoex thread to restore btlags+params */ schedule_work(&btco_inf->work); } } /* Restoring btc_flag paramter anyway */ if (saved_status == TRUE) dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); #endif /* COEX_DHCP */ /* Restore original values */ if (saved_status == TRUE) { regaddr = 66; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg66); regaddr = 41; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg41); regaddr = 68; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg68); WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); } saved_status = FALSE; } else { WL_ERR(("Unkwown yet power setting, ignored\n")); } snprintf(command, 3, "OK"); return (strlen("OK")); }
/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */ static int set_btc_esco_params(struct net_device *dev, bool trump_sco) { static bool saved_status = FALSE; char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; uint32 regaddr; static uint32 saved_reg50; static uint32 saved_reg51; static uint32 saved_reg64; static uint32 saved_reg65; static uint32 saved_reg71; if (trump_sco) { /* this should reduce eSCO agressive retransmit * w/o breaking it */ /* 1st save current */ WL_TRACE(("Do new SCO/eSCO coex algo {save &" "override}\n")); if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { saved_status = TRUE; WL_TRACE(("saved bt_params[50,51,64,65,71]:" "0x%x 0x%x 0x%x 0x%x 0x%x\n", saved_reg50, saved_reg51, saved_reg64, saved_reg65, saved_reg71)); } else { WL_ERR((":%s: save btc_params failed\n", __FUNCTION__)); saved_status = FALSE; return -1; } WL_TRACE(("override with [50,51,64,65,71]:" "0x%x 0x%x 0x%x 0x%x 0x%x\n", *(u32 *)(buf_reg50va_dhcp_on+4), *(u32 *)(buf_reg51va_dhcp_on+4), *(u32 *)(buf_reg64va_dhcp_on+4), *(u32 *)(buf_reg65va_dhcp_on+4), *(u32 *)(buf_reg71va_dhcp_on+4))); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8); saved_status = TRUE; } else if (saved_status) { /* restore previously saved bt params */ WL_TRACE(("Do new SCO/eSCO coex algo {save &" "override}\n")); regaddr = 50; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg50); regaddr = 51; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg51); regaddr = 64; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg64); regaddr = 65; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg65); regaddr = 71; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg71); WL_TRACE(("restore bt_params[50,51,64,65,71]:" "0x%x 0x%x 0x%x 0x%x 0x%x\n", saved_reg50, saved_reg51, saved_reg64, saved_reg65, saved_reg71)); saved_status = FALSE; } else { WL_ERR((":%s att to restore not saved BTCOEX params\n", __FUNCTION__)); return -1; } return 0; }
int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) { struct wl_priv *wl = wlcfg_drv_priv; #ifndef OEM_ANDROID static int pm = PM_FAST; int pm_local = PM_OFF; #endif /* OEM_ANDROID */ char powermode_val = 0; char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; uint32 regaddr; static uint32 saved_reg66; static uint32 saved_reg41; static uint32 saved_reg68; static bool saved_status = FALSE; #ifdef COEX_DHCP char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; struct btcoex_info *btco_inf = wl->btcoex_info; #endif /* COEX_DHCP */ /* Figure out powermode 1 or o command */ #ifdef OEM_ANDROID strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); #else strncpy((char *)&powermode_val, command + strlen("POWERMODE") +1, 1); #endif if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); /* Retrieve and saved orig regs value */ if ((saved_status == FALSE) && #ifndef OEM_ANDROID (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) && #endif (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { saved_status = TRUE; WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); /* Disable PM mode during dhpc session */ #ifndef OEM_ANDROID dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); #endif /* Disable PM mode during dhpc session */ #ifdef COEX_DHCP /* Start BT timer only for SCO connection */ if (btcoex_is_sco_active(dev)) { /* btc_params 66 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on)); /* btc_params 41 0x33 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on)); /* btc_params 68 0x190 */ dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on)); saved_status = TRUE; btco_inf->bt_state = BT_DHCP_START; btco_inf->timer_on = 1; mod_timer(&btco_inf->timer, btco_inf->timer.expires); WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__)); } #endif /* COEX_DHCP */ } else if (saved_status == TRUE) { WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); } } #ifdef OEM_ANDROID else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { #else else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { #endif /* Restoring PM mode */ #ifndef OEM_ANDROID dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); #endif #ifdef COEX_DHCP /* Stop any bt timer because DHCP session is done */ WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); if (btco_inf->timer_on) { btco_inf->timer_on = 0; del_timer_sync(&btco_inf->timer); if (btco_inf->bt_state != BT_DHCP_IDLE) { /* need to restore original btc flags & extra btc params */ WL_TRACE(("%s bt->bt_state:%d\n", __FUNCTION__, btco_inf->bt_state)); /* wake up btcoex thread to restore btlags+params */ schedule_work(&btco_inf->work); } } /* Restoring btc_flag paramter anyway */ if (saved_status == TRUE) dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); #endif /* COEX_DHCP */ /* Restore original values */ if (saved_status == TRUE) { regaddr = 66; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg66); regaddr = 41; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg41); regaddr = 68; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg68); WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); } saved_status = FALSE; } else { WL_ERR(("%s Unkwown yet power setting, ignored\n", __FUNCTION__)); } snprintf(command, 3, "OK"); return (strlen("OK")); }
int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) { struct wl_priv *wl = wlcfg_drv_priv; char powermode_val = 0; char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; uint32 regaddr; static uint32 saved_reg66; static uint32 saved_reg41; static uint32 saved_reg68; static bool saved_status = FALSE; #ifdef COEX_DHCP char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; struct btcoex_info *btco_inf = wl->btcoex_info; #endif #ifdef PKT_FILTER_SUPPORT dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); #endif strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { WL_TRACE_HW4(("%s: DHCP session starts\n", __FUNCTION__)); #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 1; if (dhd->early_suspended) { WL_TRACE_HW4(("DHCP in progressing , disable packet filter!!!\n")); dhd_enable_packet_filter(0, dhd); } #endif if ((saved_status == FALSE) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { saved_status = TRUE; WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); #ifdef COEX_DHCP if (btcoex_is_sco_active(dev)) { dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on)); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on)); dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on)); saved_status = TRUE; btco_inf->bt_state = BT_DHCP_START; btco_inf->timer_on = 1; btco_inf->dhcp_done = 0; mod_timer(&btco_inf->timer, jiffies + msecs_to_jiffies(BT_DHCP_OPPR_WIN_TIME)); WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__)); } #endif } else if (saved_status == TRUE) { WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); } } else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 0; WL_TRACE_HW4(("%s: DHCP is complete \n", __FUNCTION__)); if (dhd->early_suspended) { WL_TRACE_HW4(("DHCP is complete , enable packet filter!!!\n")); dhd_enable_packet_filter(1, dhd); } #endif #ifdef COEX_DHCP WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); if (btco_inf->timer_on) { btco_inf->timer_on = 0; btco_inf->dhcp_done = 1; del_timer_sync(&btco_inf->timer); if (btco_inf->bt_state != BT_DHCP_IDLE) { WL_TRACE(("%s bt->bt_state:%d\n", __FUNCTION__, btco_inf->bt_state)); schedule_work(&btco_inf->work); } } if (saved_status == TRUE) dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); #endif if (saved_status == TRUE) { regaddr = 66; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg66); regaddr = 41; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg41); regaddr = 68; dev_wlc_intvar_set_reg(dev, "btc_params", (char *)®addr, (char *)&saved_reg68); WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", saved_reg66, saved_reg41, saved_reg68)); } saved_status = FALSE; } else { WL_ERR(("%s Unkwown yet power setting, ignored\n", __FUNCTION__)); } snprintf(command, 3, "OK"); return (strlen("OK")); }