diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 |
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 */ | ||
1986 | int 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 | */ |
281 | extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); | 281 | extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); |
282 | 282 | ||
283 | extern 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 | ||
1437 | static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | 1436 | static 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); | |||
1382 | IWL5000_UCODE_GET(init_data_size); | 1382 | IWL5000_UCODE_GET(init_data_size); |
1383 | IWL5000_UCODE_GET(boot_size); | 1383 | IWL5000_UCODE_GET(boot_size); |
1384 | 1384 | ||
1385 | static 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 | |||
1385 | struct iwl_hcmd_ops iwl5000_hcmd = { | 1415 | struct 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 | ||
175 | static 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 | |||
175 | static struct iwl_lib_ops iwl6000_lib = { | 206 | static 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 | } |
1292 | EXPORT_SYMBOL(iwl_rx_csa); | 1297 | EXPORT_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 | ||