From: Christian Lamparter <chunkeey@xxxxxx> This patch should finally fix the mysterious "stuck at 1 mbps" and numerous of "lost" ACKs (very important for the not yet released p54 AP addon). The patch also includes a bunch of useful one liners that did not make it in the tree yet. Signed-off-by: Christian Lamparter <chunkeey@xxxxxx> ---
diff -Nurp a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c --- a/drivers/net/wireless/p54common.c 2007-08-31 21:56:42.000000000 +0200 +++ b/drivers/net/wireless/p54common.c 2007-08-31 21:57:29.000000000 +0200 @@ -283,12 +283,13 @@ static void p54_rx_data(struct ieee80211 struct ieee80211_rx_status rx_status = {0}; u16 freq = le16_to_cpu(hdr->freq); - rx_status.ssi = hdr->rssi; /* TODO: check this */ + rx_status.ssi = hdr->rssi; rx_status.rate = hdr->rate & 0x1f; /* report short preambles & CCK too */ rx_status.channel = freq == 2484 ? 14 : (freq - 2407)/5; rx_status.freq = freq; rx_status.phymode = MODE_IEEE80211G; rx_status.antenna = hdr->antenna; + rx_status.mactime = le64_to_cpu(hdr->timestamp); skb_pull(skb, sizeof(*hdr)); skb_trim(skb, le16_to_cpu(hdr->len)); @@ -324,6 +325,9 @@ static void p54_rx_frame_sent(struct iee range = (struct memrecord *)&entry->cb; if (range->start_addr == addr) { struct ieee80211_tx_status status = {{0}}; + struct p54_control_hdr *entry_hdr; + struct p54_tx_control_allocdata *entry_data; + int pad = 0; if (entry->next != (struct sk_buff *)&priv->tx_queue) freed = ((struct memrecord *)&entry->next->cb)->start_addr - last_addr; @@ -339,14 +343,22 @@ static void p54_rx_frame_sent(struct iee memcpy(&status.control, range->control, sizeof(status.control)); kfree(range->control); - if (!payload->status) - status.flags |= IEEE80211_TX_STATUS_ACK; - else - status.excessive_retries = 1; + priv->tx_stats.data[status.control.queue].len--; + + entry_hdr = (struct p54_control_hdr *) entry->data; + entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; + if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) + pad = entry_data->align[0]; + + if (!status.control.flags & IEEE80211_TXCTL_NO_ACK) { + if (!(payload->status & 0x01)) + status.flags |= IEEE80211_TX_STATUS_ACK; + else + status.excessive_retries = 1; + } status.retry_count = payload->retries - 1; status.ack_signal = le16_to_cpu(payload->ack_rssi); - skb_pull(entry, sizeof(*hdr) + sizeof(struct p54_tx_control_allocdata)); - priv->tx_stats.data[status.control.queue].len--; + skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); ieee80211_tx_status_irqsafe(dev, entry, &status); break; } else @@ -895,7 +907,7 @@ struct ieee80211_hw *p54_init_common(siz IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_WEP_INCLUDE_IV; dev->channel_change_time = 1000; /* TODO: find actual value */ - dev->max_rssi = 100; + dev->max_rssi = 127; /* (hard) queue limits */ priv->tx_stats.data[0].limit = 3; diff -Nurp a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h --- a/drivers/net/wireless/p54common.h 2007-08-18 20:44:04.000000000 +0200 +++ b/drivers/net/wireless/p54common.h 2007-08-28 19:53:13.000000000 +0200 @@ -168,7 +168,7 @@ struct p54_rx_hdr { u8 antenna; u8 rate; u8 rssi; - u8 padding; + u8 quality; u16 unknown2; __le64 timestamp; u8 data[0];