diff options
author | Eliad Peller <eliad@wizery.com> | 2011-10-10 04:13:12 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-10-11 08:12:13 -0400 |
commit | 9f259c4e5e42d5f0c25675dc1088cd96dc81a9f1 (patch) | |
tree | f09fbef3eaaca495b24b0546ad813107d3492b30 /drivers/net/wireless/wl12xx | |
parent | 6bd650299046f00df6d7374c7f61c5afe6df6696 (diff) |
wl12xx: make op_config configure all vifs
When mac80211 changes a global (hw) config, iterate
through all the relevant vifs and update them.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index cffb40be7b5b..b2640edcc3a8 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -2408,63 +2408,20 @@ out: | |||
2408 | return ret; | 2408 | return ret; |
2409 | } | 2409 | } |
2410 | 2410 | ||
2411 | static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | 2411 | static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
2412 | struct ieee80211_conf *conf, u32 changed) | ||
2412 | { | 2413 | { |
2413 | struct wl1271 *wl = hw->priv; | 2414 | bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); |
2414 | struct ieee80211_vif *vif = wl->vif; /* TODO: reconfig all vifs */ | 2415 | int channel, ret; |
2415 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
2416 | struct ieee80211_conf *conf = &hw->conf; | ||
2417 | int channel, ret = 0; | ||
2418 | bool is_ap; | ||
2419 | 2416 | ||
2420 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 2417 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
2421 | 2418 | ||
2422 | wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s" | ||
2423 | " changed 0x%x", | ||
2424 | channel, | ||
2425 | conf->flags & IEEE80211_CONF_PS ? "on" : "off", | ||
2426 | conf->power_level, | ||
2427 | conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use", | ||
2428 | changed); | ||
2429 | |||
2430 | /* | ||
2431 | * mac80211 will go to idle nearly immediately after transmitting some | ||
2432 | * frames, such as the deauth. To make sure those frames reach the air, | ||
2433 | * wait here until the TX queue is fully flushed. | ||
2434 | */ | ||
2435 | if ((changed & IEEE80211_CONF_CHANGE_IDLE) && | ||
2436 | (conf->flags & IEEE80211_CONF_IDLE)) | ||
2437 | wl1271_tx_flush(wl); | ||
2438 | |||
2439 | mutex_lock(&wl->mutex); | ||
2440 | |||
2441 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | ||
2442 | /* we support configuring the channel and band while off */ | ||
2443 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL)) { | ||
2444 | wl->band = conf->channel->band; | ||
2445 | wl->channel = channel; | ||
2446 | } | ||
2447 | |||
2448 | if ((changed & IEEE80211_CONF_CHANGE_POWER)) | ||
2449 | wl->power_level = conf->power_level; | ||
2450 | |||
2451 | goto out; | ||
2452 | } | ||
2453 | |||
2454 | is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); | ||
2455 | |||
2456 | ret = wl1271_ps_elp_wakeup(wl); | ||
2457 | if (ret < 0) | ||
2458 | goto out; | ||
2459 | |||
2460 | /* if the channel changes while joined, join again */ | 2419 | /* if the channel changes while joined, join again */ |
2461 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && | 2420 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && |
2462 | ((wlvif->band != conf->channel->band) || | 2421 | ((wlvif->band != conf->channel->band) || |
2463 | (wlvif->channel != channel))) { | 2422 | (wlvif->channel != channel))) { |
2464 | /* send all pending packets */ | 2423 | /* send all pending packets */ |
2465 | wl1271_tx_work_locked(wl); | 2424 | wl1271_tx_work_locked(wl); |
2466 | wl->band = conf->channel->band; | ||
2467 | wl->channel = channel; | ||
2468 | wlvif->band = conf->channel->band; | 2425 | wlvif->band = conf->channel->band; |
2469 | wlvif->channel = channel; | 2426 | wlvif->channel = channel; |
2470 | 2427 | ||
@@ -2493,7 +2450,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2493 | ret = wl12xx_croc(wl, | 2450 | ret = wl12xx_croc(wl, |
2494 | wlvif->dev_role_id); | 2451 | wlvif->dev_role_id); |
2495 | if (ret < 0) | 2452 | if (ret < 0) |
2496 | goto out_sleep; | 2453 | return ret; |
2497 | } | 2454 | } |
2498 | ret = wl1271_join(wl, wlvif, false); | 2455 | ret = wl1271_join(wl, wlvif, false); |
2499 | if (ret < 0) | 2456 | if (ret < 0) |
@@ -2510,7 +2467,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2510 | ret = wl12xx_croc(wl, | 2467 | ret = wl12xx_croc(wl, |
2511 | wlvif->dev_role_id); | 2468 | wlvif->dev_role_id); |
2512 | if (ret < 0) | 2469 | if (ret < 0) |
2513 | goto out_sleep; | 2470 | return ret; |
2514 | 2471 | ||
2515 | ret = wl12xx_roc(wl, wlvif, | 2472 | ret = wl12xx_roc(wl, wlvif, |
2516 | wlvif->dev_role_id); | 2473 | wlvif->dev_role_id); |
@@ -2566,12 +2523,65 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2566 | if (conf->power_level != wlvif->power_level) { | 2523 | if (conf->power_level != wlvif->power_level) { |
2567 | ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level); | 2524 | ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level); |
2568 | if (ret < 0) | 2525 | if (ret < 0) |
2569 | goto out_sleep; | 2526 | return ret; |
2570 | 2527 | ||
2571 | wl->power_level = conf->power_level; | ||
2572 | wlvif->power_level = conf->power_level; | 2528 | wlvif->power_level = conf->power_level; |
2573 | } | 2529 | } |
2574 | 2530 | ||
2531 | return 0; | ||
2532 | } | ||
2533 | |||
2534 | static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | ||
2535 | { | ||
2536 | struct wl1271 *wl = hw->priv; | ||
2537 | struct wl12xx_vif *wlvif; | ||
2538 | struct ieee80211_conf *conf = &hw->conf; | ||
2539 | int channel, ret = 0; | ||
2540 | |||
2541 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
2542 | |||
2543 | wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s" | ||
2544 | " changed 0x%x", | ||
2545 | channel, | ||
2546 | conf->flags & IEEE80211_CONF_PS ? "on" : "off", | ||
2547 | conf->power_level, | ||
2548 | conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use", | ||
2549 | changed); | ||
2550 | |||
2551 | /* | ||
2552 | * mac80211 will go to idle nearly immediately after transmitting some | ||
2553 | * frames, such as the deauth. To make sure those frames reach the air, | ||
2554 | * wait here until the TX queue is fully flushed. | ||
2555 | */ | ||
2556 | if ((changed & IEEE80211_CONF_CHANGE_IDLE) && | ||
2557 | (conf->flags & IEEE80211_CONF_IDLE)) | ||
2558 | wl1271_tx_flush(wl); | ||
2559 | |||
2560 | mutex_lock(&wl->mutex); | ||
2561 | |||
2562 | /* we support configuring the channel and band even while off */ | ||
2563 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
2564 | wl->band = conf->channel->band; | ||
2565 | wl->channel = channel; | ||
2566 | } | ||
2567 | |||
2568 | if (changed & IEEE80211_CONF_CHANGE_POWER) | ||
2569 | wl->power_level = conf->power_level; | ||
2570 | |||
2571 | if (unlikely(wl->state == WL1271_STATE_OFF)) | ||
2572 | goto out; | ||
2573 | |||
2574 | ret = wl1271_ps_elp_wakeup(wl); | ||
2575 | if (ret < 0) | ||
2576 | goto out; | ||
2577 | |||
2578 | /* configure each interface */ | ||
2579 | wl12xx_for_each_wlvif(wl, wlvif) { | ||
2580 | ret = wl12xx_config_vif(wl, wlvif, conf, changed); | ||
2581 | if (ret < 0) | ||
2582 | goto out_sleep; | ||
2583 | } | ||
2584 | |||
2575 | out_sleep: | 2585 | out_sleep: |
2576 | wl1271_ps_elp_sleep(wl); | 2586 | wl1271_ps_elp_sleep(wl); |
2577 | 2587 | ||