diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 51c5575ed02f..26c2e0a1a308 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1255,8 +1255,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1255 | */ | 1255 | */ |
1256 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1256 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1257 | struct sk_buff *skb, | 1257 | struct sk_buff *skb, |
1258 | struct txentry_desc *txdesc, | 1258 | struct txentry_desc *txdesc) |
1259 | struct ieee80211_tx_control *control) | ||
1260 | { | 1259 | { |
1261 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1260 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1262 | __le32 *txd = skbdesc->desc; | 1261 | __le32 *txd = skbdesc->desc; |
@@ -1301,8 +1300,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1301 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1300 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1302 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1301 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1303 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1302 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1304 | !!(control->flags & | 1303 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1305 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
1306 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1304 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1307 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1305 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1308 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1306 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
@@ -1405,25 +1403,26 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1405 | { | 1403 | { |
1406 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1404 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1407 | __le32 *rxd = (__le32 *)entry->skb->data; | 1405 | __le32 *rxd = (__le32 *)entry->skb->data; |
1408 | unsigned int offset = entry->queue->desc_size + 2; | ||
1409 | u32 word0; | 1406 | u32 word0; |
1410 | u32 word1; | 1407 | u32 word1; |
1411 | 1408 | ||
1412 | /* | 1409 | /* |
1413 | * Copy descriptor to the available headroom inside the skbuffer. | 1410 | * Copy descriptor to the skb->cb array, this has 2 benefits: |
1411 | * 1) Each descriptor word is 4 byte aligned. | ||
1412 | * 2) Descriptor is safe from moving of frame data in rt2x00usb. | ||
1414 | */ | 1413 | */ |
1415 | skb_push(entry->skb, offset); | 1414 | skbdesc->desc_len = |
1416 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | 1415 | min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); |
1417 | rxd = (__le32 *)entry->skb->data; | 1416 | memcpy(entry->skb->cb, rxd, skbdesc->desc_len); |
1417 | skbdesc->desc = entry->skb->cb; | ||
1418 | rxd = (__le32 *)skbdesc->desc; | ||
1418 | 1419 | ||
1419 | /* | 1420 | /* |
1420 | * The descriptor is now aligned to 4 bytes and thus it is | 1421 | * It is now safe to read the descriptor on all architectures. |
1421 | * now safe to read it on all architectures. | ||
1422 | */ | 1422 | */ |
1423 | rt2x00_desc_read(rxd, 0, &word0); | 1423 | rt2x00_desc_read(rxd, 0, &word0); |
1424 | rt2x00_desc_read(rxd, 1, &word1); | 1424 | rt2x00_desc_read(rxd, 1, &word1); |
1425 | 1425 | ||
1426 | rxdesc->flags = 0; | ||
1427 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1426 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1428 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1427 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1429 | 1428 | ||
@@ -1437,25 +1436,18 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1437 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); | 1436 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1438 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1437 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1439 | 1438 | ||
1440 | rxdesc->dev_flags = 0; | ||
1441 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1439 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
1442 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | 1440 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; |
1443 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | 1441 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) |
1444 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 1442 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
1445 | 1443 | ||
1446 | /* | 1444 | /* |
1447 | * Adjust the skb memory window to the frame boundaries. | 1445 | * Set skb pointers, and update frame information. |
1448 | */ | 1446 | */ |
1449 | skb_pull(entry->skb, offset + entry->queue->desc_size); | 1447 | skb_pull(entry->skb, entry->queue->desc_size); |
1450 | skb_trim(entry->skb, rxdesc->size); | 1448 | skb_trim(entry->skb, rxdesc->size); |
1451 | |||
1452 | /* | ||
1453 | * Set descriptor and data pointer. | ||
1454 | */ | ||
1455 | skbdesc->data = entry->skb->data; | 1449 | skbdesc->data = entry->skb->data; |
1456 | skbdesc->data_len = rxdesc->size; | 1450 | skbdesc->data_len = rxdesc->size; |
1457 | skbdesc->desc = rxd; | ||
1458 | skbdesc->desc_len = entry->queue->desc_size; | ||
1459 | } | 1451 | } |
1460 | 1452 | ||
1461 | /* | 1453 | /* |
@@ -1833,7 +1825,6 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1833 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1825 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1834 | IEEE80211_HW_SIGNAL_DBM; | 1826 | IEEE80211_HW_SIGNAL_DBM; |
1835 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1827 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1836 | rt2x00dev->hw->queues = 4; | ||
1837 | 1828 | ||
1838 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1829 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1839 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1830 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1957,12 +1948,13 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1957 | #define rt73usb_get_tsf NULL | 1948 | #define rt73usb_get_tsf NULL |
1958 | #endif | 1949 | #endif |
1959 | 1950 | ||
1960 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 1951 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
1961 | struct ieee80211_tx_control *control) | ||
1962 | { | 1952 | { |
1963 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1953 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1964 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 1954 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1955 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1965 | struct skb_frame_desc *skbdesc; | 1956 | struct skb_frame_desc *skbdesc; |
1957 | struct txentry_desc txdesc; | ||
1966 | unsigned int beacon_base; | 1958 | unsigned int beacon_base; |
1967 | u32 reg; | 1959 | u32 reg; |
1968 | 1960 | ||
@@ -1970,6 +1962,14 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1970 | return -ENOBUFS; | 1962 | return -ENOBUFS; |
1971 | 1963 | ||
1972 | /* | 1964 | /* |
1965 | * Copy all TX descriptor information into txdesc, | ||
1966 | * after that we are free to use the skb->cb array | ||
1967 | * for our information. | ||
1968 | */ | ||
1969 | intf->beacon->skb = skb; | ||
1970 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1971 | |||
1972 | /* | ||
1973 | * Add the descriptor in front of the skb. | 1973 | * Add the descriptor in front of the skb. |
1974 | */ | 1974 | */ |
1975 | skb_push(skb, intf->beacon->queue->desc_size); | 1975 | skb_push(skb, intf->beacon->queue->desc_size); |
@@ -2001,7 +2001,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2001 | * Write entire beacon with descriptor to register, | 2001 | * Write entire beacon with descriptor to register, |
2002 | * and kick the beacon generator. | 2002 | * and kick the beacon generator. |
2003 | */ | 2003 | */ |
2004 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2004 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
2005 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | 2005 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2006 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2006 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2007 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | 2007 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
@@ -2058,21 +2058,21 @@ static const struct data_queue_desc rt73usb_queue_rx = { | |||
2058 | .entry_num = RX_ENTRIES, | 2058 | .entry_num = RX_ENTRIES, |
2059 | .data_size = DATA_FRAME_SIZE, | 2059 | .data_size = DATA_FRAME_SIZE, |
2060 | .desc_size = RXD_DESC_SIZE, | 2060 | .desc_size = RXD_DESC_SIZE, |
2061 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | 2061 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2062 | }; | 2062 | }; |
2063 | 2063 | ||
2064 | static const struct data_queue_desc rt73usb_queue_tx = { | 2064 | static const struct data_queue_desc rt73usb_queue_tx = { |
2065 | .entry_num = TX_ENTRIES, | 2065 | .entry_num = TX_ENTRIES, |
2066 | .data_size = DATA_FRAME_SIZE, | 2066 | .data_size = DATA_FRAME_SIZE, |
2067 | .desc_size = TXD_DESC_SIZE, | 2067 | .desc_size = TXD_DESC_SIZE, |
2068 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2068 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2069 | }; | 2069 | }; |
2070 | 2070 | ||
2071 | static const struct data_queue_desc rt73usb_queue_bcn = { | 2071 | static const struct data_queue_desc rt73usb_queue_bcn = { |
2072 | .entry_num = 4 * BEACON_ENTRIES, | 2072 | .entry_num = 4 * BEACON_ENTRIES, |
2073 | .data_size = MGMT_FRAME_SIZE, | 2073 | .data_size = MGMT_FRAME_SIZE, |
2074 | .desc_size = TXINFO_SIZE, | 2074 | .desc_size = TXINFO_SIZE, |
2075 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2075 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2076 | }; | 2076 | }; |
2077 | 2077 | ||
2078 | static const struct rt2x00_ops rt73usb_ops = { | 2078 | static const struct rt2x00_ops rt73usb_ops = { |
@@ -2081,6 +2081,7 @@ static const struct rt2x00_ops rt73usb_ops = { | |||
2081 | .max_ap_intf = 4, | 2081 | .max_ap_intf = 4, |
2082 | .eeprom_size = EEPROM_SIZE, | 2082 | .eeprom_size = EEPROM_SIZE, |
2083 | .rf_size = RF_SIZE, | 2083 | .rf_size = RF_SIZE, |
2084 | .tx_queues = NUM_TX_QUEUES, | ||
2084 | .rx = &rt73usb_queue_rx, | 2085 | .rx = &rt73usb_queue_rx, |
2085 | .tx = &rt73usb_queue_tx, | 2086 | .tx = &rt73usb_queue_tx, |
2086 | .bcn = &rt73usb_queue_bcn, | 2087 | .bcn = &rt73usb_queue_bcn, |