aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
7 files changed, 89 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index f5d75288bd27..09a7bd2c0be4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1982,12 +1982,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1982 return 0; 1982 return 0;
1983} 1983}
1984 1984
1985/* will add 3945 channel switch cmd handling later */
1986int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1987{
1988 return 0;
1989}
1990
1991/** 1985/**
1992 * iwl3945_reg_txpower_periodic - called when time to check our temperature. 1986 * iwl3945_reg_txpower_periodic - called when time to check our temperature.
1993 * 1987 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index f3907c1079f5..964c01980ac0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -280,8 +280,6 @@ extern void iwl3945_config_ap(struct iwl_priv *priv);
280 */ 280 */
281extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); 281extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
282 282
283extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
284
285/* 283/*
286 * Forward declare iwl-3945.c functions for iwl-base.c 284 * Forward declare iwl-3945.c functions for iwl-base.c
287 */ 285 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index bd856df5b04d..1ff465ad40d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1433,14 +1433,13 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1433 return ret; 1433 return ret;
1434} 1434}
1435 1435
1436#ifdef IEEE80211_CONF_CHANNEL_SWITCH
1437static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) 1436static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1438{ 1437{
1439 int rc; 1438 int rc;
1440 u8 band = 0; 1439 u8 band = 0;
1441 bool is_ht40 = false; 1440 bool is_ht40 = false;
1442 u8 ctrl_chan_high = 0; 1441 u8 ctrl_chan_high = 0;
1443 struct iwl4965_channel_switch_cmd cmd = { 0 }; 1442 struct iwl4965_channel_switch_cmd cmd;
1444 const struct iwl_channel_info *ch_info; 1443 const struct iwl_channel_info *ch_info;
1445 1444
1446 band = priv->band == IEEE80211_BAND_2GHZ; 1445 band = priv->band == IEEE80211_BAND_2GHZ;
@@ -1461,8 +1460,11 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1461 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 1460 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1462 if (ch_info) 1461 if (ch_info)
1463 cmd.expect_beacon = is_channel_radar(ch_info); 1462 cmd.expect_beacon = is_channel_radar(ch_info);
1464 else 1463 else {
1465 cmd.expect_beacon = 1; 1464 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1465 priv->active_rxon.channel, channel);
1466 return -EFAULT;
1467 }
1466 1468
1467 rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40, 1469 rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
1468 ctrl_chan_high, &cmd.tx_power); 1470 ctrl_chan_high, &cmd.tx_power);
@@ -1474,7 +1476,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1474 rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); 1476 rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1475 return rc; 1477 return rc;
1476} 1478}
1477#endif
1478 1479
1479/** 1480/**
1480 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 1481 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
@@ -2171,6 +2172,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2171 .load_ucode = iwl4965_load_bsm, 2172 .load_ucode = iwl4965_load_bsm,
2172 .dump_nic_event_log = iwl_dump_nic_event_log, 2173 .dump_nic_event_log = iwl_dump_nic_event_log,
2173 .dump_nic_error_log = iwl_dump_nic_error_log, 2174 .dump_nic_error_log = iwl_dump_nic_error_log,
2175 .set_channel_switch = iwl4965_hw_channel_switch,
2174 .apm_ops = { 2176 .apm_ops = {
2175 .init = iwl_apm_init, 2177 .init = iwl_apm_init,
2176 .stop = iwl_apm_stop, 2178 .stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a6e347b9799a..d256fecc6cda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1382,6 +1382,36 @@ IWL5000_UCODE_GET(init_size);
1382IWL5000_UCODE_GET(init_data_size); 1382IWL5000_UCODE_GET(init_data_size);
1383IWL5000_UCODE_GET(boot_size); 1383IWL5000_UCODE_GET(boot_size);
1384 1384
1385static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1386{
1387 struct iwl5000_channel_switch_cmd cmd;
1388 const struct iwl_channel_info *ch_info;
1389 struct iwl_host_cmd hcmd = {
1390 .id = REPLY_CHANNEL_SWITCH,
1391 .len = sizeof(cmd),
1392 .flags = CMD_SIZE_HUGE,
1393 .data = &cmd,
1394 };
1395
1396 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
1397 priv->active_rxon.channel, channel);
1398 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
1399 cmd.channel = cpu_to_le16(channel);
1400 cmd.rxon_flags = priv->active_rxon.flags;
1401 cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
1402 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1403 ch_info = iwl_get_channel_info(priv, priv->band, channel);
1404 if (ch_info)
1405 cmd.expect_beacon = is_channel_radar(ch_info);
1406 else {
1407 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1408 priv->active_rxon.channel, channel);
1409 return -EFAULT;
1410 }
1411
1412 return iwl_send_cmd_sync(priv, &hcmd);
1413}
1414
1385struct iwl_hcmd_ops iwl5000_hcmd = { 1415struct iwl_hcmd_ops iwl5000_hcmd = {
1386 .rxon_assoc = iwl5000_send_rxon_assoc, 1416 .rxon_assoc = iwl5000_send_rxon_assoc,
1387 .commit_rxon = iwl_commit_rxon, 1417 .commit_rxon = iwl_commit_rxon,
@@ -1429,6 +1459,7 @@ struct iwl_lib_ops iwl5000_lib = {
1429 .alive_notify = iwl5000_alive_notify, 1459 .alive_notify = iwl5000_alive_notify,
1430 .send_tx_power = iwl5000_send_tx_power, 1460 .send_tx_power = iwl5000_send_tx_power,
1431 .update_chain_flags = iwl_update_chain_flags, 1461 .update_chain_flags = iwl_update_chain_flags,
1462 .set_channel_switch = iwl5000_hw_channel_switch,
1432 .apm_ops = { 1463 .apm_ops = {
1433 .init = iwl_apm_init, 1464 .init = iwl_apm_init,
1434 .stop = iwl_apm_stop, 1465 .stop = iwl_apm_stop,
@@ -1480,6 +1511,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1480 .alive_notify = iwl5000_alive_notify, 1511 .alive_notify = iwl5000_alive_notify,
1481 .send_tx_power = iwl5000_send_tx_power, 1512 .send_tx_power = iwl5000_send_tx_power,
1482 .update_chain_flags = iwl_update_chain_flags, 1513 .update_chain_flags = iwl_update_chain_flags,
1514 .set_channel_switch = iwl5000_hw_channel_switch,
1483 .apm_ops = { 1515 .apm_ops = {
1484 .init = iwl_apm_init, 1516 .init = iwl_apm_init,
1485 .stop = iwl_apm_stop, 1517 .stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f5855293c767..f5639b47668a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -172,6 +172,37 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
172 return 0; 172 return 0;
173} 173}
174 174
175static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
176{
177 struct iwl6000_channel_switch_cmd cmd;
178 const struct iwl_channel_info *ch_info;
179 struct iwl_host_cmd hcmd = {
180 .id = REPLY_CHANNEL_SWITCH,
181 .len = sizeof(cmd),
182 .flags = CMD_SIZE_HUGE,
183 .data = &cmd,
184 };
185
186 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
187 priv->active_rxon.channel, channel);
188
189 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
190 cmd.channel = cpu_to_le16(channel);
191 cmd.rxon_flags = priv->active_rxon.flags;
192 cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
193 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
194 ch_info = iwl_get_channel_info(priv, priv->band, channel);
195 if (ch_info)
196 cmd.expect_beacon = is_channel_radar(ch_info);
197 else {
198 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
199 priv->active_rxon.channel, channel);
200 return -EFAULT;
201 }
202
203 return iwl_send_cmd_sync(priv, &hcmd);
204}
205
175static struct iwl_lib_ops iwl6000_lib = { 206static struct iwl_lib_ops iwl6000_lib = {
176 .set_hw_params = iwl6000_hw_set_hw_params, 207 .set_hw_params = iwl6000_hw_set_hw_params,
177 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 208 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -192,6 +223,7 @@ static struct iwl_lib_ops iwl6000_lib = {
192 .alive_notify = iwl5000_alive_notify, 223 .alive_notify = iwl5000_alive_notify,
193 .send_tx_power = iwl5000_send_tx_power, 224 .send_tx_power = iwl5000_send_tx_power,
194 .update_chain_flags = iwl_update_chain_flags, 225 .update_chain_flags = iwl_update_chain_flags,
226 .set_channel_switch = iwl6000_hw_channel_switch,
195 .apm_ops = { 227 .apm_ops = {
196 .init = iwl_apm_init, 228 .init = iwl_apm_init,
197 .stop = iwl_apm_stop, 229 .stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e43469cfbbc0..d2b56baf98fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1284,10 +1284,15 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1284 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1284 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1285 struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; 1285 struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
1286 struct iwl_csa_notification *csa = &(pkt->u.csa_notif); 1286 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
1287 IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n", 1287
1288 le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); 1288 if (!le32_to_cpu(csa->status)) {
1289 rxon->channel = csa->channel; 1289 rxon->channel = csa->channel;
1290 priv->staging_rxon.channel = csa->channel; 1290 priv->staging_rxon.channel = csa->channel;
1291 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
1292 le16_to_cpu(csa->channel));
1293 } else
1294 IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
1295 le16_to_cpu(csa->channel));
1291} 1296}
1292EXPORT_SYMBOL(iwl_rx_csa); 1297EXPORT_SYMBOL(iwl_rx_csa);
1293 1298
@@ -2714,6 +2719,14 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2714 goto set_ch_out; 2719 goto set_ch_out;
2715 } 2720 }
2716 2721
2722 if (iwl_is_associated(priv) &&
2723 (le16_to_cpu(priv->active_rxon.channel) != ch) &&
2724 priv->cfg->ops->lib->set_channel_switch) {
2725 ret = priv->cfg->ops->lib->set_channel_switch(priv,
2726 ch);
2727 goto out;
2728 }
2729
2717 spin_lock_irqsave(&priv->lock, flags); 2730 spin_lock_irqsave(&priv->lock, flags);
2718 2731
2719 /* Configure HT40 channels */ 2732 /* Configure HT40 channels */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 02bacc4975f0..b875dcfca2d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -169,6 +169,7 @@ struct iwl_lib_ops {
169 int (*load_ucode)(struct iwl_priv *priv); 169 int (*load_ucode)(struct iwl_priv *priv);
170 void (*dump_nic_event_log)(struct iwl_priv *priv); 170 void (*dump_nic_event_log)(struct iwl_priv *priv);
171 void (*dump_nic_error_log)(struct iwl_priv *priv); 171 void (*dump_nic_error_log)(struct iwl_priv *priv);
172 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
172 /* power management */ 173 /* power management */
173 struct iwl_apm_ops apm_ops; 174 struct iwl_apm_ops apm_ops;
174 175