Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

Conflicts:
	drivers/net/wireless/iwlwifi/dvm/tx.c
	drivers/net/wireless/ti/wlcore/sdio.c
	drivers/net/wireless/ti/wlcore/spi.c
This commit is contained in:
John W. Linville
2013-02-18 13:47:13 -05:00
189 changed files with 12401 additions and 3250 deletions
+5 -5
View File
@@ -309,7 +309,7 @@ static struct omap2_hsmmc_info mmc[] = {
.gpio_wp = 63, .gpio_wp = 63,
.deferred = true, .deferred = true,
}, },
#ifdef CONFIG_WL12XX_PLATFORM_DATA #ifdef CONFIG_WILINK_PLATFORM_DATA
{ {
.name = "wl1271", .name = "wl1271",
.mmc = 2, .mmc = 2,
@@ -450,7 +450,7 @@ static struct regulator_init_data omap3evm_vio = {
.consumer_supplies = omap3evm_vio_supply, .consumer_supplies = omap3evm_vio_supply,
}; };
#ifdef CONFIG_WL12XX_PLATFORM_DATA #ifdef CONFIG_WILINK_PLATFORM_DATA
#define OMAP3EVM_WLAN_PMENA_GPIO (150) #define OMAP3EVM_WLAN_PMENA_GPIO (150)
#define OMAP3EVM_WLAN_IRQ_GPIO (149) #define OMAP3EVM_WLAN_IRQ_GPIO (149)
@@ -563,7 +563,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE), OMAP_PIN_OFF_NONE),
OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_NONE), OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA #ifdef CONFIG_WILINK_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */ /* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
@@ -601,7 +601,7 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA #ifdef CONFIG_WILINK_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */ /* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
@@ -637,7 +637,7 @@ static struct gpio omap3_evm_ehci_gpios[] __initdata = {
static void __init omap3_evm_wl12xx_init(void) static void __init omap3_evm_wl12xx_init(void)
{ {
#ifdef CONFIG_WL12XX_PLATFORM_DATA #ifdef CONFIG_WILINK_PLATFORM_DATA
int ret; int ret;
/* WL12xx WLAN Init */ /* WL12xx WLAN Init */
+4
View File
@@ -1613,6 +1613,10 @@ ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
ah->ah_cal_mask |= AR5K_CALIBRATION_NF; ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
if (WARN_ON(ee_mode < 0)) {
ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
return;
}
/* completed NF calibration, test threshold */ /* completed NF calibration, test threshold */
nf = ath5k_hw_read_measured_noise_floor(ah); nf = ath5k_hw_read_measured_noise_floor(ah);
+2
View File
@@ -985,6 +985,8 @@ ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
return; return;
ee_mode = ath5k_eeprom_mode_from_channel(channel); ee_mode = ath5k_eeprom_mode_from_channel(channel);
if (WARN_ON(ee_mode < 0))
return;
/* Adjust power delta for channel 14 */ /* Adjust power delta for channel 14 */
if (channel->center_freq == 2484) if (channel->center_freq == 2484)
+73 -44
View File
@@ -427,6 +427,30 @@ static bool ath6kl_is_tx_pending(struct ath6kl *ar)
return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0; return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
} }
static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
bool enable)
{
int err;
if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
return;
if (vif->nw_type != INFRA_NETWORK)
return;
if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
vif->ar->fw_capabilities))
return;
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
enable ? "enable" : "disable");
err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
vif->fw_vif_idx, enable);
if (err)
ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
enable ? "enable" : "disable", err);
}
static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme) struct cfg80211_connect_params *sme)
@@ -616,13 +640,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif->req_bssid, vif->ch_hint, vif->req_bssid, vif->ch_hint,
ar->connect_ctrl_flags, nw_subtype); ar->connect_ctrl_flags, nw_subtype);
/* disable background scan if period is 0 */ if (sme->bg_scan_period == 0) {
if (sme->bg_scan_period == 0) /* disable background scan if period is 0 */
sme->bg_scan_period = 0xffff; sme->bg_scan_period = 0xffff;
} else if (sme->bg_scan_period == -1) {
/* configure default value if not specified */ /* configure default value if not specified */
if (sme->bg_scan_period == -1)
sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD; sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
}
ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0, ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
@@ -767,7 +791,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
nw_type & ADHOC_CREATOR ? "creator" : "joiner"); nw_type & ADHOC_CREATOR ? "creator" : "joiner");
cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
cfg80211_put_bss(bss); cfg80211_put_bss(ar->wiphy, bss);
return; return;
} }
@@ -778,7 +802,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
assoc_req_ie, assoc_req_len, assoc_req_ie, assoc_req_len,
assoc_resp_ie, assoc_resp_len, assoc_resp_ie, assoc_resp_len,
WLAN_STATUS_SUCCESS, GFP_KERNEL); WLAN_STATUS_SUCCESS, GFP_KERNEL);
cfg80211_put_bss(bss); cfg80211_put_bss(ar->wiphy, bss);
} else if (vif->sme_state == SME_CONNECTED) { } else if (vif->sme_state == SME_CONNECTED) {
/* inform roam event to cfg80211 */ /* inform roam event to cfg80211 */
cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
@@ -1454,10 +1478,10 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
return -EIO; return -EIO;
if (pmgmt) { if (pmgmt) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
mode.pwr_mode = REC_POWER; mode.pwr_mode = REC_POWER;
} else { } else {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
mode.pwr_mode = MAX_PERF_POWER; mode.pwr_mode = MAX_PERF_POWER;
} }
@@ -1509,7 +1533,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
list_del(&vif->list); list_del(&vif->list);
spin_unlock_bh(&ar->list_lock); spin_unlock_bh(&ar->list_lock);
ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
ath6kl_cfg80211_vif_cleanup(vif); ath6kl_cfg80211_vif_cleanup(vif);
@@ -1559,17 +1583,13 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
set_iface_type: set_iface_type:
switch (type) { switch (type) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
vif->next_mode = INFRA_NETWORK; vif->next_mode = INFRA_NETWORK;
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
vif->next_mode = ADHOC_NETWORK; vif->next_mode = ADHOC_NETWORK;
break; break;
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
vif->next_mode = AP_NETWORK;
break;
case NL80211_IFTYPE_P2P_CLIENT:
vif->next_mode = INFRA_NETWORK;
break;
case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_P2P_GO:
vif->next_mode = AP_NETWORK; vif->next_mode = AP_NETWORK;
break; break;
@@ -1778,14 +1798,14 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
if (vif->target_stats.rx_byte) { if (vif->target_stats.rx_byte) {
sinfo->rx_bytes = vif->target_stats.rx_byte; sinfo->rx_bytes = vif->target_stats.rx_byte;
sinfo->filled |= STATION_INFO_RX_BYTES; sinfo->filled |= STATION_INFO_RX_BYTES64;
sinfo->rx_packets = vif->target_stats.rx_pkt; sinfo->rx_packets = vif->target_stats.rx_pkt;
sinfo->filled |= STATION_INFO_RX_PACKETS; sinfo->filled |= STATION_INFO_RX_PACKETS;
} }
if (vif->target_stats.tx_byte) { if (vif->target_stats.tx_byte) {
sinfo->tx_bytes = vif->target_stats.tx_byte; sinfo->tx_bytes = vif->target_stats.tx_byte;
sinfo->filled |= STATION_INFO_TX_BYTES; sinfo->filled |= STATION_INFO_TX_BYTES64;
sinfo->tx_packets = vif->target_stats.tx_pkt; sinfo->tx_packets = vif->target_stats.tx_pkt;
sinfo->filled |= STATION_INFO_TX_PACKETS; sinfo->filled |= STATION_INFO_TX_PACKETS;
} }
@@ -2673,30 +2693,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
return 0; return 0;
} }
void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
{
int err;
if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
return;
if (vif->nw_type != INFRA_NETWORK)
return;
if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
vif->ar->fw_capabilities))
return;
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
enable ? "enable" : "disable");
err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
vif->fw_vif_idx, enable);
if (err)
ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
enable ? "enable" : "disable", err);
}
static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
u8 *rsn_capab) u8 *rsn_capab)
{ {
@@ -2776,9 +2772,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
ar->ap_mode_bkey.valid = false; ar->ap_mode_bkey.valid = false;
/* TODO: ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
* info->interval info->beacon_interval);
*/
if (ret)
ath6kl_warn("Failed to set beacon interval: %d\n", ret);
ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx, ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
info->dtim_period); info->dtim_period);
@@ -3557,6 +3555,37 @@ static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
return 0; return 0;
} }
void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
{
static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bool discon_issued;
netif_stop_queue(vif->ndev);
clear_bit(WLAN_ENABLED, &vif->flags);
if (wmi_ready) {
discon_issued = test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags);
ath6kl_disconnect(vif);
del_timer(&vif->disconnect_timer);
if (discon_issued)
ath6kl_disconnect_event(vif, DISCONNECT_CMD,
(vif->nw_type & AP_NETWORK) ?
bcast_mac : vif->bssid,
0, NULL, 0);
}
if (vif->scan_req) {
cfg80211_scan_done(vif->scan_req, true);
vif->scan_req = NULL;
}
/* need to clean up enhanced bmiss detection fw state */
ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
}
void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
{ {
struct ath6kl *ar = vif->ar; struct ath6kl *ar = vif->ar;
@@ -61,7 +61,5 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
struct ath6kl *ath6kl_cfg80211_create(void); struct ath6kl *ath6kl_cfg80211_create(void);
void ath6kl_cfg80211_destroy(struct ath6kl *ar); void ath6kl_cfg80211_destroy(struct ath6kl *ar);
/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */
void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable);
#endif /* ATH6KL_CFG80211_H */ #endif /* ATH6KL_CFG80211_H */
+1 -1
View File
@@ -940,7 +940,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
bool wait_fot_compltn, bool cold_reset); bool wait_fot_compltn, bool cold_reset);
void ath6kl_init_control_info(struct ath6kl_vif *vif); void ath6kl_init_control_info(struct ath6kl_vif *vif);
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
int ath6kl_init_hw_start(struct ath6kl *ar); int ath6kl_init_hw_start(struct ath6kl *ar);
int ath6kl_init_hw_stop(struct ath6kl *ar); int ath6kl_init_hw_stop(struct ath6kl *ar);
int ath6kl_init_fetch_firmwares(struct ath6kl *ar); int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
+20 -6
View File
@@ -509,9 +509,7 @@ static void destroy_htc_txctrl_packet(struct htc_packet *packet)
{ {
struct sk_buff *skb; struct sk_buff *skb;
skb = packet->skb; skb = packet->skb;
if (skb != NULL) dev_kfree_skb(skb);
dev_kfree_skb(skb);
kfree(packet); kfree(packet);
} }
@@ -969,6 +967,22 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
u16 payload_len; u16 payload_len;
int status = 0; int status = 0;
/*
* ar->htc_target can be NULL due to a race condition that can occur
* during driver initialization(we do 'ath6kl_hif_power_on' before
* initializing 'ar->htc_target' via 'ath6kl_htc_create').
* 'ath6kl_hif_power_on' assigns 'ath6kl_recv_complete' as
* usb_complete_t/callback function for 'usb_fill_bulk_urb'.
* Thus the possibility of ar->htc_target being NULL
* via ath6kl_recv_complete -> ath6kl_usb_io_comp_work.
*/
if (WARN_ON_ONCE(!target)) {
ath6kl_err("Target not yet initialized\n");
status = -EINVAL;
goto free_skb;
}
netdata = skb->data; netdata = skb->data;
netlen = skb->len; netlen = skb->len;
@@ -1054,6 +1068,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
dev_kfree_skb(skb); dev_kfree_skb(skb);
skb = NULL; skb = NULL;
goto free_skb; goto free_skb;
} }
@@ -1089,8 +1104,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
skb = NULL; skb = NULL;
free_skb: free_skb:
if (skb != NULL) dev_kfree_skb(skb);
dev_kfree_skb(skb);
return status; return status;
@@ -1184,7 +1198,7 @@ static void reset_endpoint_states(struct htc_target *target)
INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue); INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue);
INIT_LIST_HEAD(&ep->rx_bufq); INIT_LIST_HEAD(&ep->rx_bufq);
ep->target = target; ep->target = target;
ep->pipe.tx_credit_flow_enabled = (bool) 1; /* FIXME */ ep->pipe.tx_credit_flow_enabled = true;
} }
} }
+1 -35
View File
@@ -1715,38 +1715,6 @@ void ath6kl_init_hw_restart(struct ath6kl *ar)
} }
} }
/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
{
static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bool discon_issued;
netif_stop_queue(vif->ndev);
clear_bit(WLAN_ENABLED, &vif->flags);
if (wmi_ready) {
discon_issued = test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags);
ath6kl_disconnect(vif);
del_timer(&vif->disconnect_timer);
if (discon_issued)
ath6kl_disconnect_event(vif, DISCONNECT_CMD,
(vif->nw_type & AP_NETWORK) ?
bcast_mac : vif->bssid,
0, NULL, 0);
}
if (vif->scan_req) {
cfg80211_scan_done(vif->scan_req, true);
vif->scan_req = NULL;
}
/* need to clean up enhanced bmiss detection fw state */
ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
}
void ath6kl_stop_txrx(struct ath6kl *ar) void ath6kl_stop_txrx(struct ath6kl *ar)
{ {
struct ath6kl_vif *vif, *tmp_vif; struct ath6kl_vif *vif, *tmp_vif;
@@ -1766,7 +1734,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
list_del(&vif->list); list_del(&vif->list);
spin_unlock_bh(&ar->list_lock); spin_unlock_bh(&ar->list_lock);
ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
rtnl_lock(); rtnl_lock();
ath6kl_cfg80211_vif_cleanup(vif); ath6kl_cfg80211_vif_cleanup(vif);
rtnl_unlock(); rtnl_unlock();
@@ -1801,8 +1769,6 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
"attempting to reset target on instance destroy\n"); "attempting to reset target on instance destroy\n");
ath6kl_reset_device(ar, ar->target_type, true, true); ath6kl_reset_device(ar, ar->target_type, true, true);
clear_bit(WLAN_ENABLED, &ar->flag);
up(&ar->sem); up(&ar->sem);
} }
EXPORT_SYMBOL(ath6kl_stop_txrx); EXPORT_SYMBOL(ath6kl_stop_txrx);
+2 -4
View File
@@ -159,10 +159,8 @@ static void ath6kl_usb_free_urb_to_pipe(struct ath6kl_usb_pipe *pipe,
static void ath6kl_usb_cleanup_recv_urb(struct ath6kl_urb_context *urb_context) static void ath6kl_usb_cleanup_recv_urb(struct ath6kl_urb_context *urb_context)
{ {
if (urb_context->skb != NULL) { dev_kfree_skb(urb_context->skb);
dev_kfree_skb(urb_context->skb); urb_context->skb = NULL;
urb_context->skb = NULL;
}
ath6kl_usb_free_urb_to_pipe(urb_context->pipe, urb_context); ath6kl_usb_free_urb_to_pipe(urb_context->pipe, urb_context);
} }
+21 -9
View File
@@ -751,6 +751,23 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
NO_SYNC_WMIFLAG); NO_SYNC_WMIFLAG);
} }
int ath6kl_wmi_ap_set_beacon_intvl_cmd(struct wmi *wmi, u8 if_idx,
u32 beacon_intvl)
{
struct sk_buff *skb;
struct set_beacon_int_cmd *cmd;
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
if (!skb)
return -ENOMEM;
cmd = (struct set_beacon_int_cmd *) skb->data;
cmd->beacon_intvl = cpu_to_le32(beacon_intvl);
return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
WMI_SET_BEACON_INT_CMDID, NO_SYNC_WMIFLAG);
}
int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period) int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period)
{ {
struct sk_buff *skb; struct sk_buff *skb;
@@ -1108,7 +1125,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
kfree(mgmt); kfree(mgmt);
if (bss == NULL) if (bss == NULL)
return -ENOMEM; return -ENOMEM;
cfg80211_put_bss(bss); cfg80211_put_bss(ar->wiphy, bss);
/* /*
* Firmware doesn't return any event when scheduled scan has * Firmware doesn't return any event when scheduled scan has
@@ -2480,16 +2497,11 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
free_cmd_skb: free_cmd_skb:
/* free up any resources left over (possibly due to an error) */ /* free up any resources left over (possibly due to an error) */
if (skb) dev_kfree_skb(skb);
dev_kfree_skb(skb);
free_data_skb: free_data_skb:
for (index = 0; index < num_pri_streams; index++) { for (index = 0; index < num_pri_streams; index++)
if (data_sync_bufs[index].skb != NULL) { dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].skb);
dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
skb);
}
}
return ret; return ret;
} }
+6
View File
@@ -1660,6 +1660,10 @@ struct roam_ctrl_cmd {
u8 roam_ctrl; u8 roam_ctrl;
} __packed; } __packed;
struct set_beacon_int_cmd {
__le32 beacon_intvl;
} __packed;
struct set_dtim_cmd { struct set_dtim_cmd {
__le32 dtim_period; __le32 dtim_period;
} __packed; } __packed;
@@ -2649,6 +2653,8 @@ int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi); int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi);
int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
int ath6kl_wmi_ap_set_beacon_intvl_cmd(struct wmi *wmi, u8 if_idx,
u32 beacon_interval);
int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
+1
View File
@@ -389,6 +389,7 @@ struct ath_beacon_config {
u16 bmiss_timeout; u16 bmiss_timeout;
u8 dtim_count; u8 dtim_count;
bool enable_beacon; bool enable_beacon;
bool ibss_creator;
}; };
struct ath_beacon { struct ath_beacon {
+87 -26
View File
@@ -407,12 +407,17 @@ void ath9k_beacon_tasklet(unsigned long data)
} }
} }
static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, u32 intval) /*
* Both nexttbtt and intval have to be in usecs.
*/
static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
u32 intval, bool reset_tsf)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
ath9k_hw_disable_interrupts(ah); ath9k_hw_disable_interrupts(ah);
ath9k_hw_reset_tsf(ah); if (reset_tsf)
ath9k_hw_reset_tsf(ah);
ath9k_beaconq_config(sc); ath9k_beaconq_config(sc);
ath9k_hw_beaconinit(ah, nexttbtt, intval); ath9k_hw_beaconinit(ah, nexttbtt, intval);
sc->beacon.bmisscnt = 0; sc->beacon.bmisscnt = 0;
@@ -442,10 +447,12 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
else else
ah->imask &= ~ATH9K_INT_SWBA; ah->imask &= ~ATH9K_INT_SWBA;
ath_dbg(common, BEACON, "AP nexttbtt: %u intval: %u conf_intval: %u\n", ath_dbg(common, BEACON,
"AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
(conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval); nexttbtt, intval, conf->beacon_interval);
ath9k_beacon_init(sc, nexttbtt, intval); ath9k_beacon_init(sc, nexttbtt, intval, true);
} }
/* /*
@@ -586,17 +593,45 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
ath9k_reset_beacon_status(sc); ath9k_reset_beacon_status(sc);
intval = TU_TO_USEC(conf->beacon_interval); intval = TU_TO_USEC(conf->beacon_interval);
nexttbtt = intval;
if (conf->ibss_creator) {
nexttbtt = intval;
} else {
u32 tbtt, offset, tsftu;
u64 tsf;
/*
* Pull nexttbtt forward to reflect the current
* sync'd TSF.
*/
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
offset = tsftu % conf->beacon_interval;
tbtt = tsftu - offset;
if (offset)
tbtt += conf->beacon_interval;
nexttbtt = TU_TO_USEC(tbtt);
}
if (conf->enable_beacon) if (conf->enable_beacon)
ah->imask |= ATH9K_INT_SWBA; ah->imask |= ATH9K_INT_SWBA;
else else
ah->imask &= ~ATH9K_INT_SWBA; ah->imask &= ~ATH9K_INT_SWBA;
ath_dbg(common, BEACON, "IBSS nexttbtt: %u intval: %u conf_intval: %u\n", ath_dbg(common, BEACON,
"IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
(conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval); nexttbtt, intval, conf->beacon_interval);
ath9k_beacon_init(sc, nexttbtt, intval); ath9k_beacon_init(sc, nexttbtt, intval, conf->ibss_creator);
/*
* Set the global 'beacon has been configured' flag for the
* joiner case in IBSS mode.
*/
if (!conf->ibss_creator && conf->enable_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
} }
bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
@@ -639,6 +674,7 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
cur_conf->dtim_period = bss_conf->dtim_period; cur_conf->dtim_period = bss_conf->dtim_period;
cur_conf->listen_interval = 1; cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1; cur_conf->dtim_count = 1;
cur_conf->ibss_creator = bss_conf->ibss_creator;
cur_conf->bmiss_timeout = cur_conf->bmiss_timeout =
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
@@ -666,34 +702,59 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
{ {
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
unsigned long flags;
bool skip_beacon = false;
if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
ath9k_cache_beacon_config(sc, bss_conf); ath9k_cache_beacon_config(sc, bss_conf);
ath9k_set_beacon(sc); ath9k_set_beacon(sc);
set_bit(SC_OP_BEACONS, &sc->sc_flags); set_bit(SC_OP_BEACONS, &sc->sc_flags);
} else { return;
}
/*
* Take care of multiple interfaces when
* enabling/disabling SWBA.
*/
if (changed & BSS_CHANGED_BEACON_ENABLED) {
if (!bss_conf->enable_beacon &&
(sc->nbcnvifs <= 1)) {
cur_conf->enable_beacon = false;
} else if (bss_conf->enable_beacon) {
cur_conf->enable_beacon = true;
ath9k_cache_beacon_config(sc, bss_conf);
}
}
/*
* Configure the HW beacon registers only when we have a valid
* beacon interval.
*/
if (cur_conf->beacon_interval) {
/* /*
* Take care of multiple interfaces when * If we are joining an existing IBSS network, start beaconing
* enabling/disabling SWBA. * only after a TSF-sync has taken place. Ensure that this
* happens by setting the appropriate flags.
*/ */
if (changed & BSS_CHANGED_BEACON_ENABLED) { if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator &&
if (!bss_conf->enable_beacon && bss_conf->enable_beacon) {
(sc->nbcnvifs <= 1)) { spin_lock_irqsave(&sc->sc_pm_lock, flags);
cur_conf->enable_beacon = false; sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
} else if (bss_conf->enable_beacon) { spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
cur_conf->enable_beacon = true; skip_beacon = true;
ath9k_cache_beacon_config(sc, bss_conf); } else {
}
}
if (cur_conf->beacon_interval) {
ath9k_set_beacon(sc); ath9k_set_beacon(sc);
if (cur_conf->enable_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
else
clear_bit(SC_OP_BEACONS, &sc->sc_flags);
} }
/*
* Do not set the SC_OP_BEACONS flag for IBSS joiner mode
* here, it is done in ath9k_beacon_config_adhoc().
*/
if (cur_conf->enable_beacon && !skip_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
else
clear_bit(SC_OP_BEACONS, &sc->sc_flags);
} }
} }
+5 -8
View File
@@ -320,28 +320,25 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct ath_node *an; struct ath_node *an;
u8 density;
an = (struct ath_node *)sta->drv_priv; an = (struct ath_node *)sta->drv_priv;
an->sc = sc; an->sc = sc;
an->sta = sta; an->sta = sta;
an->vif = vif; an->vif = vif;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { ath_tx_node_init(sc, an);
ath_tx_node_init(sc, an);
if (sta->ht_cap.ht_supported) {
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor); sta->ht_cap.ampdu_factor);
density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); an->mpdudensity = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
an->mpdudensity = density;
} }
} }
static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
{ {
struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_node *an = (struct ath_node *)sta->drv_priv;
ath_tx_node_cleanup(sc, an);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ath_tx_node_cleanup(sc, an);
} }
void ath9k_tasklet(unsigned long data) void ath9k_tasklet(unsigned long data)
+1 -1
View File
@@ -1204,7 +1204,7 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta)
caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
else if (sta->ht_cap.mcs.rx_mask[1]) else if (sta->ht_cap.mcs.rx_mask[1])
caps |= WLAN_RC_DS_FLAG; caps |= WLAN_RC_DS_FLAG;
if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
caps |= WLAN_RC_40_FLAG; caps |= WLAN_RC_40_FLAG;
if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
caps |= WLAN_RC_SGI_FLAG; caps |= WLAN_RC_SGI_FLAG;
+1 -1
View File
@@ -533,7 +533,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (sc->ps_flags & PS_BEACON_SYNC) { if (sc->ps_flags & PS_BEACON_SYNC) {
sc->ps_flags &= ~PS_BEACON_SYNC; sc->ps_flags &= ~PS_BEACON_SYNC;
ath_dbg(common, PS, ath_dbg(common, PS,
"Reconfigure Beacon timers based on timestamp from the AP\n"); "Reconfigure beacon timers based on synchronized timestamp\n");
ath9k_set_beacon(sc); ath9k_set_beacon(sc);
} }
+2 -3
View File
@@ -1233,7 +1233,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
* in HT IBSS when a beacon with HT-info is received after the station * in HT IBSS when a beacon with HT-info is received after the station
* has already been added. * has already been added.
*/ */
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { if (sta->ht_cap.ht_supported) {
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor); sta->ht_cap.ampdu_factor);
density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
@@ -1904,8 +1904,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
struct ath_buf *bf; struct ath_buf *bf;
u8 tidno; u8 tidno;
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an && if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) {
ieee80211_is_data_qos(hdr->frame_control)) {
tidno = ieee80211_get_qos_ctl(hdr)[0] & tidno = ieee80211_get_qos_ctl(hdr)[0] &
IEEE80211_QOS_CTL_TID_MASK; IEEE80211_QOS_CTL_TID_MASK;
tid = ATH_AN_2_TID(txctl->an, tidno); tid = ATH_AN_2_TID(txctl->an, tidno);
+1 -1
View File
@@ -1853,7 +1853,7 @@ void *carl9170_alloc(size_t priv_size)
IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
IEEE80211_HW_SIGNAL_DBM; IEEE80211_HW_SIGNAL_DBM;
if (!modparam_noht) { if (!modparam_noht) {
+1 -1
View File
@@ -341,7 +341,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
} }
out: out:
cfg80211_put_bss(bss); cfg80211_put_bss(wiphy, bss);
return rc; return rc;
} }
+1 -1
View File
@@ -338,7 +338,7 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
if (bss) { if (bss) {
wil_dbg_wmi(wil, "Added BSS %pM\n", wil_dbg_wmi(wil, "Added BSS %pM\n",
rx_mgmt_frame->bssid); rx_mgmt_frame->bssid);
cfg80211_put_bss(bss); cfg80211_put_bss(wiphy, bss);
} else { } else {
wil_err(wil, "cfg80211_inform_bss() failed\n"); wil_err(wil, "cfg80211_inform_bss() failed\n");
} }

Some files were not shown because too many files have changed in this diff Show More