Lines Matching +full:bt +full:- +full:sco
1 // SPDX-License-Identifier: ISC
20 /* T1 start SCO/eSCO priority suppression */
23 /* BT registers values during DHCP */
33 /* number of samples for SCO detection */
37 * enum brcmf_btcoex_state - BT coex DHCP state machine states
54 * struct brcmf_btcoex_info - BT coex related information
98 * brcmf_btcoex_params_write() - write btc_params firmware variable
117 * brcmf_btcoex_params_read() - read btc_params firmware variable
130 * brcmf_btcoex_boost_wifi() - control BT SCO/eSCO parameters
131 * @btci: BT coex info
133 * true - set SCO/eSCO parameters for compatibility
135 * false - restore saved parameter values
137 * Enhanced BT COEX settings for eSCO compatibility during DHCP window
142 struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0); in brcmf_btcoex_boost_wifi()
144 if (trump_sco && !btci->saved_regs_part2) { in brcmf_btcoex_boost_wifi()
150 brcmf_dbg(INFO, "new SCO/eSCO coex algo {save & override}\n"); in brcmf_btcoex_boost_wifi()
151 brcmf_btcoex_params_read(ifp, 50, &btci->reg50); in brcmf_btcoex_boost_wifi()
152 brcmf_btcoex_params_read(ifp, 51, &btci->reg51); in brcmf_btcoex_boost_wifi()
153 brcmf_btcoex_params_read(ifp, 64, &btci->reg64); in brcmf_btcoex_boost_wifi()
154 brcmf_btcoex_params_read(ifp, 65, &btci->reg65); in brcmf_btcoex_boost_wifi()
155 brcmf_btcoex_params_read(ifp, 71, &btci->reg71); in brcmf_btcoex_boost_wifi()
157 btci->saved_regs_part2 = true; in brcmf_btcoex_boost_wifi()
160 btci->reg50, btci->reg51, btci->reg64, in brcmf_btcoex_boost_wifi()
161 btci->reg65, btci->reg71); in brcmf_btcoex_boost_wifi()
170 } else if (btci->saved_regs_part2) { in brcmf_btcoex_boost_wifi()
171 /* restore previously saved bt params */ in brcmf_btcoex_boost_wifi()
172 brcmf_dbg(INFO, "Do new SCO/eSCO coex algo {restore}\n"); in brcmf_btcoex_boost_wifi()
173 brcmf_btcoex_params_write(ifp, 50, btci->reg50); in brcmf_btcoex_boost_wifi()
174 brcmf_btcoex_params_write(ifp, 51, btci->reg51); in brcmf_btcoex_boost_wifi()
175 brcmf_btcoex_params_write(ifp, 64, btci->reg64); in brcmf_btcoex_boost_wifi()
176 brcmf_btcoex_params_write(ifp, 65, btci->reg65); in brcmf_btcoex_boost_wifi()
177 brcmf_btcoex_params_write(ifp, 71, btci->reg71); in brcmf_btcoex_boost_wifi()
181 btci->reg50, btci->reg51, btci->reg64, in brcmf_btcoex_boost_wifi()
182 btci->reg65, btci->reg71); in brcmf_btcoex_boost_wifi()
184 btci->saved_regs_part2 = false; in brcmf_btcoex_boost_wifi()
191 * brcmf_btcoex_is_sco_active() - check if SCO/eSCO is active
194 * return: true if SCO/eSCO session is active
214 if ((param27 & 0x6) == 2) { /* count both sco & esco */ in brcmf_btcoex_is_sco_active()
220 "sco/esco detected, pkt id_cnt:%d samples:%d\n", in brcmf_btcoex_is_sco_active()
231 * btcmf_btcoex_save_part1() - save first step parameters.
235 struct brcmf_if *ifp = btci->vif->ifp; in btcmf_btcoex_save_part1()
237 if (!btci->saved_regs_part1) { in btcmf_btcoex_save_part1()
239 brcmf_btcoex_params_read(ifp, 66, &btci->reg66); in btcmf_btcoex_save_part1()
240 brcmf_btcoex_params_read(ifp, 41, &btci->reg41); in btcmf_btcoex_save_part1()
241 brcmf_btcoex_params_read(ifp, 68, &btci->reg68); in btcmf_btcoex_save_part1()
242 btci->saved_regs_part1 = true; in btcmf_btcoex_save_part1()
245 btci->reg66, btci->reg41, in btcmf_btcoex_save_part1()
246 btci->reg68); in btcmf_btcoex_save_part1()
251 * brcmf_btcoex_restore_part1() - restore first step parameters.
257 if (btci->saved_regs_part1) { in brcmf_btcoex_restore_part1()
258 btci->saved_regs_part1 = false; in brcmf_btcoex_restore_part1()
259 ifp = btci->vif->ifp; in brcmf_btcoex_restore_part1()
260 brcmf_btcoex_params_write(ifp, 66, btci->reg66); in brcmf_btcoex_restore_part1()
261 brcmf_btcoex_params_write(ifp, 41, btci->reg41); in brcmf_btcoex_restore_part1()
262 brcmf_btcoex_params_write(ifp, 68, btci->reg68); in brcmf_btcoex_restore_part1()
265 btci->reg66, btci->reg41, in brcmf_btcoex_restore_part1()
266 btci->reg68); in brcmf_btcoex_restore_part1()
271 * brcmf_btcoex_timerfunc() - BT coex timer callback
278 bt_local->timer_on = false; in brcmf_btcoex_timerfunc()
279 schedule_work(&bt_local->work); in brcmf_btcoex_timerfunc()
283 * brcmf_btcoex_handler() - BT coex state machine work handler
290 if (btci->timer_on) { in brcmf_btcoex_handler()
291 btci->timer_on = false; in brcmf_btcoex_handler()
292 del_timer_sync(&btci->timer); in brcmf_btcoex_handler()
295 switch (btci->bt_state) { in brcmf_btcoex_handler()
301 btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN; in brcmf_btcoex_handler()
302 if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) { in brcmf_btcoex_handler()
303 mod_timer(&btci->timer, btci->timer.expires); in brcmf_btcoex_handler()
305 btci->timeout -= BRCMF_BTCOEX_OPPR_WIN_TIME; in brcmf_btcoex_handler()
306 mod_timer(&btci->timer, in brcmf_btcoex_handler()
309 btci->timer_on = true; in brcmf_btcoex_handler()
313 if (btci->dhcp_done) { in brcmf_btcoex_handler()
318 /* DHCP is not over yet, start lowering BT priority */ in brcmf_btcoex_handler()
323 btci->bt_state = BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT; in brcmf_btcoex_handler()
324 mod_timer(&btci->timer, jiffies + btci->timeout); in brcmf_btcoex_handler()
325 btci->timer_on = true; in brcmf_btcoex_handler()
329 if (btci->dhcp_done) in brcmf_btcoex_handler()
338 brcmf_err("invalid state=%d !!!\n", btci->bt_state); in brcmf_btcoex_handler()
345 btci->bt_state = BRCMF_BT_DHCP_IDLE; in brcmf_btcoex_handler()
346 btci->timer_on = false; in brcmf_btcoex_handler()
348 cfg80211_crit_proto_stopped(&btci->vif->wdev, GFP_KERNEL); in brcmf_btcoex_handler()
350 btci->vif = NULL; in brcmf_btcoex_handler()
354 * brcmf_btcoex_attach() - initialize BT coex data
366 return -ENOMEM; in brcmf_btcoex_attach()
368 btci->bt_state = BRCMF_BT_DHCP_IDLE; in brcmf_btcoex_attach()
370 /* Set up timer for BT */ in brcmf_btcoex_attach()
371 btci->timer_on = false; in brcmf_btcoex_attach()
372 btci->timeout = BRCMF_BTCOEX_OPPR_WIN_TIME; in brcmf_btcoex_attach()
373 timer_setup(&btci->timer, brcmf_btcoex_timerfunc, 0); in brcmf_btcoex_attach()
374 btci->cfg = cfg; in brcmf_btcoex_attach()
375 btci->saved_regs_part1 = false; in brcmf_btcoex_attach()
376 btci->saved_regs_part2 = false; in brcmf_btcoex_attach()
378 INIT_WORK(&btci->work, brcmf_btcoex_handler); in brcmf_btcoex_attach()
380 cfg->btcoex = btci; in brcmf_btcoex_attach()
385 * brcmf_btcoex_detach - clean BT coex data
392 if (!cfg->btcoex) in brcmf_btcoex_detach()
395 if (cfg->btcoex->timer_on) { in brcmf_btcoex_detach()
396 cfg->btcoex->timer_on = false; in brcmf_btcoex_detach()
397 timer_shutdown_sync(&cfg->btcoex->timer); in brcmf_btcoex_detach()
400 cancel_work_sync(&cfg->btcoex->work); in brcmf_btcoex_detach()
402 brcmf_btcoex_boost_wifi(cfg->btcoex, false); in brcmf_btcoex_detach()
403 brcmf_btcoex_restore_part1(cfg->btcoex); in brcmf_btcoex_detach()
405 kfree(cfg->btcoex); in brcmf_btcoex_detach()
406 cfg->btcoex = NULL; in brcmf_btcoex_detach()
411 struct brcmf_if *ifp = btci->vif->ifp; in brcmf_btcoex_dhcp_start()
418 btci->dhcp_done = false; in brcmf_btcoex_dhcp_start()
419 btci->bt_state = BRCMF_BT_DHCP_START; in brcmf_btcoex_dhcp_start()
420 schedule_work(&btci->work); in brcmf_btcoex_dhcp_start()
421 brcmf_dbg(TRACE, "enable BT DHCP Timer\n"); in brcmf_btcoex_dhcp_start()
426 /* Stop any bt timer because DHCP session is done */ in brcmf_btcoex_dhcp_end()
427 btci->dhcp_done = true; in brcmf_btcoex_dhcp_end()
428 if (btci->timer_on) { in brcmf_btcoex_dhcp_end()
429 brcmf_dbg(INFO, "disable BT DHCP Timer\n"); in brcmf_btcoex_dhcp_end()
430 btci->timer_on = false; in brcmf_btcoex_dhcp_end()
431 del_timer_sync(&btci->timer); in brcmf_btcoex_dhcp_end()
434 if (btci->bt_state != BRCMF_BT_DHCP_IDLE) { in brcmf_btcoex_dhcp_end()
436 btci->bt_state); in brcmf_btcoex_dhcp_end()
437 schedule_work(&btci->work); in brcmf_btcoex_dhcp_end()
446 * brcmf_btcoex_set_mode - set BT coex mode
447 * @mode: Wifi-Bluetooth coexistence mode
454 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); in brcmf_btcoex_set_mode()
455 struct brcmf_btcoex_info *btci = cfg->btcoex; in brcmf_btcoex_set_mode()
456 struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); in brcmf_btcoex_set_mode()
461 if (btci->bt_state != BRCMF_BT_DHCP_IDLE) in brcmf_btcoex_set_mode()
462 return -EBUSY; in brcmf_btcoex_set_mode()
463 /* Start BT timer only for SCO connection */ in brcmf_btcoex_set_mode()
465 btci->timeout = msecs_to_jiffies(duration); in brcmf_btcoex_set_mode()
466 btci->vif = vif; in brcmf_btcoex_set_mode()
473 if (btci->bt_state != BRCMF_BT_DHCP_IDLE && in brcmf_btcoex_set_mode()
474 vif == btci->vif) { in brcmf_btcoex_set_mode()