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")); }
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")); }