Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 247096
b: refs/heads/master
c: ae47c45
h: refs/heads/master
v: v3
  • Loading branch information
Shahar Levi authored and Luciano Coelho committed Apr 19, 2011
1 parent effdc23 commit bd72613
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 22 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: ae77eccf04f8c36769bdba334e1bbcc7bb9d3644
refs/heads/master: ae47c45fd02fdf88d57adc370e78e7a01e2bfcbc
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)

if (wl->bss_type == BSS_TYPE_AP_BSS)
wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
else
wl->event_mask |= DUMMY_PACKET_EVENT_ID;

ret = wl1271_event_unmask(wl);
if (ret < 0) {
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_event_rssi_trigger(wl, mbox);
}

if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) {
wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
if (wl->vif)
wl1271_tx_dummy_packet(wl);
}

if (wl->vif && beacon_loss)
ieee80211_connection_loss(wl->vif);

Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/net/wireless/wl12xx/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ enum {
BSS_LOSE_EVENT_ID = BIT(18),
REGAINED_BSS_EVENT_ID = BIT(19),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20),
STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), /* AP */
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID = BIT(21),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID = BIT(21),
SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23),
SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/wl12xx/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void);
int wl1271_free_hw(struct wl1271 *wl);
irqreturn_t wl1271_irq(int irq, void *data);
bool wl1271_set_block_size(struct wl1271 *wl);
int wl1271_tx_dummy_packet(struct wl1271 *wl);

#endif
42 changes: 42 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,48 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
spin_unlock_irqrestore(&wl->wl_lock, flags);
}

#define TX_DUMMY_PACKET_SIZE 1400
int wl1271_tx_dummy_packet(struct wl1271 *wl)
{
struct sk_buff *skb = NULL;
struct ieee80211_hdr_3addr *hdr;
int ret = 0;

skb = dev_alloc_skb(
sizeof(struct wl1271_tx_hw_descr) + sizeof(*hdr) +
TX_DUMMY_PACKET_SIZE);
if (!skb) {
wl1271_warning("failed to allocate buffer for dummy packet");
ret = -ENOMEM;
goto out;
}

skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));

hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
memset(hdr, 0, sizeof(*hdr));
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
IEEE80211_FCTL_TODS |
IEEE80211_STYPE_NULLFUNC);

memcpy(hdr->addr1, wl->bssid, ETH_ALEN);
memcpy(hdr->addr2, wl->mac_addr, ETH_ALEN);
memcpy(hdr->addr3, wl->bssid, ETH_ALEN);

skb_put(skb, TX_DUMMY_PACKET_SIZE);

memset(skb->data, 0, TX_DUMMY_PACKET_SIZE);

skb->pkt_type = TX_PKT_TYPE_DUMMY_REQ;
/* CONF_TX_AC_VO */
skb->queue_mapping = 0;

wl1271_op_tx(wl->hw, skb);

out:
return ret;
}

static struct notifier_block wl1271_dev_notifier = {
.notifier_call = wl1271_dev_notify,
};
Expand Down
75 changes: 55 additions & 20 deletions trunk/drivers/net/wireless/wl12xx/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,29 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
else
desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);

/* configure the tx attributes */
tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;

/* queue (we use same identifiers for tid's and ac's */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
desc->tid = ac;

if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
/*
* FW expects the dummy packet to have an invalid session id -
* any session id that is different than the one set in the join
*/
tx_attr = ((~wl->session_counter) <<
TX_HW_ATTR_OFST_SESSION_COUNTER) &
TX_HW_ATTR_SESSION_COUNTER;

tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;

/* Dummy packets require the TID to be management */
desc->tid = WL1271_TID_MGMT;
} else {
/* configure the tx attributes */
tx_attr =
wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
}

if (wl->bss_type != BSS_TYPE_AP_BSS) {
desc->aid = hlid;

Expand Down Expand Up @@ -587,6 +603,12 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
skb = wl->tx_frames[id];
info = IEEE80211_SKB_CB(skb);

if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
dev_kfree_skb(skb);
wl1271_free_tx_id(wl, id);
return;
}

/* update the TX status info */
if (result->status == TX_SUCCESS) {
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
Expand Down Expand Up @@ -716,10 +738,15 @@ void wl1271_tx_reset(struct wl1271 *wl)
while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
wl1271_debug(DEBUG_TX, "freeing skb 0x%p",
skb);
info = IEEE80211_SKB_CB(skb);
info->status.rates[0].idx = -1;
info->status.rates[0].count = 0;
ieee80211_tx_status(wl->hw, skb);

if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
dev_kfree_skb(skb);
} else {
info = IEEE80211_SKB_CB(skb);
info->status.rates[0].idx = -1;
info->status.rates[0].count = 0;
ieee80211_tx_status(wl->hw, skb);
}
}
}
}
Expand All @@ -740,21 +767,29 @@ void wl1271_tx_reset(struct wl1271 *wl)
wl1271_free_tx_id(wl, i);
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);

/* Remove private headers before passing the skb to mac80211 */
info = IEEE80211_SKB_CB(skb);
skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
if (info->control.hw_key &&
info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data,
hdrlen);
skb_pull(skb, WL1271_TKIP_IV_SPACE);
}
if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
dev_kfree_skb(skb);
} else {
/*
* Remove private headers before passing the skb to
* mac80211
*/
info = IEEE80211_SKB_CB(skb);
skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
if (info->control.hw_key &&
info->control.hw_key->cipher ==
WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_TKIP_IV_SPACE,
skb->data, hdrlen);
skb_pull(skb, WL1271_TKIP_IV_SPACE);
}

info->status.rates[0].idx = -1;
info->status.rates[0].count = 0;
info->status.rates[0].idx = -1;
info->status.rates[0].count = 0;

ieee80211_tx_status(wl->hw, skb);
ieee80211_tx_status(wl->hw, skb);
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
BIT(8) | BIT(9))
#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)

#define TX_PKT_TYPE_DUMMY_REQ 5

#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
#define TX_HW_ATTR_OFST_HEADER_PAD 1
Expand All @@ -55,6 +58,9 @@
#define WL1271_TX_ALIGN_TO 4
#define WL1271_TKIP_IV_SPACE 4

/* Used for management frames and dummy packets */
#define WL1271_TID_MGMT 7

struct wl127x_tx_mem {
/*
* Number of extra memory blocks to allocate for this packet
Expand Down

0 comments on commit bd72613

Please sign in to comment.