Commit 0b8004aa authored by Gertjan van Wingerde's avatar Gertjan van Wingerde Committed by Ivo van Doorn

rt2x00: Properly reserve room for descriptors in skbs.

Instead of fiddling with the skb->data pointer and thereby risking
out of bounds accesses, properly reserve the space needed in an
skb for descriptors.
Signed-off-by: default avatarGertjan van Wingerde <gwingerde@gmail.com>
Acked-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
parent baaffe67
...@@ -1229,7 +1229,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, ...@@ -1229,7 +1229,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
} }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
rt2x00lib_txdone(entry, &txdesc); rt2x00pci_txdone(entry, &txdesc);
} }
} }
......
...@@ -1365,7 +1365,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, ...@@ -1365,7 +1365,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
} }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
rt2x00lib_txdone(entry, &txdesc); rt2x00pci_txdone(entry, &txdesc);
} }
} }
......
...@@ -1034,7 +1034,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1034,7 +1034,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); __le32 *txd = (__le32 *) skb->data;
u32 word; u32 word;
/* /*
...@@ -1080,6 +1080,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1080,6 +1080,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
*/ */
skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txd; skbdesc->desc = txd;
skbdesc->desc_len = TXD_DESC_SIZE; skbdesc->desc_len = TXD_DESC_SIZE;
} }
...@@ -1107,6 +1108,12 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, ...@@ -1107,6 +1108,12 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0); rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
/*
* Add space for the descriptor in front of the skb.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
memset(entry->skb->data, 0, TXD_DESC_SIZE);
/* /*
* Write the TX descriptor for the beacon. * Write the TX descriptor for the beacon.
*/ */
...@@ -1117,11 +1124,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, ...@@ -1117,11 +1124,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
*/ */
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Take the descriptor in front of the skb into account.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
/* /*
* USB devices cannot blindly pass the skb->len as the * USB devices cannot blindly pass the skb->len as the
* length of the data to usb_fill_bulk_urb. Pass the skb * length of the data to usb_fill_bulk_urb. Pass the skb
......
...@@ -282,9 +282,8 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) ...@@ -282,9 +282,8 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
} }
EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
{ {
__le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE);
u32 word; u32 word;
/* /*
......
...@@ -111,7 +111,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, ...@@ -111,7 +111,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token, const u8 command, const u8 token,
const u8 arg0, const u8 arg1); const u8 arg0, const u8 arg1);
void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc); void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc); void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
extern const struct rt2x00debug rt2800_rt2x00debug; extern const struct rt2x00debug rt2800_rt2x00debug;
......
...@@ -616,7 +616,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, ...@@ -616,7 +616,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
static void rt2800pci_write_tx_datadesc(struct queue_entry* entry, static void rt2800pci_write_tx_datadesc(struct queue_entry* entry,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
{ {
rt2800_write_txwi(entry->skb, txdesc); rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
} }
...@@ -692,27 +692,29 @@ static void rt2800pci_write_beacon(struct queue_entry *entry, ...@@ -692,27 +692,29 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0); rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
* Add space for the TXWI in front of the skb.
*/
skb_push(entry->skb, TXWI_DESC_SIZE);
memset(entry->skb, 0, TXWI_DESC_SIZE);
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
*/ */
skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE; skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = entry->skb->data;
skbdesc->desc_len = TXWI_DESC_SIZE; skbdesc->desc_len = TXWI_DESC_SIZE;
/* /*
* Add the TXWI for the beacon to the skb. * Add the TXWI for the beacon to the skb.
*/ */
rt2800_write_txwi(entry->skb, txdesc); rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
/* /*
* Dump beacon to userspace through debugfs. * Dump beacon to userspace through debugfs.
*/ */
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Adjust skb to take TXWI into account.
*/
skb_push(entry->skb, TXWI_DESC_SIZE);
/* /*
* Write entire beacon with TXWI to register. * Write entire beacon with TXWI to register.
*/ */
...@@ -888,8 +890,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) ...@@ -888,8 +890,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
/* Check if we got a match by looking at WCID/ACK/PID /* Check if we got a match by looking at WCID/ACK/PID
* fields */ * fields */
txwi = (__le32 *)(entry->skb->data - txwi = (__le32 *) entry->skb->data;
rt2x00dev->ops->extra_tx_headroom);
rt2x00_desc_read(txwi, 1, &word); rt2x00_desc_read(txwi, 1, &word);
tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
...@@ -934,7 +935,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) ...@@ -934,7 +935,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
__set_bit(TXDONE_FALLBACK, &txdesc.flags); __set_bit(TXDONE_FALLBACK, &txdesc.flags);
rt2x00lib_txdone(entry, &txdesc); rt2x00pci_txdone(entry, &txdesc);
} }
} }
......
...@@ -400,13 +400,14 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -400,13 +400,14 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE); __le32 *txi = (__le32 *) skb->data;
__le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE);
u32 word; u32 word;
/* /*
* Initialize TXWI descriptor * Initialize TXWI descriptor
*/ */
rt2800_write_txwi(skb, txdesc); rt2800_write_txwi(txwi, txdesc);
/* /*
* Initialize TXINFO descriptor * Initialize TXINFO descriptor
...@@ -426,6 +427,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -426,6 +427,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
*/ */
skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txi; skbdesc->desc = txi;
skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
} }
...@@ -449,27 +451,29 @@ static void rt2800usb_write_beacon(struct queue_entry *entry, ...@@ -449,27 +451,29 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0); rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
* Add space for the TXWI in front of the skb.
*/
skb_push(entry->skb, TXWI_DESC_SIZE);
memset(entry->skb, 0, TXWI_DESC_SIZE);
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
*/ */
skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE; skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = entry->skb->data;
skbdesc->desc_len = TXWI_DESC_SIZE; skbdesc->desc_len = TXWI_DESC_SIZE;
/* /*
* Add the TXWI for the beacon to the skb. * Add the TXWI for the beacon to the skb.
*/ */
rt2800_write_txwi(entry->skb, txdesc); rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
/* /*
* Dump beacon to userspace through debugfs. * Dump beacon to userspace through debugfs.
*/ */
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Adjust skb to take TXWI into account.
*/
skb_push(entry->skb, TXWI_DESC_SIZE);
/* /*
* Write entire beacon with descriptor to register. * Write entire beacon with descriptor to register.
*/ */
......
...@@ -1001,6 +1001,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) ...@@ -1001,6 +1001,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
*/ */
void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
* rt2x00queue_unmap_skb - Unmap a skb from DMA.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to unmap.
*/
void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/** /**
* rt2x00queue_get_queue - Convert queue index to queue pointer * rt2x00queue_get_queue - Convert queue index to queue pointer
* @rt2x00dev: Pointer to &struct rt2x00_dev. * @rt2x00dev: Pointer to &struct rt2x00_dev.
......
...@@ -210,11 +210,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -210,11 +210,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
unsigned int i; unsigned int i;
bool success; bool success;
/*
* Unmap the skb.
*/
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/* /*
* Remove L2 padding which was added during * Remove L2 padding which was added during
*/ */
......
...@@ -104,13 +104,6 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -104,13 +104,6 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry); struct queue_entry *entry);
/**
* rt2x00queue_unmap_skb - Unmap a skb from DMA.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to unmap.
*/
void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/** /**
* rt2x00queue_free_skb - free a skb * rt2x00queue_free_skb - free a skb
* @rt2x00dev: Pointer to &struct rt2x00_dev. * @rt2x00dev: Pointer to &struct rt2x00_dev.
......
...@@ -81,12 +81,24 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry, ...@@ -81,12 +81,24 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry,
return -EINVAL; return -EINVAL;
} }
/*
* Add the requested extra tx headroom in front of the skb.
*/
skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
/* /*
* Call the driver's write_tx_datadesc function, if it exists. * Call the driver's write_tx_datadesc function, if it exists.
*/ */
if (rt2x00dev->ops->lib->write_tx_datadesc) if (rt2x00dev->ops->lib->write_tx_datadesc)
rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc); rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc);
/*
* Map the skb to DMA.
*/
if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
rt2x00queue_map_txskb(rt2x00dev, entry->skb);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
...@@ -94,6 +106,34 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); ...@@ -94,6 +106,34 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
/* /*
* TX/RX data handlers. * TX/RX data handlers.
*/ */
void rt2x00pci_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
/*
* Unmap the skb.
*/
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/*
* Remove the extra tx headroom from the skb.
*/
skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
/*
* Signal that the TX descriptor is no longer in the skb.
*/
skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
/*
* Pass on to rt2x00lib.
*/
rt2x00lib_txdone(entry, txdesc);
}
EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{ {
struct data_queue *queue = rt2x00dev->rx; struct data_queue *queue = rt2x00dev->rx;
......
...@@ -108,6 +108,14 @@ struct queue_entry_priv_pci { ...@@ -108,6 +108,14 @@ struct queue_entry_priv_pci {
dma_addr_t desc_dma; dma_addr_t desc_dma;
}; };
/**
* rt2x00pci_txdone - Handle TX done events.
* @entry: The queue entry for which a TX done event was received.
* @txdesc: The TX done descriptor for the entry.
*/
void rt2x00pci_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
/** /**
* rt2x00pci_rxdone - Handle RX done events * rt2x00pci_rxdone - Handle RX done events
* @rt2x00dev: Device pointer, see &struct rt2x00_dev. * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
......
...@@ -100,21 +100,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) ...@@ -100,21 +100,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
/*
* If device has requested headroom, we should make sure that
* is also mapped to the DMA so it can be used for transfering
* additional descriptor information to the hardware.
*/
skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
skbdesc->skb_dma = skbdesc->skb_dma =
dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
/*
* Restore data pointer to original location again.
*/
skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
} }
EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
...@@ -130,16 +117,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) ...@@ -130,16 +117,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
} }
if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
/* dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
* Add headroom to the skb length, it has been removed
* by the driver, but it was actually mapped to DMA.
*/
dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
skb->len + rt2x00dev->ops->extra_tx_headroom,
DMA_TO_DEVICE); DMA_TO_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
} }
} }
EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{ {
...@@ -534,9 +517,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, ...@@ -534,9 +517,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
return -EIO; return -EIO;
} }
if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
rt2x00queue_map_txskb(queue->rt2x00dev, skb);
set_bit(ENTRY_DATA_PENDING, &entry->flags); set_bit(ENTRY_DATA_PENDING, &entry->flags);
rt2x00queue_index_inc(queue, Q_INDEX); rt2x00queue_index_inc(queue, Q_INDEX);
......
...@@ -197,6 +197,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) ...@@ -197,6 +197,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return; return;
/*
* Remove the descriptor from the front of the skb.
*/
skb_pull(entry->skb, entry->queue->desc_size);
/* /*
* Obtain the status about this packet. * Obtain the status about this packet.
* Note that when the status is 0 it does not mean the * Note that when the status is 0 it does not mean the
...@@ -242,12 +247,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry, ...@@ -242,12 +247,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry,
entry->skb->data, length, entry->skb->data, length,
rt2x00usb_interrupt_txdone, entry); rt2x00usb_interrupt_txdone, entry);
/*
* Make sure the skb->data pointer points to the frame, not the
* descriptor.
*/
skb_pull(entry->skb, entry->queue->desc_size);
/* /*
* Call the driver's write_tx_datadesc function, if it exists. * Call the driver's write_tx_datadesc function, if it exists.
*/ */
......
...@@ -2110,7 +2110,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) ...@@ -2110,7 +2110,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
__set_bit(TXDONE_UNKNOWN, &txdesc.flags); __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
txdesc.retry = 0; txdesc.retry = 0;
rt2x00lib_txdone(entry_done, &txdesc); rt2x00pci_txdone(entry_done, &txdesc);
entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
} }
...@@ -2130,7 +2130,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) ...@@ -2130,7 +2130,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
} }
txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
rt2x00lib_txdone(entry, &txdesc); rt2x00pci_txdone(entry, &txdesc);
} }
} }
......
...@@ -1442,7 +1442,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1442,7 +1442,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); __le32 *txd = (__le32 *) skb->data;
u32 word; u32 word;
/* /*
...@@ -1505,6 +1505,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1505,6 +1505,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
*/ */
skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txd; skbdesc->desc = txd;
skbdesc->desc_len = TXD_DESC_SIZE; skbdesc->desc_len = TXD_DESC_SIZE;
} }
...@@ -1527,6 +1528,12 @@ static void rt73usb_write_beacon(struct queue_entry *entry, ...@@ -1527,6 +1528,12 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
/*
* Add space for the descriptor in front of the skb.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
memset(entry->skb->data, 0, TXD_DESC_SIZE);
/* /*
* Write the TX descriptor for the beacon. * Write the TX descriptor for the beacon.
*/ */
...@@ -1537,11 +1544,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry, ...@@ -1537,11 +1544,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
*/ */
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Take the descriptor in front of the skb into account.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
/* /*
* Write entire beacon with descriptor to register. * Write entire beacon with descriptor to register.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment