diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-10 01:54:31 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-10 01:54:31 -0700 |
commit | 788c0a53164c05c5ccdb1472474372b72ba74644 (patch) | |
tree | 5f274102e3dc4bcca6cb3a695aa2c8228ad5fc4f /drivers/net/wireless/rt2x00/rt2500pci.c | |
parent | e64bda89b8fe81cce9b4a20885d2c204c2d52532 (diff) | |
parent | 78cf07472f0ede8394bacc4bc02354505080cfe1 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/ps3_gelic_wireless.c
drivers/net/wireless/libertas/main.c
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 120 |
1 files changed, 68 insertions, 52 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c06f1b5e588..673350953b8 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -715,38 +715,33 @@ dynamic_cca_tune: static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { - struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; + struct queue_entry_priv_pci *entry_priv = entry->priv_data; u32 word; - rt2x00_desc_read(priv_rx->desc, 1, &word); - rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); - rt2x00_desc_write(priv_rx->desc, 1, word); + rt2x00_desc_read(entry_priv->desc, 1, &word); + rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); + rt2x00_desc_write(entry_priv->desc, 1, word); - rt2x00_desc_read(priv_rx->desc, 0, &word); + rt2x00_desc_read(entry_priv->desc, 0, &word); rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); - rt2x00_desc_write(priv_rx->desc, 0, word); + rt2x00_desc_write(entry_priv->desc, 0, word); } static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { - struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; + struct queue_entry_priv_pci *entry_priv = entry->priv_data; u32 word; - rt2x00_desc_read(priv_tx->desc, 1, &word); - rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); - rt2x00_desc_write(priv_tx->desc, 1, word); - - rt2x00_desc_read(priv_tx->desc, 0, &word); + rt2x00_desc_read(entry_priv->desc, 0, &word); rt2x00_set_field32(&word, TXD_W0_VALID, 0); rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); - rt2x00_desc_write(priv_tx->desc, 0, word); + rt2x00_desc_write(entry_priv->desc, 0, word); } static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) { - struct queue_entry_priv_pci_rx *priv_rx; - struct queue_entry_priv_pci_tx *priv_tx; + struct queue_entry_priv_pci *entry_priv; u32 reg; /* @@ -759,28 +754,28 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); - priv_tx = rt2x00dev->tx[1].entries[0].priv_data; + entry_priv = rt2x00dev->tx[1].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, - priv_tx->desc_dma); + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); - priv_tx = rt2x00dev->tx[0].entries[0].priv_data; + entry_priv = rt2x00dev->tx[0].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, - priv_tx->desc_dma); + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); - priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; + entry_priv = rt2x00dev->bcn[1].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, - priv_tx->desc_dma); + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); - priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; + entry_priv = rt2x00dev->bcn[0].entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, - priv_tx->desc_dma); + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); @@ -788,9 +783,10 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); - priv_rx = rt2x00dev->rx->entries[0].priv_data; + entry_priv = rt2x00dev->rx->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); - rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); + rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, + entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); return 0; @@ -1155,16 +1151,20 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, */ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, - struct txentry_desc *txdesc, - struct ieee80211_tx_control *control) + struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; __le32 *txd = skbdesc->desc; u32 word; /* * Start writing the descriptor words. */ + rt2x00_desc_read(entry_priv->desc, 1, &word); + rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); + rt2x00_desc_write(entry_priv->desc, 1, word); + rt2x00_desc_read(txd, 2, &word); rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); @@ -1198,9 +1198,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, - !!(control->flags & - IEEE80211_TXCTL_LONG_RETRY_LIMIT)); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); + test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); } @@ -1237,14 +1235,13 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2500pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { - struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; + struct queue_entry_priv_pci *entry_priv = entry->priv_data; u32 word0; u32 word2; - rt2x00_desc_read(priv_rx->desc, 0, &word0); - rt2x00_desc_read(priv_rx->desc, 2, &word2); + rt2x00_desc_read(entry_priv->desc, 0, &word0); + rt2x00_desc_read(entry_priv->desc, 2, &word2); - rxdesc->flags = 0; if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) @@ -1261,7 +1258,6 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry, entry->queue->rt2x00dev->rssi_offset; rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); - rxdesc->dev_flags = 0; if (rt2x00_get_field32(word0, RXD_W0_OFDM)) rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) @@ -1275,15 +1271,15 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); - struct queue_entry_priv_pci_tx *priv_tx; + struct queue_entry_priv_pci *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; u32 word; while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - priv_tx = entry->priv_data; - rt2x00_desc_read(priv_tx->desc, 0, &word); + entry_priv = entry->priv_data; + rt2x00_desc_read(entry_priv->desc, 0, &word); if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || !rt2x00_get_field32(word, TXD_W0_VALID)) @@ -1292,7 +1288,18 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, /* * Obtain the status about this packet. */ - txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); + txdesc.flags = 0; + switch (rt2x00_get_field32(word, TXD_W0_RESULT)) { + case 0: /* Success */ + case 1: /* Success with retry */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + break; + case 2: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); + /* Don't break, this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00pci_txdone(rt2x00dev, entry, &txdesc); @@ -1684,7 +1691,6 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - rt2x00dev->hw->queues = 2; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, @@ -1793,19 +1799,28 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) return tsf; } -static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ieee80211_tx_control *control) +static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct rt2x00_intf *intf = vif_to_intf(control->vif); - struct queue_entry_priv_pci_tx *priv_tx; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); + struct queue_entry_priv_pci *entry_priv; struct skb_frame_desc *skbdesc; + struct txentry_desc txdesc; u32 reg; if (unlikely(!intf->beacon)) return -ENOBUFS; - priv_tx = intf->beacon->priv_data; + entry_priv = intf->beacon->priv_data; + + /* + * Copy all TX descriptor information into txdesc, + * after that we are free to use the skb->cb array + * for our information. + */ + intf->beacon->skb = skb; + rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); /* * Fill in skb descriptor @@ -1815,7 +1830,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; skbdesc->data = skb->data; skbdesc->data_len = skb->len; - skbdesc->desc = priv_tx->desc; + skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; @@ -1834,8 +1849,8 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * Write entire beacon with descriptor to register, * and kick the beacon generator. */ - rt2x00lib_write_tx_desc(rt2x00dev, skb, control); - memcpy(priv_tx->data, skb->data, skb->len); + memcpy(entry_priv->data, skb->data, skb->len); + rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); return 0; @@ -1895,28 +1910,28 @@ static const struct data_queue_desc rt2500pci_queue_rx = { .entry_num = RX_ENTRIES, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci_rx), + .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_tx = { .entry_num = TX_ENTRIES, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci_tx), + .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_bcn = { .entry_num = BEACON_ENTRIES, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci_tx), + .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_atim = { .entry_num = ATIM_ENTRIES, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci_tx), + .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct rt2x00_ops rt2500pci_ops = { @@ -1925,6 +1940,7 @@ static const struct rt2x00_ops rt2500pci_ops = { .max_ap_intf = 1, .eeprom_size = EEPROM_SIZE, .rf_size = RF_SIZE, + .tx_queues = NUM_TX_QUEUES, .rx = &rt2500pci_queue_rx, .tx = &rt2500pci_queue_tx, .bcn = &rt2500pci_queue_bcn, |