|
@@ -162,7 +162,7 @@ static int ath_key_config(struct ath_softc *sc,
|
|
if (!sc->sc_vaps[0])
|
|
if (!sc->sc_vaps[0])
|
|
return -EIO;
|
|
return -EIO;
|
|
|
|
|
|
- vif = sc->sc_vaps[0]->av_if_data;
|
|
|
|
|
|
+ vif = sc->sc_vaps[0];
|
|
opmode = vif->type;
|
|
opmode = vif->type;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -313,11 +313,12 @@ static void ath9k_ht_conf(struct ath_softc *sc,
|
|
}
|
|
}
|
|
|
|
|
|
static void ath9k_bss_assoc_info(struct ath_softc *sc,
|
|
static void ath9k_bss_assoc_info(struct ath_softc *sc,
|
|
|
|
+ struct ieee80211_vif *vif,
|
|
struct ieee80211_bss_conf *bss_conf)
|
|
struct ieee80211_bss_conf *bss_conf)
|
|
{
|
|
{
|
|
struct ieee80211_hw *hw = sc->hw;
|
|
struct ieee80211_hw *hw = sc->hw;
|
|
struct ieee80211_channel *curchan = hw->conf.channel;
|
|
struct ieee80211_channel *curchan = hw->conf.channel;
|
|
- struct ath_vap *avp;
|
|
|
|
|
|
+ struct ath_vap *avp = (void *)vif->drv_priv;
|
|
int pos;
|
|
int pos;
|
|
|
|
|
|
if (bss_conf->assoc) {
|
|
if (bss_conf->assoc) {
|
|
@@ -325,13 +326,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
|
|
__func__,
|
|
__func__,
|
|
bss_conf->aid);
|
|
bss_conf->aid);
|
|
|
|
|
|
- avp = sc->sc_vaps[0];
|
|
|
|
- if (avp == NULL) {
|
|
|
|
- DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
|
|
|
|
- __func__);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* New association, store aid */
|
|
/* New association, store aid */
|
|
if (avp->av_opmode == ATH9K_M_STA) {
|
|
if (avp->av_opmode == ATH9K_M_STA) {
|
|
sc->sc_curaid = bss_conf->aid;
|
|
sc->sc_curaid = bss_conf->aid;
|
|
@@ -906,6 +900,7 @@ static int ath_attach(u16 devid,
|
|
|
|
|
|
hw->queues = 4;
|
|
hw->queues = 4;
|
|
hw->sta_data_size = sizeof(struct ath_node);
|
|
hw->sta_data_size = sizeof(struct ath_node);
|
|
|
|
+ hw->vif_data_size = sizeof(struct ath_vap);
|
|
|
|
|
|
/* Register rate control */
|
|
/* Register rate control */
|
|
hw->rate_control_algorithm = "ath9k_rate_control";
|
|
hw->rate_control_algorithm = "ath9k_rate_control";
|
|
@@ -1091,7 +1086,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
|
|
struct ieee80211_if_init_conf *conf)
|
|
struct ieee80211_if_init_conf *conf)
|
|
{
|
|
{
|
|
struct ath_softc *sc = hw->priv;
|
|
struct ath_softc *sc = hw->priv;
|
|
- int error, ic_opmode = 0;
|
|
|
|
|
|
+ struct ath_vap *avp = (void *)conf->vif->drv_priv;
|
|
|
|
+ int ic_opmode = 0;
|
|
|
|
|
|
/* Support only vap for now */
|
|
/* Support only vap for now */
|
|
|
|
|
|
@@ -1119,13 +1115,22 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
|
|
__func__,
|
|
__func__,
|
|
ic_opmode);
|
|
ic_opmode);
|
|
|
|
|
|
- error = ath_vap_attach(sc, 0, conf->vif, ic_opmode);
|
|
|
|
- if (error) {
|
|
|
|
- DPRINTF(sc, ATH_DBG_FATAL,
|
|
|
|
- "%s: Unable to attach vap, error: %d\n",
|
|
|
|
- __func__, error);
|
|
|
|
- return error;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Set the VAP opmode */
|
|
|
|
+ avp->av_opmode = ic_opmode;
|
|
|
|
+ avp->av_bslot = -1;
|
|
|
|
+
|
|
|
|
+ if (ic_opmode == ATH9K_M_HOSTAP)
|
|
|
|
+ ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
|
|
|
|
+
|
|
|
|
+ sc->sc_vaps[0] = conf->vif;
|
|
|
|
+ sc->sc_nvaps++;
|
|
|
|
+
|
|
|
|
+ /* Set the device opmode */
|
|
|
|
+ sc->sc_ah->ah_opmode = ic_opmode;
|
|
|
|
+
|
|
|
|
+ /* default VAP configuration */
|
|
|
|
+ avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
|
|
|
|
+ avp->av_config.av_fixed_retryset = 0x03030303;
|
|
|
|
|
|
if (conf->type == NL80211_IFTYPE_AP) {
|
|
if (conf->type == NL80211_IFTYPE_AP) {
|
|
/* TODO: is this a suitable place to start ANI for AP mode? */
|
|
/* TODO: is this a suitable place to start ANI for AP mode? */
|
|
@@ -1141,27 +1146,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
|
struct ieee80211_if_init_conf *conf)
|
|
struct ieee80211_if_init_conf *conf)
|
|
{
|
|
{
|
|
struct ath_softc *sc = hw->priv;
|
|
struct ath_softc *sc = hw->priv;
|
|
- struct ath_vap *avp;
|
|
|
|
- int error;
|
|
|
|
|
|
+ struct ath_vap *avp = (void *)conf->vif->drv_priv;
|
|
|
|
|
|
DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
|
|
DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
|
|
|
|
|
|
- avp = sc->sc_vaps[0];
|
|
|
|
- if (avp == NULL) {
|
|
|
|
- DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
|
|
|
|
- __func__);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
#ifdef CONFIG_SLOW_ANT_DIV
|
|
#ifdef CONFIG_SLOW_ANT_DIV
|
|
ath_slow_ant_div_stop(&sc->sc_antdiv);
|
|
ath_slow_ant_div_stop(&sc->sc_antdiv);
|
|
#endif
|
|
#endif
|
|
/* Stop ANI */
|
|
/* Stop ANI */
|
|
del_timer_sync(&sc->sc_ani.timer);
|
|
del_timer_sync(&sc->sc_ani.timer);
|
|
|
|
|
|
- /* Update ratectrl */
|
|
|
|
- ath_rate_newstate(sc, avp);
|
|
|
|
-
|
|
|
|
/* Reclaim beacon resources */
|
|
/* Reclaim beacon resources */
|
|
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
|
|
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
|
|
sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
|
|
sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
|
|
@@ -1169,16 +1163,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
|
ath_beacon_return(sc, avp);
|
|
ath_beacon_return(sc, avp);
|
|
}
|
|
}
|
|
|
|
|
|
- /* Set interrupt mask */
|
|
|
|
- sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
|
|
|
|
- ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
|
|
|
|
sc->sc_flags &= ~SC_OP_BEACONS;
|
|
sc->sc_flags &= ~SC_OP_BEACONS;
|
|
|
|
|
|
- error = ath_vap_detach(sc, 0);
|
|
|
|
- if (error)
|
|
|
|
- DPRINTF(sc, ATH_DBG_FATAL,
|
|
|
|
- "%s: Unable to detach vap, error: %d\n",
|
|
|
|
- __func__, error);
|
|
|
|
|
|
+ sc->sc_vaps[0] = NULL;
|
|
|
|
+ sc->sc_nvaps--;
|
|
}
|
|
}
|
|
|
|
|
|
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|
@@ -1226,17 +1214,10 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
|
|
{
|
|
{
|
|
struct ath_softc *sc = hw->priv;
|
|
struct ath_softc *sc = hw->priv;
|
|
struct ath_hal *ah = sc->sc_ah;
|
|
struct ath_hal *ah = sc->sc_ah;
|
|
- struct ath_vap *avp;
|
|
|
|
|
|
+ struct ath_vap *avp = (void *)vif->drv_priv;
|
|
u32 rfilt = 0;
|
|
u32 rfilt = 0;
|
|
int error, i;
|
|
int error, i;
|
|
|
|
|
|
- avp = sc->sc_vaps[0];
|
|
|
|
- if (avp == NULL) {
|
|
|
|
- DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
|
|
|
|
- __func__);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* TODO: Need to decide which hw opmode to use for multi-interface
|
|
/* TODO: Need to decide which hw opmode to use for multi-interface
|
|
* cases */
|
|
* cases */
|
|
if (vif->type == NL80211_IFTYPE_AP &&
|
|
if (vif->type == NL80211_IFTYPE_AP &&
|
|
@@ -1317,7 +1298,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
|
|
}
|
|
}
|
|
|
|
|
|
/* Check for WLAN_CAPABILITY_PRIVACY ? */
|
|
/* Check for WLAN_CAPABILITY_PRIVACY ? */
|
|
- if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
|
|
|
|
|
|
+ if ((avp->av_opmode != ATH9K_M_STA)) {
|
|
for (i = 0; i < IEEE80211_WEP_NKID; i++)
|
|
for (i = 0; i < IEEE80211_WEP_NKID; i++)
|
|
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
|
|
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
|
|
ath9k_hw_keysetmac(sc->sc_ah,
|
|
ath9k_hw_keysetmac(sc->sc_ah,
|
|
@@ -1366,9 +1347,6 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
|
|
__func__, sc->rx_filter);
|
|
__func__, sc->rx_filter);
|
|
}
|
|
}
|
|
|
|
|
|
-/* Only a single interface is currently supported,
|
|
|
|
- so pass 0 as the interface id to ath_node_attach */
|
|
|
|
-
|
|
|
|
static void ath9k_sta_notify(struct ieee80211_hw *hw,
|
|
static void ath9k_sta_notify(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
struct ieee80211_vif *vif,
|
|
enum sta_notify_cmd cmd,
|
|
enum sta_notify_cmd cmd,
|
|
@@ -1378,7 +1356,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
|
|
|
|
|
|
switch (cmd) {
|
|
switch (cmd) {
|
|
case STA_NOTIFY_ADD:
|
|
case STA_NOTIFY_ADD:
|
|
- ath_node_attach(sc, sta, 0);
|
|
|
|
|
|
+ ath_node_attach(sc, sta);
|
|
break;
|
|
break;
|
|
case STA_NOTIFY_REMOVE:
|
|
case STA_NOTIFY_REMOVE:
|
|
ath_node_detach(sc, sta);
|
|
ath_node_detach(sc, sta);
|
|
@@ -1496,7 +1474,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
|
DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
|
|
DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
|
|
__func__,
|
|
__func__,
|
|
bss_conf->assoc);
|
|
bss_conf->assoc);
|
|
- ath9k_bss_assoc_info(sc, bss_conf);
|
|
|
|
|
|
+ ath9k_bss_assoc_info(sc, vif, bss_conf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|