aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-23 10:57:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-25 14:34:53 -0400
commitb6e116e8bf7d749b0743c167bd47930c22c77a82 (patch)
treed64302d6a6785f3bf0301ad7c8d41b670cf74147 /drivers/net
parentda5dbb971573efda54c7c39e7e4ccd3fc7c86e49 (diff)
iwlagn: generic bt coex functions
Move bt coex functions to iwl-agn-lib.c, so those functions can be shared by multiple wifi/bt combo devices Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c391
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c370
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h74
7 files changed, 441 insertions, 425 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 30dc1f334202..fc9344b873ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -122,165 +122,6 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
122 priv->cfg->ops->lib->temp_ops.set_calib_version(priv); 122 priv->cfg->ops->lib->temp_ops.set_calib_version(priv);
123} 123}
124 124
125/*
126 * Macros to access the lookup table.
127 *
128 * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
129 * wifi_prio, wifi_txrx and wifi_sh_ant_req.
130 *
131 * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
132 *
133 * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
134 * one after another in 32-bit registers, and "registers" 0 through 7 contain
135 * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
136 *
137 * These macros encode that format.
138 */
139#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
140 wifi_txrx, wifi_sh_ant_req) \
141 (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
142 (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
143
144#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
145 lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
146#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
147 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \
148 (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx,\
149 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
150#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
151 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \
152 LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
153 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
154#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
155 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \
156 LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
157 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
158
159#define LUT_WLAN_KILL_OP(lut, op, val) \
160 lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
161#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
162 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
163 (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
164 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
165#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
166 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
167 LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
168 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
169#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
170 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
171 LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
172 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
173
174#define LUT_ANT_SWITCH_OP(lut, op, val) \
175 lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
176#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
177 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
178 (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
179 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
180#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
181 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
182 LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
183 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
184#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
185 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
186 LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
187 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
188
189static const __le32 iwl6000g2b_def_3w_lookup[12] = {
190 cpu_to_le32(0xaaaaaaaa),
191 cpu_to_le32(0xaaaaaaaa),
192 cpu_to_le32(0xaeaaaaaa),
193 cpu_to_le32(0xaaaaaaaa),
194 cpu_to_le32(0xcc00ff28),
195 cpu_to_le32(0x0000aaaa),
196 cpu_to_le32(0xcc00aaaa),
197 cpu_to_le32(0x0000aaaa),
198 cpu_to_le32(0xc0004000),
199 cpu_to_le32(0x00004000),
200 cpu_to_le32(0xf0005000),
201 cpu_to_le32(0xf0004000),
202};
203
204static const __le32 iwl6000g2b_concurrent_lookup[12] = {
205 cpu_to_le32(0xaaaaaaaa),
206 cpu_to_le32(0xaaaaaaaa),
207 cpu_to_le32(0xaaaaaaaa),
208 cpu_to_le32(0xaaaaaaaa),
209 cpu_to_le32(0xaaaaaaaa),
210 cpu_to_le32(0xaaaaaaaa),
211 cpu_to_le32(0xaaaaaaaa),
212 cpu_to_le32(0xaaaaaaaa),
213 cpu_to_le32(0x00000000),
214 cpu_to_le32(0x00000000),
215 cpu_to_le32(0x00000000),
216 cpu_to_le32(0x00000000),
217};
218
219static void iwl6000g2b_send_bt_config(struct iwl_priv *priv)
220{
221 struct iwl6000g2b_bt_cmd bt_cmd = {
222 .max_kill = IWL6000G2B_BT_MAX_KILL_DEFAULT,
223 .bt3_timer_t7_value = IWL6000G2B_BT3_T7_DEFAULT,
224 .bt3_prio_sample_time = IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT,
225 .bt3_timer_t2_value = IWL6000G2B_BT3_T2_DEFAULT,
226 };
227
228 BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) !=
229 sizeof(bt_cmd.bt3_lookup_table));
230
231 bt_cmd.prio_boost = priv->cfg->bt_prio_boost;
232 bt_cmd.kill_ack_mask = priv->kill_ack_mask;
233 bt_cmd.kill_cts_mask = priv->kill_cts_mask;
234 bt_cmd.valid = priv->bt_valid;
235
236 /*
237 * Configure BT coex mode to "no coexistence" when the
238 * user disabled BT coexistence, we have no interface
239 * user disabled BT coexistence, or the interface is in
240 * IBSS mode (no proper uCode support for coex then).
241 */
242 if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
243 bt_cmd.flags = 0;
244 } else {
245 bt_cmd.flags = IWL6000G2B_BT_FLAG_COEX_MODE_3W <<
246 IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT;
247 if (priv->bt_ch_announce)
248 bt_cmd.flags |= IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION;
249 IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
250 }
251
252 if (priv->bt_full_concurrent)
253 memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_concurrent_lookup,
254 sizeof(iwl6000g2b_concurrent_lookup));
255 else
256 memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup,
257 sizeof(iwl6000g2b_def_3w_lookup));
258
259 IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n",
260 bt_cmd.flags ? "active" : "disabled",
261 priv->bt_full_concurrent ?
262 "full concurrency" : "3-wire");
263
264 if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd))
265 IWL_ERR(priv, "failed to send BT Coex Config\n");
266
267 /*
268 * When we are doing a restart, need to also reconfigure BT
269 * SCO to the device. If not doing a restart, bt_sco_active
270 * will always be false, so there's no need to have an extra
271 * variable to check for it.
272 */
273 if (priv->bt_sco_active) {
274 struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 };
275
276 if (priv->bt_sco_active)
277 sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE;
278 if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO,
279 sizeof(sco_cmd), &sco_cmd))
280 IWL_ERR(priv, "failed to send BT SCO command\n");
281 }
282}
283
284static struct iwl_sensitivity_ranges iwl6000_sensitivity = { 125static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
285 .min_nrg_cck = 97, 126 .min_nrg_cck = 97,
286 .max_nrg_cck = 0, /* not used, set to 0 */ 127 .max_nrg_cck = 0, /* not used, set to 0 */
@@ -422,210 +263,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
422 return iwl_send_cmd_sync(priv, &hcmd); 263 return iwl_send_cmd_sync(priv, &hcmd);
423} 264}
424 265
425static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work)
426{
427 struct iwl_priv *priv =
428 container_of(work, struct iwl_priv, bt_traffic_change_work);
429 int smps_request = -1;
430
431 IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
432 priv->bt_traffic_load);
433
434 switch (priv->bt_traffic_load) {
435 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
436 smps_request = IEEE80211_SMPS_AUTOMATIC;
437 break;
438 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
439 smps_request = IEEE80211_SMPS_DYNAMIC;
440 break;
441 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
442 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
443 smps_request = IEEE80211_SMPS_STATIC;
444 break;
445 default:
446 IWL_ERR(priv, "Invalid BT traffic load: %d\n",
447 priv->bt_traffic_load);
448 break;
449 }
450
451 mutex_lock(&priv->mutex);
452
453 if (priv->cfg->ops->lib->update_chain_flags)
454 priv->cfg->ops->lib->update_chain_flags(priv);
455
456 if (smps_request != -1 &&
457 priv->vif && priv->vif->type == NL80211_IFTYPE_STATION)
458 ieee80211_request_smps(priv->vif, smps_request);
459
460 mutex_unlock(&priv->mutex);
461}
462
463static void iwlagn_print_uartmsg(struct iwl_priv *priv,
464 struct iwl_bt_uart_msg *uart_msg)
465{
466 IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
467 "Update Req = 0x%X",
468 (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
469 BT_UART_MSG_FRAME1MSGTYPE_POS,
470 (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
471 BT_UART_MSG_FRAME1SSN_POS,
472 (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
473 BT_UART_MSG_FRAME1UPDATEREQ_POS);
474
475 IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
476 "Chl_SeqN = 0x%X, In band = 0x%X",
477 (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
478 BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
479 (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
480 BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
481 (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
482 BT_UART_MSG_FRAME2CHLSEQN_POS,
483 (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
484 BT_UART_MSG_FRAME2INBAND_POS);
485
486 IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
487 "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
488 (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
489 BT_UART_MSG_FRAME3SCOESCO_POS,
490 (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
491 BT_UART_MSG_FRAME3SNIFF_POS,
492 (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
493 BT_UART_MSG_FRAME3A2DP_POS,
494 (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
495 BT_UART_MSG_FRAME3ACL_POS,
496 (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
497 BT_UART_MSG_FRAME3MASTER_POS,
498 (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
499 BT_UART_MSG_FRAME3OBEX_POS);
500
501 IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X",
502 (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
503 BT_UART_MSG_FRAME4IDLEDURATION_POS);
504
505 IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
506 "eSCO Retransmissions = 0x%X",
507 (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
508 BT_UART_MSG_FRAME5TXACTIVITY_POS,
509 (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
510 BT_UART_MSG_FRAME5RXACTIVITY_POS,
511 (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
512 BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
513
514 IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
515 (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
516 BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
517 (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
518 BT_UART_MSG_FRAME6DISCOVERABLE_POS);
519
520 IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = "
521 "0x%X, Connectable = 0x%X",
522 (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
523 BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
524 (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >>
525 BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS,
526 (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
527 BT_UART_MSG_FRAME7CONNECTABLE_POS);
528}
529
530static void iwl6000g2b_set_kill_ack_msk(struct iwl_priv *priv,
531 struct iwl_bt_uart_msg *uart_msg)
532{
533 u8 kill_ack_msk;
534 __le32 bt_kill_ack_msg[2] = {
535 cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
536
537 kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
538 BT_UART_MSG_FRAME3SNIFF_MSK |
539 BT_UART_MSG_FRAME3SCOESCO_MSK) &
540 uart_msg->frame3) == 0) ? 1 : 0;
541 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
542 priv->bt_valid |= IWL6000G2B_BT_VALID_KILL_ACK_MASK;
543 priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
544 /* schedule to send runtime bt_config */
545 queue_work(priv->workqueue, &priv->bt_runtime_config);
546 }
547
548}
549
550static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv,
551 struct iwl_rx_mem_buffer *rxb)
552{
553 unsigned long flags;
554 struct iwl_rx_packet *pkt = rxb_addr(rxb);
555 struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
556 struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 };
557 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
558 u8 last_traffic_load;
559
560 IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
561 IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
562 IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);
563 IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance);
564 iwlagn_print_uartmsg(priv, uart_msg);
565
566 last_traffic_load = priv->notif_bt_traffic_load;
567 priv->notif_bt_traffic_load = coex->bt_traffic_load;
568 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
569 if (priv->bt_status != coex->bt_status ||
570 last_traffic_load != coex->bt_traffic_load) {
571 if (coex->bt_status) {
572 /* BT on */
573 if (!priv->bt_ch_announce)
574 priv->bt_traffic_load =
575 IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
576 else
577 priv->bt_traffic_load =
578 coex->bt_traffic_load;
579 } else {
580 /* BT off */
581 priv->bt_traffic_load =
582 IWL_BT_COEX_TRAFFIC_LOAD_NONE;
583 }
584 priv->bt_status = coex->bt_status;
585 queue_work(priv->workqueue,
586 &priv->bt_traffic_change_work);
587 }
588 if (priv->bt_sco_active !=
589 (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
590 priv->bt_sco_active = uart_msg->frame3 &
591 BT_UART_MSG_FRAME3SCOESCO_MSK;
592 if (priv->bt_sco_active)
593 sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE;
594 iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO,
595 sizeof(sco_cmd), &sco_cmd, NULL);
596 }
597 }
598
599 iwl6000g2b_set_kill_ack_msk(priv, uart_msg);
600
601 /* FIXME: based on notification, adjust the prio_boost */
602
603 spin_lock_irqsave(&priv->lock, flags);
604 priv->bt_ci_compliance = coex->bt_ci_compliance;
605 spin_unlock_irqrestore(&priv->lock, flags);
606}
607
608void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv)
609{
610 iwlagn_rx_handler_setup(priv);
611 priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
612 iwl6000g2b_bt_coex_profile_notif;
613}
614
615static void iwl6000g2b_bt_setup_deferred_work(struct iwl_priv *priv)
616{
617 iwlagn_setup_deferred_work(priv);
618
619 INIT_WORK(&priv->bt_traffic_change_work,
620 iwl6000g2b_bt_traffic_change_work);
621
622}
623
624static void iwl6000g2b_bt_cancel_deferred_work(struct iwl_priv *priv)
625{
626 cancel_work_sync(&priv->bt_traffic_change_work);
627}
628
629static struct iwl_lib_ops iwl6000_lib = { 266static struct iwl_lib_ops iwl6000_lib = {
630 .set_hw_params = iwl6000_hw_set_hw_params, 267 .set_hw_params = iwl6000_hw_set_hw_params,
631 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 268 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
@@ -710,9 +347,9 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
710 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 347 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
711 .txq_free_tfd = iwl_hw_txq_free_tfd, 348 .txq_free_tfd = iwl_hw_txq_free_tfd,
712 .txq_init = iwl_hw_tx_queue_init, 349 .txq_init = iwl_hw_tx_queue_init,
713 .rx_handler_setup = iwl6000g2b_rx_handler_setup, 350 .rx_handler_setup = iwlagn_bt_rx_handler_setup,
714 .setup_deferred_work = iwl6000g2b_bt_setup_deferred_work, 351 .setup_deferred_work = iwlagn_bt_setup_deferred_work,
715 .cancel_deferred_work = iwl6000g2b_bt_cancel_deferred_work, 352 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
716 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 353 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
717 .load_ucode = iwlagn_load_ucode, 354 .load_ucode = iwlagn_load_ucode,
718 .dump_nic_event_log = iwl_dump_nic_event_log, 355 .dump_nic_event_log = iwl_dump_nic_event_log,
@@ -782,17 +419,9 @@ static const struct iwl_ops iwl6000_ops = {
782 .led = &iwlagn_led_ops, 419 .led = &iwlagn_led_ops,
783}; 420};
784 421
785static struct iwl_hcmd_ops iwl6000g2b_hcmd = {
786 .rxon_assoc = iwlagn_send_rxon_assoc,
787 .commit_rxon = iwl_commit_rxon,
788 .set_rxon_chain = iwl_set_rxon_chain,
789 .set_tx_ant = iwlagn_send_tx_ant_config,
790 .send_bt_config = iwl6000g2b_send_bt_config,
791};
792
793static const struct iwl_ops iwl6000g2b_ops = { 422static const struct iwl_ops iwl6000g2b_ops = {
794 .lib = &iwl6000g2b_lib, 423 .lib = &iwl6000g2b_lib,
795 .hcmd = &iwl6000g2b_hcmd, 424 .hcmd = &iwlagn_bt_hcmd,
796 .utils = &iwlagn_hcmd_utils, 425 .utils = &iwlagn_hcmd_utils,
797 .led = &iwlagn_led_ops, 426 .led = &iwlagn_led_ops,
798}; 427};
@@ -945,7 +574,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
945 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 574 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
946 .advanced_bt_coexist = true, 575 .advanced_bt_coexist = true,
947 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 576 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
948 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 577 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
949}; 578};
950 579
951struct iwl_cfg iwl6000g2b_2abg_cfg = { 580struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -986,7 +615,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
986 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 615 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
987 .advanced_bt_coexist = true, 616 .advanced_bt_coexist = true,
988 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 617 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
989 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 618 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
990}; 619};
991 620
992struct iwl_cfg iwl6000g2b_2bgn_cfg = { 621struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -1029,7 +658,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
1029 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 658 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
1030 .advanced_bt_coexist = true, 659 .advanced_bt_coexist = true,
1031 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 660 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
1032 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 661 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
1033}; 662};
1034 663
1035struct iwl_cfg iwl6000g2b_2bg_cfg = { 664struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -1070,7 +699,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
1070 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 699 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
1071 .advanced_bt_coexist = true, 700 .advanced_bt_coexist = true,
1072 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 701 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
1073 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 702 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
1074}; 703};
1075 704
1076struct iwl_cfg iwl6000g2b_bgn_cfg = { 705struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -1113,7 +742,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
1113 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 742 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
1114 .advanced_bt_coexist = true, 743 .advanced_bt_coexist = true,
1115 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 744 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
1116 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 745 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
1117}; 746};
1118 747
1119struct iwl_cfg iwl6000g2b_bg_cfg = { 748struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -1154,7 +783,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
1154 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 783 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
1155 .advanced_bt_coexist = true, 784 .advanced_bt_coexist = true,
1156 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 785 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
1157 .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, 786 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
1158}; 787};
1159 788
1160/* 789/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 84939763d178..84fe06adcef4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -277,6 +277,14 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
277 .send_bt_config = iwl_send_bt_config, 277 .send_bt_config = iwl_send_bt_config,
278}; 278};
279 279
280struct iwl_hcmd_ops iwlagn_bt_hcmd = {
281 .rxon_assoc = iwlagn_send_rxon_assoc,
282 .commit_rxon = iwl_commit_rxon,
283 .set_rxon_chain = iwl_set_rxon_chain,
284 .set_tx_ant = iwlagn_send_tx_ant_config,
285 .send_bt_config = iwlagn_send_advance_bt_config,
286};
287
280struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { 288struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
281 .get_hcmd_size = iwlagn_get_hcmd_size, 289 .get_hcmd_size = iwlagn_get_hcmd_size,
282 .build_addsta_hcmd = iwlagn_build_addsta_hcmd, 290 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index ea242401b5a3..a9e69a6213f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1542,3 +1542,373 @@ done:
1542 ieee80211_wake_queues(priv->hw); 1542 ieee80211_wake_queues(priv->hw);
1543 mutex_unlock(&priv->mutex); 1543 mutex_unlock(&priv->mutex);
1544} 1544}
1545
1546/*
1547 * BT coex
1548 */
1549/*
1550 * Macros to access the lookup table.
1551 *
1552 * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
1553* wifi_prio, wifi_txrx and wifi_sh_ant_req.
1554 *
1555 * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
1556 *
1557 * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
1558 * one after another in 32-bit registers, and "registers" 0 through 7 contain
1559 * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
1560 *
1561 * These macros encode that format.
1562 */
1563#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
1564 wifi_txrx, wifi_sh_ant_req) \
1565 (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
1566 (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
1567
1568#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
1569 lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
1570#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1571 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1572 (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
1573 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1574 wifi_sh_ant_req))))
1575#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1576 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1577 LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
1578 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1579 wifi_sh_ant_req))
1580#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
1581 wifi_req, wifi_prio, wifi_txrx, \
1582 wifi_sh_ant_req) \
1583 LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
1584 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1585 wifi_sh_ant_req))
1586
1587#define LUT_WLAN_KILL_OP(lut, op, val) \
1588 lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
1589#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1590 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1591 (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1592 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
1593#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1594 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1595 LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1596 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1597#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1598 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1599 LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1600 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1601
1602#define LUT_ANT_SWITCH_OP(lut, op, val) \
1603 lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
1604#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1605 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1606 (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1607 wifi_req, wifi_prio, wifi_txrx, \
1608 wifi_sh_ant_req))))
1609#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1610 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1611 LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1612 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1613#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1614 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1615 LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1616 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1617
1618static const __le32 iwlagn_def_3w_lookup[12] = {
1619 cpu_to_le32(0xaaaaaaaa),
1620 cpu_to_le32(0xaaaaaaaa),
1621 cpu_to_le32(0xaeaaaaaa),
1622 cpu_to_le32(0xaaaaaaaa),
1623 cpu_to_le32(0xcc00ff28),
1624 cpu_to_le32(0x0000aaaa),
1625 cpu_to_le32(0xcc00aaaa),
1626 cpu_to_le32(0x0000aaaa),
1627 cpu_to_le32(0xc0004000),
1628 cpu_to_le32(0x00004000),
1629 cpu_to_le32(0xf0005000),
1630 cpu_to_le32(0xf0004000),
1631};
1632
1633static const __le32 iwlagn_concurrent_lookup[12] = {
1634 cpu_to_le32(0xaaaaaaaa),
1635 cpu_to_le32(0xaaaaaaaa),
1636 cpu_to_le32(0xaaaaaaaa),
1637 cpu_to_le32(0xaaaaaaaa),
1638 cpu_to_le32(0xaaaaaaaa),
1639 cpu_to_le32(0xaaaaaaaa),
1640 cpu_to_le32(0xaaaaaaaa),
1641 cpu_to_le32(0xaaaaaaaa),
1642 cpu_to_le32(0x00000000),
1643 cpu_to_le32(0x00000000),
1644 cpu_to_le32(0x00000000),
1645 cpu_to_le32(0x00000000),
1646};
1647
1648void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
1649{
1650 struct iwlagn_bt_cmd bt_cmd = {
1651 .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT,
1652 .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT,
1653 .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
1654 .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
1655 };
1656
1657 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
1658 sizeof(bt_cmd.bt3_lookup_table));
1659
1660 bt_cmd.prio_boost = priv->cfg->bt_prio_boost;
1661 bt_cmd.kill_ack_mask = priv->kill_ack_mask;
1662 bt_cmd.kill_cts_mask = priv->kill_cts_mask;
1663 bt_cmd.valid = priv->bt_valid;
1664
1665 /*
1666 * Configure BT coex mode to "no coexistence" when the
1667 * user disabled BT coexistence, we have no interface
1668 * (might be in monitor mode), or the interface is in
1669 * IBSS mode (no proper uCode support for coex then).
1670 */
1671 if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
1672 bt_cmd.flags = 0;
1673 } else {
1674 bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
1675 IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
1676 if (priv->bt_ch_announce)
1677 bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
1678 IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
1679 }
1680 if (priv->bt_full_concurrent)
1681 memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
1682 sizeof(iwlagn_concurrent_lookup));
1683 else
1684 memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup,
1685 sizeof(iwlagn_def_3w_lookup));
1686
1687 IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n",
1688 bt_cmd.flags ? "active" : "disabled",
1689 priv->bt_full_concurrent ?
1690 "full concurrency" : "3-wire");
1691
1692 if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd))
1693 IWL_ERR(priv, "failed to send BT Coex Config\n");
1694
1695 /*
1696 * When we are doing a restart, need to also reconfigure BT
1697 * SCO to the device. If not doing a restart, bt_sco_active
1698 * will always be false, so there's no need to have an extra
1699 * variable to check for it.
1700 */
1701 if (priv->bt_sco_active) {
1702 struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
1703
1704 if (priv->bt_sco_active)
1705 sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
1706 if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO,
1707 sizeof(sco_cmd), &sco_cmd))
1708 IWL_ERR(priv, "failed to send BT SCO command\n");
1709 }
1710}
1711
1712static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1713{
1714 struct iwl_priv *priv =
1715 container_of(work, struct iwl_priv, bt_traffic_change_work);
1716 int smps_request = -1;
1717
1718 IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
1719 priv->bt_traffic_load);
1720
1721 switch (priv->bt_traffic_load) {
1722 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1723 smps_request = IEEE80211_SMPS_AUTOMATIC;
1724 break;
1725 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1726 smps_request = IEEE80211_SMPS_DYNAMIC;
1727 break;
1728 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1729 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1730 smps_request = IEEE80211_SMPS_STATIC;
1731 break;
1732 default:
1733 IWL_ERR(priv, "Invalid BT traffic load: %d\n",
1734 priv->bt_traffic_load);
1735 break;
1736 }
1737
1738 mutex_lock(&priv->mutex);
1739
1740 if (priv->cfg->ops->lib->update_chain_flags)
1741 priv->cfg->ops->lib->update_chain_flags(priv);
1742
1743 if (smps_request != -1 &&
1744 priv->vif && priv->vif->type == NL80211_IFTYPE_STATION)
1745 ieee80211_request_smps(priv->vif, smps_request);
1746
1747 mutex_unlock(&priv->mutex);
1748}
1749
1750static void iwlagn_print_uartmsg(struct iwl_priv *priv,
1751 struct iwl_bt_uart_msg *uart_msg)
1752{
1753 IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
1754 "Update Req = 0x%X",
1755 (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
1756 BT_UART_MSG_FRAME1MSGTYPE_POS,
1757 (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
1758 BT_UART_MSG_FRAME1SSN_POS,
1759 (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
1760 BT_UART_MSG_FRAME1UPDATEREQ_POS);
1761
1762 IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
1763 "Chl_SeqN = 0x%X, In band = 0x%X",
1764 (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
1765 BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
1766 (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
1767 BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
1768 (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
1769 BT_UART_MSG_FRAME2CHLSEQN_POS,
1770 (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
1771 BT_UART_MSG_FRAME2INBAND_POS);
1772
1773 IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
1774 "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
1775 (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
1776 BT_UART_MSG_FRAME3SCOESCO_POS,
1777 (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
1778 BT_UART_MSG_FRAME3SNIFF_POS,
1779 (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
1780 BT_UART_MSG_FRAME3A2DP_POS,
1781 (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
1782 BT_UART_MSG_FRAME3ACL_POS,
1783 (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
1784 BT_UART_MSG_FRAME3MASTER_POS,
1785 (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
1786 BT_UART_MSG_FRAME3OBEX_POS);
1787
1788 IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X",
1789 (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
1790 BT_UART_MSG_FRAME4IDLEDURATION_POS);
1791
1792 IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
1793 "eSCO Retransmissions = 0x%X",
1794 (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
1795 BT_UART_MSG_FRAME5TXACTIVITY_POS,
1796 (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
1797 BT_UART_MSG_FRAME5RXACTIVITY_POS,
1798 (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
1799 BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
1800
1801 IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
1802 (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
1803 BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
1804 (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
1805 BT_UART_MSG_FRAME6DISCOVERABLE_POS);
1806
1807 IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = "
1808 "0x%X, Connectable = 0x%X",
1809 (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
1810 BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
1811 (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >>
1812 BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS,
1813 (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
1814 BT_UART_MSG_FRAME7CONNECTABLE_POS);
1815}
1816
1817static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
1818 struct iwl_bt_uart_msg *uart_msg)
1819{
1820 u8 kill_ack_msk;
1821 __le32 bt_kill_ack_msg[2] = {
1822 cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
1823
1824 kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
1825 BT_UART_MSG_FRAME3SNIFF_MSK |
1826 BT_UART_MSG_FRAME3SCOESCO_MSK) &
1827 uart_msg->frame3) == 0) ? 1 : 0;
1828 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
1829 priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
1830 priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
1831 /* schedule to send runtime bt_config */
1832 queue_work(priv->workqueue, &priv->bt_runtime_config);
1833 }
1834
1835}
1836
1837void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
1838 struct iwl_rx_mem_buffer *rxb)
1839{
1840 unsigned long flags;
1841 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1842 struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
1843 struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
1844 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
1845 u8 last_traffic_load;
1846
1847 IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
1848 IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
1849 IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);
1850 IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n",
1851 coex->bt_ci_compliance);
1852 iwlagn_print_uartmsg(priv, uart_msg);
1853
1854 last_traffic_load = priv->notif_bt_traffic_load;
1855 priv->notif_bt_traffic_load = coex->bt_traffic_load;
1856 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
1857 if (priv->bt_status != coex->bt_status ||
1858 last_traffic_load != coex->bt_traffic_load) {
1859 if (coex->bt_status) {
1860 /* BT on */
1861 if (!priv->bt_ch_announce)
1862 priv->bt_traffic_load =
1863 IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1864 else
1865 priv->bt_traffic_load =
1866 coex->bt_traffic_load;
1867 } else {
1868 /* BT off */
1869 priv->bt_traffic_load =
1870 IWL_BT_COEX_TRAFFIC_LOAD_NONE;
1871 }
1872 priv->bt_status = coex->bt_status;
1873 queue_work(priv->workqueue,
1874 &priv->bt_traffic_change_work);
1875 }
1876 if (priv->bt_sco_active !=
1877 (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
1878 priv->bt_sco_active = uart_msg->frame3 &
1879 BT_UART_MSG_FRAME3SCOESCO_MSK;
1880 if (priv->bt_sco_active)
1881 sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
1882 iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO,
1883 sizeof(sco_cmd), &sco_cmd, NULL);
1884 }
1885 }
1886
1887 iwlagn_set_kill_ack_msk(priv, uart_msg);
1888
1889 /* FIXME: based on notification, adjust the prio_boost */
1890
1891 spin_lock_irqsave(&priv->lock, flags);
1892 priv->bt_ci_compliance = coex->bt_ci_compliance;
1893 spin_unlock_irqrestore(&priv->lock, flags);
1894}
1895
1896void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
1897{
1898 iwlagn_rx_handler_setup(priv);
1899 priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
1900 iwlagn_bt_coex_profile_notif;
1901}
1902
1903void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
1904{
1905 iwlagn_setup_deferred_work(priv);
1906
1907 INIT_WORK(&priv->bt_traffic_change_work,
1908 iwlagn_bt_traffic_change_work);
1909}
1910
1911void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
1912{
1913 cancel_work_sync(&priv->bt_traffic_change_work);
1914}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 771ceffb8f8b..f2499e1f2047 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -464,11 +464,11 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
464 if (priv->cfg->advanced_bt_coexist) { 464 if (priv->cfg->advanced_bt_coexist) {
465 /* Configure Bluetooth device coexistence support */ 465 /* Configure Bluetooth device coexistence support */
466 /* need to perform this before any calibration */ 466 /* need to perform this before any calibration */
467 priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; 467 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
468 priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; 468 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
469 priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; 469 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
470 priv->cfg->ops->hcmd->send_bt_config(priv); 470 priv->cfg->ops->hcmd->send_bt_config(priv);
471 priv->bt_valid = IWL6000G2B_BT_VALID_ENABLE_FLAGS; 471 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
472 472
473 if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) { 473 if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) {
474 iwlagn_send_prio_tbl(priv); 474 iwlagn_send_prio_tbl(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4410f820c2f3..5e0d0d527bf0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4024,9 +4024,9 @@ static int iwl_init_drv(struct iwl_priv *priv)
4024 4024
4025 /* init bt coex */ 4025 /* init bt coex */
4026 if (priv->cfg->advanced_bt_coexist) { 4026 if (priv->cfg->advanced_bt_coexist) {
4027 priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; 4027 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
4028 priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; 4028 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
4029 priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; 4029 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
4030 priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; 4030 priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
4031 priv->bt_duration = BT_DURATION_LIMIT_DEF; 4031 priv->bt_duration = BT_DURATION_LIMIT_DEF;
4032 priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; 4032 priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index cc6464dc72e5..1a7f70f293a0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -95,6 +95,7 @@ extern struct iwl_cfg iwl1000_bg_cfg;
95 95
96extern struct iwl_mod_params iwlagn_mod_params; 96extern struct iwl_mod_params iwlagn_mod_params;
97extern struct iwl_hcmd_ops iwlagn_hcmd; 97extern struct iwl_hcmd_ops iwlagn_hcmd;
98extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
98extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 99extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
99 100
100int iwl_reset_ict(struct iwl_priv *priv); 101int iwl_reset_ict(struct iwl_priv *priv);
@@ -226,4 +227,12 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
226int iwlagn_send_rxon_assoc(struct iwl_priv *priv); 227int iwlagn_send_rxon_assoc(struct iwl_priv *priv);
227int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); 228int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
228 229
230/* bt coex */
231void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
232void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
233 struct iwl_rx_mem_buffer *rxb);
234void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
235void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
236void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
237
229#endif /* __iwl_agn_h__ */ 238#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 5df22f1d57a5..8ed2412862d7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2411,52 +2411,52 @@ struct iwl_bt_cmd {
2411 __le32 kill_cts_mask; 2411 __le32 kill_cts_mask;
2412} __packed; 2412} __packed;
2413 2413
2414#define IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION BIT(0) 2414#define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0)
2415 2415
2416#define IWL6000G2B_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) 2416#define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5))
2417#define IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT 3 2417#define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3
2418#define IWL6000G2B_BT_FLAG_COEX_MODE_DISABLED 0 2418#define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0
2419#define IWL6000G2B_BT_FLAG_COEX_MODE_LEGACY_2W 1 2419#define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1
2420#define IWL6000G2B_BT_FLAG_COEX_MODE_3W 2 2420#define IWLAGN_BT_FLAG_COEX_MODE_3W 2
2421#define IWL6000G2B_BT_FLAG_COEX_MODE_4W 3 2421#define IWLAGN_BT_FLAG_COEX_MODE_4W 3
2422 2422
2423#define IWL6000G2B_BT_FLAG_UCODE_DEFAULT BIT(6) 2423#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
2424#define IWL6000G2B_BT_FLAG_NOCOEX_NOTIF BIT(7) 2424#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7)
2425 2425
2426#define IWL6000G2B_BT_PRIO_BOOST_MAX 0xFF 2426#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF
2427#define IWL6000G2B_BT_PRIO_BOOST_MIN 0x00 2427#define IWLAGN_BT_PRIO_BOOST_MIN 0x00
2428#define IWL6000G2B_BT_PRIO_BOOST_DEFAULT 0xF0 2428#define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0
2429 2429
2430#define IWL6000G2B_BT_MAX_KILL_DEFAULT 5 2430#define IWLAGN_BT_MAX_KILL_DEFAULT 5
2431 2431
2432#define IWL6000G2B_BT3_T7_DEFAULT 1 2432#define IWLAGN_BT3_T7_DEFAULT 1
2433 2433
2434#define IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) 2434#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff)
2435#define IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) 2435#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff)
2436 2436
2437#define IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT 2 2437#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
2438 2438
2439#define IWL6000G2B_BT3_T2_DEFAULT 0xc 2439#define IWLAGN_BT3_T2_DEFAULT 0xc
2440 2440
2441#define IWL6000G2B_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) 2441#define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0))
2442#define IWL6000G2B_BT_VALID_BOOST cpu_to_le16(BIT(1)) 2442#define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1))
2443#define IWL6000G2B_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) 2443#define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2))
2444#define IWL6000G2B_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) 2444#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3))
2445#define IWL6000G2B_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) 2445#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4))
2446#define IWL6000G2B_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) 2446#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5))
2447#define IWL6000G2B_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) 2447#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6))
2448#define IWL6000G2B_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) 2448#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7))
2449 2449
2450#define IWL6000G2B_BT_ALL_VALID_MSK (IWL6000G2B_BT_VALID_ENABLE_FLAGS | \ 2450#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \
2451 IWL6000G2B_BT_VALID_BOOST | \ 2451 IWLAGN_BT_VALID_BOOST | \
2452 IWL6000G2B_BT_VALID_MAX_KILL | \ 2452 IWLAGN_BT_VALID_MAX_KILL | \
2453 IWL6000G2B_BT_VALID_3W_TIMERS | \ 2453 IWLAGN_BT_VALID_3W_TIMERS | \
2454 IWL6000G2B_BT_VALID_KILL_ACK_MASK | \ 2454 IWLAGN_BT_VALID_KILL_ACK_MASK | \
2455 IWL6000G2B_BT_VALID_KILL_CTS_MASK | \ 2455 IWLAGN_BT_VALID_KILL_CTS_MASK | \
2456 IWL6000G2B_BT_VALID_BT4_TIMES | \ 2456 IWLAGN_BT_VALID_BT4_TIMES | \
2457 IWL6000G2B_BT_VALID_3W_LUT) 2457 IWLAGN_BT_VALID_3W_LUT)
2458 2458
2459struct iwl6000g2b_bt_cmd { 2459struct iwlagn_bt_cmd {
2460 u8 flags; 2460 u8 flags;
2461 u8 ledtime; /* unused */ 2461 u8 ledtime; /* unused */
2462 u8 max_kill; 2462 u8 max_kill;
@@ -2473,9 +2473,9 @@ struct iwl6000g2b_bt_cmd {
2473 u8 reserved[3]; 2473 u8 reserved[3];
2474}; 2474};
2475 2475
2476#define IWL6000G2B_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) 2476#define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0))
2477 2477
2478struct iwl6000g2b_bt_sco_cmd { 2478struct iwlagn_bt_sco_cmd {
2479 __le32 flags; 2479 __le32 flags;
2480}; 2480};
2481 2481