rt2x00: Correctly handle RTS frames
Subsystems (3)
PATCH 16/26 rt2x00: Correctly handle RTS frames
Correctly handle rts frames in txdone, by freeing the packet. Also use the is_rts_frame to detect if the frame was rts. This was done incorrectly previously.
Signed-off-by Ivo van Doorn <[email protected]>
---
drivers/net/wireless/d80211/rt2x00/rt2400pci.c +11 -4
@@ -1597,6 +1597,7 @@int tx_status;int ack;int ring_full; +int rts;/* * Store the current status of the ring.
@@ -1634,9 +1635,16 @@ entry->tx_status.retry_count =rt2x00_get_field32 ( word,TXD_W0_RETRY_COUNT ); -if (!GET_FLAG (entry,ENTRY_RTS_FRAME )) +/* +* If this is not an RTS frame send the tx_status to d80211, +* that method also cleans up the skb structure. When this +* is a RTS frame, that it is our job to clean this structure up. +*/ +if (!rts)ieee80211_tx_status (rt2x00dev->hw, entry->skb, &entry->tx_status); +else +dev_kfree_skb (entry->skb);rt2x00_set_field32 (&word,TXD_W0_VALID ,0 );rt2x00_desc_write (txd,0 , word);
@@ -1772,7 +1780,7 @@*/ frame_control =le16_to_cpu (ieee80211hdr->frame_control);if ((control->flags &IEEE80211_TXCTL_USE_RTS_CTS ) && - (frame_control &IEEE80211_FCTL_STYPE ) !=IEEE80211_STYPE_RTS ) { + !is_rts_frame (frame_control)) { skb_rts =rt2400pci_create_rts (rt2x00dev, ieee80211hdr, control->rts_cts_duration);if (!skb_rts) {
@@ -1808,8 +1816,7 @@memcpy (rt2x00_data_addr (entry), skb->data, skb->len);rt2400pci_write_tx_desc (rt2x00dev, txd, skb, control);memcpy (&entry->tx_status.control, control,sizeof (*control)); -if (((frame_control &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_CTL ) && - ((frame_control &IEEE80211_FCTL_STYPE ) ==IEEE80211_STYPE_RTS )) +if (is_rts_frame (frame_control))SET_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb = skb;
drivers/net/wireless/d80211/rt2x00/rt2500pci.c +11 -4
@@ -1760,6 +1760,7 @@int tx_status;int ack;int ring_full; +int rts;/* * Store the current status of the ring.
@@ -1797,9 +1798,16 @@ entry->tx_status.retry_count =rt2x00_get_field32 ( word,TXD_W0_RETRY_COUNT ); -if (!GET_FLAG (entry,ENTRY_RTS_FRAME )) +/* +* If this is not an RTS frame send the tx_status to d80211, +* that method also cleans up the skb structure. When this +* is a RTS frame, that it is our job to clean this structure up. +*/ +if (!rts)ieee80211_tx_status (rt2x00dev->hw, entry->skb, &entry->tx_status); +else +dev_kfree_skb (entry->skb);rt2x00_set_field32 (&word,TXD_W0_VALID ,0 );rt2x00_desc_write (txd,0 , word);
@@ -1935,7 +1943,7 @@*/ frame_control =le16_to_cpu (ieee80211hdr->frame_control);if ((control->flags &IEEE80211_TXCTL_USE_RTS_CTS ) && - (frame_control &IEEE80211_FCTL_STYPE ) !=IEEE80211_STYPE_RTS ) { + !is_rts_frame (frame_control)) { skb_rts =rt2500pci_create_rts (rt2x00dev, ieee80211hdr, control->rts_cts_duration);if (!skb_rts) {
@@ -1970,8 +1978,7 @@memcpy (rt2x00_data_addr (entry), skb->data, skb->len);rt2500pci_write_tx_desc (rt2x00dev, txd, skb, control);memcpy (&entry->tx_status.control, control,sizeof (*control)); -if (((frame_control &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_CTL ) && - ((frame_control &IEEE80211_FCTL_STYPE ) ==IEEE80211_STYPE_RTS )) +if (is_rts_frame (frame_control))SET_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb = skb;
drivers/net/wireless/d80211/rt2x00/rt2500usb.c +11 -4
@@ -1722,6 +1722,7 @@u32 word;int ack;int ring_full; +int rts;/* * Store the current status of the ring.
@@ -1755,9 +1756,16 @@rt2x00_bbp_read (rt2x00dev,0 , (u8 *)&entry->tx_status.ack_signal); -if (!GET_FLAG (entry,ENTRY_RTS_FRAME )) +/* +* If this is not an RTS frame send the tx_status to d80211, +* that method also cleans up the skb structure. When this +* is a RTS frame, that it is our job to clean this structure up. +*/ +if (!rts)ieee80211_tx_status (rt2x00dev->hw, entry->skb, &entry->tx_status); +else +dev_kfree_skb (entry->skb);CLEAR_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb =NULL ;
@@ -1845,7 +1853,7 @@*/ frame_control =le16_to_cpu (ieee80211hdr->frame_control);if ((control->flags &IEEE80211_TXCTL_USE_RTS_CTS ) && - (frame_control &IEEE80211_FCTL_STYPE ) !=IEEE80211_STYPE_RTS ) { + !is_rts_frame (frame_control)) { skb_rts =rt2500usb_create_rts (rt2x00dev, ieee80211hdr, control->rts_cts_duration);if (!skb_rts) {
@@ -1874,8 +1882,7 @@memcpy (rt2x00_txdata_addr (entry), skb->data, skb->len);rt2500usb_write_tx_desc (rt2x00dev, txd, skb, control);memcpy (&entry->tx_status.control, control,sizeof (*control)); -if (((frame_control &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_CTL ) && - ((frame_control &IEEE80211_FCTL_STYPE ) ==IEEE80211_STYPE_RTS )) +if (is_rts_frame (frame_control))SET_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb = skb;
drivers/net/wireless/d80211/rt2x00/rt61pci.c +11 -4
@@ -2223,6 +2223,7 @@int tx_status;int ack;int ring_full; +int rts; txd =rt2x00_desc_addr (entry);rt2x00_desc_read (txd,0 , &word);
@@ -2255,9 +2256,16 @@ entry->tx_status.retry_count =rt2x00_get_field32 ( sta_csr4,STA_CSR4_RETRY_COUNT ); -if (!GET_FLAG (entry,ENTRY_RTS_FRAME )) +/* +* If this is not an RTS frame send the tx_status to d80211, +* that method also cleans up the skb structure. When this +* is a RTS frame, that it is our job to clean this structure up. +*/ +if (!rts)ieee80211_tx_status (rt2x00dev->hw, entry->skb, &entry->tx_status); +else +dev_kfree_skb (entry->skb);rt2x00_set_field32 (&word,TXD_W0_VALID ,0 );rt2x00_desc_write (txd,0 , word);
@@ -2433,7 +2441,7 @@*/ frame_control =le16_to_cpu (ieee80211hdr->frame_control);if ((control->flags &IEEE80211_TXCTL_USE_RTS_CTS ) && - (frame_control &IEEE80211_FCTL_STYPE ) !=IEEE80211_STYPE_RTS ) { + !is_rts_frame (frame_control)) { skb_rts =rt61pci_create_rts (rt2x00dev, ieee80211hdr, control->rts_cts_duration);if (!skb_rts) {
@@ -2463,8 +2471,7 @@memcpy (rt2x00_data_addr (entry), skb->data, skb->len);rt61pci_write_tx_desc (rt2x00dev, txd, skb, control);memcpy (&entry->tx_status.control, control,sizeof (*control)); -if (((frame_control &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_CTL ) && - ((frame_control &IEEE80211_FCTL_STYPE ) ==IEEE80211_STYPE_RTS )) +if (is_rts_frame (frame_control))SET_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb = skb;
drivers/net/wireless/d80211/rt2x00/rt73usb.c +11 -4
@@ -2001,6 +2001,7 @@u32 word;int ack;int ring_full; +int rts;/* * Store the current status of the ring.
@@ -2034,9 +2035,16 @@rt2x00_bbp_read (rt2x00dev,32 , (u8 *)&entry->tx_status.ack_signal); -if (!GET_FLAG (entry,ENTRY_RTS_FRAME )) +/* +* If this is not an RTS frame send the tx_status to d80211, +* that method also cleans up the skb structure. When this +* is a RTS frame, that it is our job to clean this structure up. +*/ +if (!rts)ieee80211_tx_status (rt2x00dev->hw, entry->skb, &entry->tx_status); +else +dev_kfree_skb (entry->skb);CLEAR_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb =NULL ;
@@ -2123,7 +2131,7 @@*/ frame_control =le16_to_cpu (ieee80211hdr->frame_control);if ((control->flags &IEEE80211_TXCTL_USE_RTS_CTS ) && - (frame_control &IEEE80211_FCTL_STYPE ) !=IEEE80211_STYPE_RTS ) { + !is_rts_frame (frame_control)) { skb_rts =rt73usb_create_rts (rt2x00dev, ieee80211hdr, control->rts_cts_duration);if (!skb_rts) {
@@ -2152,8 +2160,7 @@memcpy (rt2x00_data_addr (entry), skb->data, skb->len);rt73usb_write_tx_desc (rt2x00dev, txd, skb, control);memcpy (&entry->tx_status.control, control,sizeof (*control)); -if (((frame_control &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_CTL ) && - ((frame_control &IEEE80211_FCTL_STYPE ) ==IEEE80211_STYPE_RTS )) +if (is_rts_frame (frame_control))SET_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb = skb;