Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327449
b: refs/heads/master
c: 017a92a
h: refs/heads/master
i:
  327447: ad9dff2
v: v3
  • Loading branch information
Avinash Patil authored and John W. Linville committed Aug 6, 2012
1 parent afa6b2b commit 72c5d6f
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3d99d9877dabc6468c3df1c990d436bd221b5089
refs/heads/master: 017a92a15a119be3b751456cb04791282721c661
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/mwifiex/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
list_del(&priv->tx_ba_stream_tbl_ptr);
list_del(&priv->rx_reorder_tbl_ptr);
list_del(&priv->sta_list);
}
}
}
Expand Down Expand Up @@ -486,6 +487,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
spin_lock_init(&priv->rx_pkt_lock);
spin_lock_init(&priv->wmm.ra_list_spinlock);
spin_lock_init(&priv->curr_bcn_buf_lock);
spin_lock_init(&priv->sta_list_spinlock);
}
}

Expand Down Expand Up @@ -518,6 +520,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
}
INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
INIT_LIST_HEAD(&priv->sta_list);

spin_lock_init(&priv->tx_ba_stream_tbl_lock);
spin_lock_init(&priv->rx_reorder_tbl_lock);
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/net/wireless/mwifiex/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ struct mwifiex_private {
u8 wmm_enabled;
u8 wmm_qosinfo;
struct mwifiex_wmm_desc wmm;
struct list_head sta_list;
/* spin lock for associated station list */
spinlock_t sta_list_spinlock;
struct list_head tx_ba_stream_tbl_ptr;
/* spin lock for tx_ba_stream_tbl_ptr queue */
spinlock_t tx_ba_stream_tbl_lock;
Expand Down Expand Up @@ -552,6 +555,19 @@ struct mwifiex_bss_priv {
u64 fw_tsf;
};

/* This is AP specific structure which stores information
* about associated STA
*/
struct mwifiex_sta_node {
struct list_head list;
u8 mac_addr[ETH_ALEN];
u8 is_wmm_enabled;
u8 is_11n_enabled;
u8 ampdu_sta[MAX_NUM_TID];
u16 rx_seq[MAX_NUM_TID];
u16 max_amsdu;
};

struct mwifiex_if_ops {
int (*init_if) (struct mwifiex_adapter *);
void (*cleanup_if) (struct mwifiex_adapter *);
Expand Down Expand Up @@ -786,6 +802,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
struct sk_buff *skb);
int mwifiex_process_sta_event(struct mwifiex_private *);
int mwifiex_process_uap_event(struct mwifiex_private *);
struct mwifiex_sta_node *
mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
void mwifiex_delete_all_station_list(struct mwifiex_private *priv);
void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
Expand Down
158 changes: 155 additions & 3 deletions trunk/drivers/net/wireless/mwifiex/uap_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,130 @@
#include "decl.h"
#include "main.h"

/*
* This function will return the pointer to station entry in station list
* table which matches specified mac address.
* This function should be called after acquiring RA list spinlock.
* NULL is returned if station entry is not found in associated STA list.
*/
struct mwifiex_sta_node *
mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac)
{
struct mwifiex_sta_node *node;

if (!mac)
return NULL;

list_for_each_entry(node, &priv->sta_list, list) {
if (!memcmp(node->mac_addr, mac, ETH_ALEN))
return node;
}

return NULL;
}

/*
* This function will add a sta_node entry to associated station list
* table with the given mac address.
* If entry exist already, existing entry is returned.
* If received mac address is NULL, NULL is returned.
*/
static struct mwifiex_sta_node *
mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac)
{
struct mwifiex_sta_node *node;
unsigned long flags;

if (!mac)
return NULL;

spin_lock_irqsave(&priv->sta_list_spinlock, flags);
node = mwifiex_get_sta_entry(priv, mac);
if (node)
goto done;

node = kzalloc(sizeof(struct mwifiex_sta_node), GFP_KERNEL);
if (!node)
goto done;

memcpy(node->mac_addr, mac, ETH_ALEN);
list_add_tail(&node->list, &priv->sta_list);

done:
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
return node;
}

/*
* This function will search for HT IE in association request IEs
* and set station HT parameters accordingly.
*/
static void
mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
int ies_len, struct mwifiex_sta_node *node)
{
const struct ieee80211_ht_cap *ht_cap;

if (!ies)
return;

ht_cap = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
if (ht_cap) {
node->is_11n_enabled = 1;
node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
IEEE80211_HT_CAP_MAX_AMSDU ?
MWIFIEX_TX_DATA_BUF_SIZE_8K :
MWIFIEX_TX_DATA_BUF_SIZE_4K;
} else {
node->is_11n_enabled = 0;
}

return;
}

/*
* This function will delete a station entry from station list
*/
static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
{
struct mwifiex_sta_node *node, *tmp;
unsigned long flags;

spin_lock_irqsave(&priv->sta_list_spinlock, flags);

node = mwifiex_get_sta_entry(priv, mac);
if (node) {
list_for_each_entry_safe(node, tmp, &priv->sta_list,
list) {
list_del(&node->list);
kfree(node);
}
}

spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
return;
}

/*
* This function will delete all stations from associated station list.
*/
static void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
{
struct mwifiex_sta_node *node, *tmp;
unsigned long flags;

spin_lock_irqsave(&priv->sta_list_spinlock, flags);

list_for_each_entry_safe(node, tmp, &priv->sta_list, list) {
list_del(&node->list);
kfree(node);
}

INIT_LIST_HEAD(&priv->sta_list);
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
return;
}

/*
* This function handles AP interface specific events generated by firmware.
*
Expand All @@ -38,10 +162,12 @@
int mwifiex_process_uap_event(struct mwifiex_private *priv)
{
struct mwifiex_adapter *adapter = priv->adapter;
int len;
int len, i;
u32 eventcause = adapter->event_cause;
struct station_info sinfo;
struct mwifiex_assoc_event *event;
struct mwifiex_sta_node *node;
u8 *deauth_mac;

switch (eventcause) {
case EVENT_UAP_STA_ASSOC:
Expand Down Expand Up @@ -70,13 +196,39 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
}
cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo,
GFP_KERNEL);

node = mwifiex_add_sta_entry(priv, event->sta_addr);
if (!node) {
dev_warn(adapter->dev,
"could not create station entry!\n");
return -1;
}

if (!priv->ap_11n_enabled)
break;

mwifiex_set_sta_ht_cap(priv, sinfo.assoc_req_ies,
sinfo.assoc_req_ies_len, node);

for (i = 0; i < MAX_NUM_TID; i++) {
if (node->is_11n_enabled)
node->ampdu_sta[i] =
priv->aggr_prio_tbl[i].ampdu_user;
else
node->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
}
memset(node->rx_seq, 0xff, sizeof(node->rx_seq));
break;
case EVENT_UAP_STA_DEAUTH:
cfg80211_del_sta(priv->netdev, adapter->event_body +
MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL);
deauth_mac = adapter->event_body +
MWIFIEX_UAP_EVENT_EXTRA_HEADER;
cfg80211_del_sta(priv->netdev, deauth_mac, GFP_KERNEL);

mwifiex_del_sta_entry(priv, deauth_mac);
break;
case EVENT_UAP_BSS_IDLE:
priv->media_connected = false;
mwifiex_del_all_sta_list(priv);
break;
case EVENT_UAP_BSS_ACTIVE:
priv->media_connected = true;
Expand Down

0 comments on commit 72c5d6f

Please sign in to comment.