#include "rt2x00.h"
#include "rt2x00lib.h"
-#include "rt2x00dump.h"
/*
* Link tuning handlers
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct skb_frame_desc *skbdesc;
struct ieee80211_tx_status tx_status;
- int success = !!(txdesc->status == TX_SUCCESS ||
- txdesc->status == TX_SUCCESS_RETRY);
- int fail = !!(txdesc->status == TX_FAIL_RETRY ||
- txdesc->status == TX_FAIL_INVALID ||
- txdesc->status == TX_FAIL_OTHER);
/*
* Update TX statistics.
*/
- rt2x00dev->link.qual.tx_success += success;
- rt2x00dev->link.qual.tx_failed += txdesc->retry + fail;
+ rt2x00dev->link.qual.tx_success +=
+ test_bit(TXDONE_SUCCESS, &txdesc->flags);
+ rt2x00dev->link.qual.tx_failed +=
+ txdesc->retry + !!test_bit(TXDONE_FAILURE, &txdesc->flags);
/*
* Initialize TX status
*/
tx_status.flags = 0;
tx_status.ack_signal = 0;
- tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY);
+ tx_status.excessive_retries =
+ test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags);
tx_status.retry_count = txdesc->retry;
memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control));
if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
- if (success)
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
tx_status.flags |= IEEE80211_TX_STATUS_ACK;
- else
+ else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11ACKFailureCount++;
}
- tx_status.queue_length = entry->queue->limit;
- tx_status.queue_number = tx_status.control.queue;
-
if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- if (success)
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
- else
+ else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
}
* If send to mac80211, mac80211 will clean up the skb structure,
* otherwise we have to do it ourself.
*/
- skbdesc = get_skb_frame_desc(entry->skb);
- skbdesc->frame_type = DUMP_FRAME_TXDONE;
-
- rt2x00debug_dump_frame(rt2x00dev, entry->skb);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
+ skbdesc = get_skb_frame_desc(entry->skb);
if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
ieee80211_tx_status_irqsafe(rt2x00dev->hw,
entry->skb, &tx_status);
else
- dev_kfree_skb(entry->skb);
+ dev_kfree_skb_irq(entry->skb);
entry->skb = NULL;
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
rt2x00dev->link.qual.rx_success++;
rx_status->rate_idx = idx;
- rx_status->signal =
+ rx_status->qual =
rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
- rx_status->ssi = rxdesc->rssi;
+ rx_status->signal = rxdesc->rssi;
rx_status->flag = rxdesc->flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
* Send frame to mac80211 & debugfs.
* mac80211 will clean up the skb structure.
*/
- get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE;
- rt2x00debug_dump_frame(rt2x00dev, entry->skb);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
entry->skb = NULL;
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
-/*
- * TX descriptor initializer
- */
-void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct txentry_desc txdesc;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data;
- const struct rt2x00_rate *rate;
- int tx_rate;
- int length;
- int duration;
- int residual;
- u16 frame_control;
- u16 seq_ctrl;
-
- memset(&txdesc, 0, sizeof(txdesc));
-
- txdesc.queue = skbdesc->entry->queue->qid;
- txdesc.cw_min = skbdesc->entry->queue->cw_min;
- txdesc.cw_max = skbdesc->entry->queue->cw_max;
- txdesc.aifs = skbdesc->entry->queue->aifs;
-
- /*
- * Read required fields from ieee80211 header.
- */
- frame_control = le16_to_cpu(hdr->frame_control);
- seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
-
- tx_rate = control->tx_rate->hw_value;
-
- /*
- * Check whether this frame is to be acked
- */
- if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
- __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
-
- /*
- * Check if this is a RTS/CTS frame
- */
- if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
- __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
- if (is_rts_frame(frame_control)) {
- __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags);
- __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
- } else
- __clear_bit(ENTRY_TXD_ACK, &txdesc.flags);
- if (control->rts_cts_rate)
- tx_rate = control->rts_cts_rate->hw_value;
- }
-
- rate = rt2x00_get_rate(tx_rate);
-
- /*
- * Check if more fragments are pending
- */
- if (ieee80211_get_morefrag(hdr)) {
- __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
- __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags);
- }
-
- /*
- * Beacons and probe responses require the tsf timestamp
- * to be inserted into the frame.
- */
- if (control->queue == RT2X00_BCN_QUEUE_BEACON ||
- is_probe_resp(frame_control))
- __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags);
-
- /*
- * Determine with what IFS priority this frame should be send.
- * Set ifs to IFS_SIFS when the this is not the first fragment,
- * or this fragment came after RTS/CTS.
- */
- if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 ||
- test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags))
- txdesc.ifs = IFS_SIFS;
- else
- txdesc.ifs = IFS_BACKOFF;
-
- /*
- * PLCP setup
- * Length calculation depends on OFDM/CCK rate.
- */
- txdesc.signal = rate->plcp;
- txdesc.service = 0x04;
-
- length = skbdesc->data_len + FCS_LEN;
- if (rate->flags & DEV_RATE_OFDM) {
- __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags);
-
- txdesc.length_high = (length >> 6) & 0x3f;
- txdesc.length_low = length & 0x3f;
- } else {
- /*
- * Convert length to microseconds.
- */
- residual = get_duration_res(length, rate->bitrate);
- duration = get_duration(length, rate->bitrate);
-
- if (residual != 0) {
- duration++;
-
- /*
- * Check if we need to set the Length Extension
- */
- if (rate->bitrate == 110 && residual <= 30)
- txdesc.service |= 0x80;
- }
-
- txdesc.length_high = (duration >> 8) & 0xff;
- txdesc.length_low = duration & 0xff;
-
- /*
- * When preamble is enabled we should set the
- * preamble bit for the signal.
- */
- if (rt2x00_get_rate_preamble(tx_rate))
- txdesc.signal |= 0x08;
- }
-
- rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control);
-
- /*
- * Update queue entry.
- */
- skbdesc->entry->skb = skb;
-
- /*
- * The frame has been completely initialized and ready
- * for sending to the device. The caller will push the
- * frame to the device, but we are going to push the
- * frame to debugfs here.
- */
- skbdesc->frame_type = DUMP_FRAME_TX;
- rt2x00debug_dump_frame(rt2x00dev, skb);
-}
-EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
-
/*
* Driver initialization handlers.
*/
if (status)
return status;
+ /*
+ * Initialize HW fields.
+ */
+ rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;
+
/*
* Register HW.
*/
* Initialize the device.
*/
status = rt2x00dev->ops->lib->initialize(rt2x00dev);
- if (status)
- goto exit;
+ if (status) {
+ rt2x00queue_uninitialize(rt2x00dev);
+ return status;
+ }
__set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags);
rt2x00rfkill_register(rt2x00dev);
return 0;
-
-exit:
- rt2x00lib_uninitialize(rt2x00dev);
-
- return status;
}
int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)