From ac1044628d477d655f5f70420c3493119abeb6d3 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 16 Jun 2008 19:54:57 +0200 Subject: rt2x00: Use ieee80211 fc handlers With the introduction of the ieee80211 fc handlers we can now remove the rt2x00.h versions to use the global versions. Signed-off-by: Ivo van Doorn Reviewed-by: Harvey Harrison Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 27 --------------------------- drivers/net/wireless/rt2x00/rt2x00dev.c | 5 ++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 14 +++++--------- 3 files changed, 7 insertions(+), 39 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0da8f972a1b..21fd9b40be8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -110,33 +110,6 @@ #define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) -/* - * IEEE802.11 header defines - */ -static inline int is_rts_frame(u16 fc) -{ - return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); -} - -static inline int is_cts_frame(u16 fc) -{ - return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); -} - -static inline int is_probe_resp(u16 fc) -{ - return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); -} - -static inline int is_beacon(u16 fc) -{ - return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)); -} - /* * Chipset identification * The chipset on the device is composed of a RT and RF chip. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9ea677320da..f9e75319770 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -561,7 +561,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry, unsigned int align; unsigned int i; int idx = -1; - u16 fc; /* * The data behind the ieee80211 header must be @@ -606,8 +605,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, * Only update link status if this is a beacon frame carrying our bssid. */ hdr = (struct ieee80211_hdr *)entry->skb->data; - fc = le16_to_cpu(hdr->frame_control); - if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS)) + if (ieee80211_is_beacon(hdr->frame_control) && + (rxdesc->dev_flags & RXDONE_MY_BSS)) rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); rt2x00dev->link.qual.rx_success++; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7b52039b01a..15660b588a1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -80,7 +80,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, unsigned int data_length; unsigned int duration; unsigned int residual; - u16 frame_control; memset(txdesc, 0, sizeof(*txdesc)); @@ -95,11 +94,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* Data length should be extended with 4 bytes for CRC */ data_length = entry->skb->len + 4; - /* - * Read required fields from ieee80211 header. - */ - frame_control = le16_to_cpu(hdr->frame_control); - /* * Check whether this frame is to be acked. */ @@ -109,9 +103,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Check if this is a RTS/CTS frame */ - if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { + if (ieee80211_is_rts(hdr->frame_control) || + ieee80211_is_cts(hdr->frame_control)) { __set_bit(ENTRY_TXD_BURST, &txdesc->flags); - if (is_rts_frame(frame_control)) + if (ieee80211_is_rts(hdr->frame_control)) __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags); else __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); @@ -139,7 +134,8 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, * Beacons and probe responses require the tsf timestamp * to be inserted into the frame. */ - if (txdesc->queue == QID_BEACON || is_probe_resp(frame_control)) + if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); /* -- cgit v1.2.3 From c95edf5432f097c926dd3f59239ecde80da3b214 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 16 Jun 2008 19:55:18 +0200 Subject: rt2x00: Properly clean up beacon skbs. The skbs containing the beacons weren't properly cleaned up for rt2400pci, rt2500pci, rt61pci, and rt73usb. Clean up those skbs in the manner appropriate for each driver. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 6 ++++++ drivers/net/wireless/rt2x00/rt61pci.c | 6 ++++++ drivers/net/wireless/rt2x00/rt73usb.c | 6 ++++++ 3 files changed, 18 insertions(+) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index f9e75319770..b8e0c4c3ed0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -474,6 +474,12 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac, vif->type != IEEE80211_IF_TYPE_IBSS) return; + /* + * Clean up the beacon skb. + */ + dev_kfree_skb_irq(intf->beacon->skb); + intf->beacon->skb = NULL; + spin_lock(&intf->lock); intf->delayed_flags |= DELAYED_UPDATE_BEACON; spin_unlock(&intf->lock); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 5b7267ece1b..27f30ae8f52 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2402,6 +2402,12 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) skb->data, skb->len); rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); + /* + * Clean up beacon skb. + */ + dev_kfree_skb_any(skb); + intf->beacon->skb = NULL; + return 0; } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index fceefd730ab..42b7e98b2d2 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2001,6 +2001,12 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) REGISTER_TIMEOUT32(skb->len)); rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); + /* + * Clean up the beacon skb. + */ + dev_kfree_skb(skb); + intf->beacon->skb = NULL; + return 0; } -- cgit v1.2.3 From 14a3bf89212b5c758bd39bb4afc972c4ba6d599f Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 16 Jun 2008 19:55:43 +0200 Subject: rt2x00: Convert rt2x00 to use generic DMA-mapping API At the same time clean up the device administration a bit, by storing a pointer to struct device instead of a void pointer that is dependent on the type of device. The normal PCI and USB subsystem provided macros can be used to convert the device pointer to the right type. This makes the rt2x00 driver a bit more type-safe. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500usb.c | 5 +++-- drivers/net/wireless/rt2x00/rt2x00.h | 6 +----- drivers/net/wireless/rt2x00/rt2x00pci.c | 19 +++++++++---------- drivers/net/wireless/rt2x00/rt2x00usb.c | 11 +++++++---- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 8 files changed, 25 insertions(+), 26 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index bb3d83560d0..76ec1514fa4 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1366,7 +1366,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3c956b91c4e..5f0117f9a88 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1688,7 +1688,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->extra_tx_headroom = 0; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9851cefaabf..6b6e7b93d2a 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1588,7 +1588,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); @@ -1672,7 +1672,8 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = + interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); 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_usb_bcn *bcn_priv; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 21fd9b40be8..8d45235ecc3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -625,11 +625,7 @@ struct rt2x00_dev { * When accessing this variable, the rt2x00dev_{pci,usb} * macro's should be used for correct typecasting. */ - void *dev; -#define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) -#define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) -#define rt2x00dev_usb_dev(__dev)\ - ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) + struct device *dev; /* * Callback functions. diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 8d6ad18d389..d6138389a5d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -194,7 +194,6 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, struct data_queue *queue) { - struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); struct queue_entry_priv_pci *entry_priv; void *addr; dma_addr_t dma; @@ -203,7 +202,8 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, /* * Allocate DMA memory for descriptor and buffer. */ - addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); + addr = dma_alloc_coherent(rt2x00dev->dev, dma_size(queue), &dma, + GFP_KERNEL | GFP_DMA); if (!addr) return -ENOMEM; @@ -226,19 +226,18 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, struct data_queue *queue) { - struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); struct queue_entry_priv_pci *entry_priv = queue->entries[0].priv_data; if (entry_priv->data) - pci_free_consistent(pci_dev, dma_size(queue), - entry_priv->data, entry_priv->data_dma); + dma_free_coherent(rt2x00dev->dev, dma_size(queue), + entry_priv->data, entry_priv->data_dma); entry_priv->data = NULL; } int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) { - struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); + struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); struct data_queue *queue; int status; @@ -279,7 +278,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) /* * Free irq line. */ - free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev); + free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev); /* * Free DMA @@ -308,7 +307,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) { - struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); + struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); @@ -357,7 +356,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) if (pci_set_mwi(pci_dev)) ERROR_PROBE("MWI not available.\n"); - if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { + if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) { ERROR_PROBE("PCI DMA not supported.\n"); retval = -EIO; goto exit_disable_device; @@ -373,7 +372,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) pci_set_drvdata(pci_dev, hw); rt2x00dev = hw->priv; - rt2x00dev->dev = pci_dev; + rt2x00dev->dev = &pci_dev->dev; rt2x00dev->ops = ops; rt2x00dev->hw = hw; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 3080969ae5b..f91901ffda5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -40,7 +40,8 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, void *buffer, const u16 buffer_length, const int timeout) { - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = + interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); int status; unsigned int i; unsigned int pipe = @@ -176,7 +177,8 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) int rt2x00usb_write_tx_data(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = + interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc; u32 length; @@ -364,7 +366,8 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = + interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); struct queue_entry_priv_usb *entry_priv = entry->priv_data; usb_fill_bulk_urb(entry_priv->urb, usb_dev, @@ -558,7 +561,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, usb_set_intfdata(usb_intf, hw); rt2x00dev = hw->priv; - rt2x00dev->dev = usb_intf; + rt2x00dev->dev = &usb_intf->dev; rt2x00dev->ops = ops; rt2x00dev->hw = hw; mutex_init(&rt2x00dev->usb_cache_mutex); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 27f30ae8f52..2a7f3062035 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1973,7 +1973,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * To determine the RT chip we have to read the * PCI header of the device. */ - pci_read_config_word(rt2x00dev_pci(rt2x00dev), + pci_read_config_word(to_pci_dev(rt2x00dev->dev), PCI_CONFIG_HEADER_DEVICE, &device); value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); @@ -2239,7 +2239,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 42b7e98b2d2..ead6db04d60 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1821,7 +1821,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; - SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); -- cgit v1.2.3 From 30caa6e3d586442f7c3ad081260ee1b22bb123de Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 16 Jun 2008 19:56:08 +0200 Subject: rt2x00: Centralize allocation of RX skbs. In preparation of replacing the statically allocated DMA buffers with dynamically mapped skbs, centralize the allocation of RX skbs to rt2x00queue.c and let rt2x00pci already use them. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 10 +++- drivers/net/wireless/rt2x00/rt2x00pci.c | 77 ++++++++++++++++++++----------- drivers/net/wireless/rt2x00/rt2x00queue.c | 71 +++++++++++++++++++++------- drivers/net/wireless/rt2x00/rt2x00usb.c | 21 +-------- 4 files changed, 113 insertions(+), 66 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8d45235ecc3..08e8b0a005a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -899,10 +899,16 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) } /** - * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. + * rt2x00queue_alloc_skb - allocate a skb. * @queue: The queue for which the skb will be applicable. */ -struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); +struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue); + +/** + * rt2x00queue_free_skb - free a skb + * @skb: The skb to free. + */ +void rt2x00queue_free_skb(struct sk_buff *skb); /** * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index d6138389a5d..e7e3a459b66 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -74,13 +74,59 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); /* * TX/RX data handlers. */ +static void rt2x00pci_rxdone_entry(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry) +{ + struct sk_buff *skb; + struct skb_frame_desc *skbdesc; + struct rxdone_entry_desc rxdesc; + struct queue_entry_priv_pci *entry_priv = entry->priv_data; + + /* + * Allocate a new sk_buffer. If no new buffer available, drop the + * received frame and reuse the existing buffer. + */ + skb = rt2x00queue_alloc_skb(entry->queue); + if (!skb) + return; + + /* + * Extract the RXD details. + */ + memset(&rxdesc, 0, sizeof(rxdesc)); + rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); + + /* + * Copy the received data to the entries' skb. + */ + memcpy(entry->skb->data, entry_priv->data, rxdesc.size); + skb_trim(entry->skb, rxdesc.size); + + /* + * Fill in skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->desc = entry_priv->desc; + skbdesc->desc_len = entry->queue->desc_size; + skbdesc->entry = entry; + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(entry, &rxdesc); + + /* + * Replace the entries' skb with the newly allocated one. + */ + entry->skb = skb; +} + void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue = rt2x00dev->rx; struct queue_entry *entry; struct queue_entry_priv_pci *entry_priv; - struct skb_frame_desc *skbdesc; - struct rxdone_entry_desc rxdesc; u32 word; while (1) { @@ -91,32 +137,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) break; - memset(&rxdesc, 0, sizeof(rxdesc)); - rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); - - /* - * Allocate the sk_buffer and copy all data into it. - */ - entry->skb = rt2x00queue_alloc_rxskb(queue); - if (!entry->skb) - return; - - memcpy(entry->skb->data, entry_priv->data, rxdesc.size); - skb_trim(entry->skb, rxdesc.size); - - /* - * Fill in skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->desc = entry_priv->desc; - skbdesc->desc_len = queue->desc_size; - skbdesc->entry = entry; - - /* - * Send the frame to rt2x00lib for further processing. - */ - rt2x00lib_rxdone(entry, &rxdesc); + rt2x00pci_rxdone_entry(rt2x00dev, entry); if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 15660b588a1..278f1a1ac92 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -29,7 +29,7 @@ #include "rt2x00.h" #include "rt2x00lib.h" -struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) +struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) { struct sk_buff *skb; unsigned int frame_size; @@ -42,17 +42,10 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) frame_size = queue->data_size + queue->desc_size; /* - * For the allocation we should keep a few things in mind: - * 1) 4byte alignment of 802.11 payload - * - * For (1) we need at most 4 bytes to guarentee the correct - * alignment. We are going to optimize the fact that the chance - * that the 802.11 header_size % 4 == 2 is much bigger then - * anything else. However since we need to move the frame up - * to 3 bytes to the front, which means we need to preallocate - * 6 bytes. + * Reserve a few bytes extra headroom to allow drivers some moving + * space (e.g. for alignment), while keeping the skb aligned. */ - reserved_size = 6; + reserved_size = 8; /* * Allocate skbuffer. @@ -66,7 +59,13 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) return skb; } -EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); +EXPORT_SYMBOL_GPL(rt2x00queue_alloc_skb); + +void rt2x00queue_free_skb(struct sk_buff *skb) +{ + dev_kfree_skb_any(skb); +} +EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) @@ -422,12 +421,45 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return 0; } +static void rt2x00queue_free_skbs(struct data_queue *queue) +{ + unsigned int i; + + if (!queue->entries) + return; + + for (i = 0; i < queue->limit; i++) { + if (queue->entries[i].skb) + rt2x00queue_free_skb(queue->entries[i].skb); + } +} + +static int rt2x00queue_alloc_skbs(struct data_queue *queue) +{ + unsigned int i; + struct sk_buff *skb; + + for (i = 0; i < queue->limit; i++) { + skb = rt2x00queue_alloc_skb(queue); + if (!skb) + goto exit; + + queue->entries[i].skb = skb; + } + + return 0; + +exit: + rt2x00queue_free_skbs(queue); + + return -ENOMEM; +} + int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; int status; - status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); if (status) goto exit; @@ -442,11 +474,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) if (status) goto exit; - if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) - return 0; + if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { + status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], + rt2x00dev->ops->atim); + if (status) + goto exit; + } - status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], - rt2x00dev->ops->atim); + status = rt2x00queue_alloc_skbs(rt2x00dev->rx); if (status) goto exit; @@ -464,6 +499,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; + rt2x00queue_free_skbs(rt2x00dev->rx); + queue_for_each(rt2x00dev, queue) { kfree(queue->entries); queue->entries = NULL; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index f91901ffda5..29dba86c8cf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -300,7 +300,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * If allocation fails, we should drop the current frame * so we can recycle the existing sk buffer for the new frame. */ - skb = rt2x00queue_alloc_rxskb(entry->queue); + skb = rt2x00queue_alloc_skb(entry->queue); if (!skb) goto skip_entry; @@ -434,8 +434,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, entry_priv = queue->entries[i].priv_data; usb_kill_urb(entry_priv->urb); usb_free_urb(entry_priv->urb); - if (queue->entries[i].skb) - kfree_skb(queue->entries[i].skb); } /* @@ -457,10 +455,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - struct sk_buff *skb; - unsigned int entry_size; - unsigned int i; - int uninitialized_var(status); + int status; /* * Allocate DMA @@ -471,18 +466,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) goto exit; } - /* - * For the RX queue, skb's should be allocated. - */ - entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; - for (i = 0; i < rt2x00dev->rx->limit; i++) { - skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx); - if (!skb) - goto exit; - - rt2x00dev->rx->entries[i].skb = skb; - } - return 0; exit: -- cgit v1.2.3 From c4da004857056e6ee034c4110ccdcba659077b7e Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 16 Jun 2008 19:56:31 +0200 Subject: rt2x00: Replace statically allocated DMA buffers with mapped skb's. The current PCI drivers require a lot of pre-allocated DMA buffers. Reduce this by using dynamically mapped skb's (using pci_map_single) instead of the pre- allocated DMA buffers that are allocated at device start-up time. At the same time move common RX path code into rt2x00lib from rt2x00pci and rt2x00usb, as the RX paths now are now almost the same. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 13 ++-- drivers/net/wireless/rt2x00/rt2500pci.c | 10 ++- drivers/net/wireless/rt2x00/rt2x00.h | 28 +++++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 64 ++++++++++----- drivers/net/wireless/rt2x00/rt2x00pci.c | 125 ++++++++---------------------- drivers/net/wireless/rt2x00/rt2x00pci.h | 3 - drivers/net/wireless/rt2x00/rt2x00queue.c | 85 ++++++++++++++++---- drivers/net/wireless/rt2x00/rt2x00queue.h | 16 ++-- drivers/net/wireless/rt2x00/rt2x00usb.c | 27 +------ drivers/net/wireless/rt2x00/rt61pci.c | 9 ++- 10 files changed, 204 insertions(+), 176 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 76ec1514fa4..de2dd336f23 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; rt2x00_desc_read(entry_priv->desc, 2, &word); - rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, - entry->queue->data_size); + rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); rt2x00_desc_write(entry_priv->desc, 2, word); rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); + rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(entry_priv->desc, 0, &word); @@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, * 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_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(txd, 2, &word); @@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) rt2400pci_probe_hw_mode(rt2x00dev); /* - * This device requires the atim queue + * This device requires the atim queue and DMA-mapped skbs. */ __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); /* * Set the rssi offset. @@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) * Write entire beacon with descriptor to register, * and kick the beacon generator. */ - memcpy(entry_priv->data, skb->data, skb->len); + rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5f0117f9a88..5077b62dcc5 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); + rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(entry_priv->desc, 0, &word); @@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, * 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_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(txd, 2, &word); @@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) rt2500pci_probe_hw_mode(rt2x00dev); /* - * This device requires the atim queue + * This device requires the atim queue and DMA-mapped skbs. */ __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); /* * Set the rssi offset. @@ -1842,7 +1844,7 @@ 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. */ - memcpy(entry_priv->data, skb->data, skb->len); + rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 08e8b0a005a..28c9026bb56 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -601,6 +601,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_BEACON_GUARD, DRIVER_REQUIRE_ATIM_QUEUE, DRIVER_REQUIRE_SCHEDULED, + DRIVER_REQUIRE_DMA, /* * Driver configuration @@ -899,16 +900,33 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) } /** - * rt2x00queue_alloc_skb - allocate a skb. + * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. + * @rt2x00dev: Pointer to &struct rt2x00_dev. * @queue: The queue for which the skb will be applicable. */ -struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue); +struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry); + +/** + * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @skb: The skb to map. + */ +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_free_skb - free a skb + * @rt2x00dev: Pointer to &struct rt2x00_dev. * @skb: The skb to free. */ -void rt2x00queue_free_skb(struct sk_buff *skb); +void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); /** * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input @@ -977,8 +995,8 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); -void rt2x00lib_rxdone(struct queue_entry *entry, - struct rxdone_entry_desc *rxdesc); +void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry); /* * mac80211 handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b8e0c4c3ed0..99b14ba99d9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -468,6 +468,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) static void rt2x00lib_beacondone_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { + struct rt2x00_dev *rt2x00dev = data; struct rt2x00_intf *intf = vif_to_intf(vif); if (vif->type != IEEE80211_IF_TYPE_AP && @@ -477,7 +478,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac, /* * Clean up the beacon skb. */ - dev_kfree_skb_irq(intf->beacon->skb); + rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); intf->beacon->skb = NULL; spin_lock(&intf->lock); @@ -555,34 +556,55 @@ void rt2x00lib_txdone(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); -void rt2x00lib_rxdone(struct queue_entry *entry, - struct rxdone_entry_desc *rxdesc) +void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct rxdone_entry_desc rxdesc; + struct sk_buff *skb; struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; - unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb); struct ieee80211_supported_band *sband; struct ieee80211_hdr *hdr; const struct rt2x00_rate *rate; + unsigned int header_size; unsigned int align; unsigned int i; int idx = -1; + /* + * Allocate a new sk_buffer. If no new buffer available, drop the + * received frame and reuse the existing buffer. + */ + skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); + if (!skb) + return; + + /* + * Unmap the skb. + */ + rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + + /* + * Extract the RXD details. + */ + memset(&rxdesc, 0, sizeof(rxdesc)); + rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); + /* * The data behind the ieee80211 header must be * aligned on a 4 byte boundary. */ + header_size = ieee80211_get_hdrlen_from_skb(entry->skb); align = ((unsigned long)(entry->skb->data + header_size)) & 3; if (align) { skb_push(entry->skb, align); /* Move entire frame in 1 command */ memmove(entry->skb->data, entry->skb->data + align, - rxdesc->size); + rxdesc.size); } /* Update data pointers, trim buffer to correct size */ - skb_trim(entry->skb, rxdesc->size); + skb_trim(entry->skb, rxdesc.size); /* * Update RX statistics. @@ -591,10 +613,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry, for (i = 0; i < sband->n_bitrates; i++) { rate = rt2x00_get_rate(sband->bitrates[i].hw_value); - if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && - (rate->plcp == rxdesc->signal)) || - (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && - (rate->bitrate == rxdesc->signal))) { + if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && + (rate->plcp == rxdesc.signal)) || + (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && + (rate->bitrate == rxdesc.signal))) { idx = i; break; } @@ -602,8 +624,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, if (idx < 0) { WARNING(rt2x00dev, "Frame received with unrecognized signal," - "signal=0x%.2x, plcp=%d.\n", rxdesc->signal, - !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); + "signal=0x%.2x, plcp=%d.\n", rxdesc.signal, + !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP)); idx = 0; } @@ -612,16 +634,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry, */ hdr = (struct ieee80211_hdr *)entry->skb->data; if (ieee80211_is_beacon(hdr->frame_control) && - (rxdesc->dev_flags & RXDONE_MY_BSS)) - rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); + (rxdesc.dev_flags & RXDONE_MY_BSS)) + rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi); rt2x00dev->link.qual.rx_success++; rx_status->rate_idx = idx; rx_status->qual = - rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); - rx_status->signal = rxdesc->rssi; - rx_status->flag = rxdesc->flags; + rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); + rx_status->signal = rxdesc.rssi; + rx_status->flag = rxdesc.flags; rx_status->antenna = rt2x00dev->link.ant.active.rx; /* @@ -630,7 +652,11 @@ void rt2x00lib_rxdone(struct queue_entry *entry, */ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); - entry->skb = NULL; + + /* + * Replace the skb with the freshly allocated one. + */ + entry->skb = skb; } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index e7e3a459b66..f9d0d76f870 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -65,7 +65,7 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry) skbdesc->desc_len = entry->queue->desc_size; skbdesc->entry = entry; - memcpy(entry_priv->data, entry->skb->data, entry->skb->len); + rt2x00queue_map_txskb(entry->queue->rt2x00dev, entry->skb); return 0; } @@ -74,59 +74,12 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); /* * TX/RX data handlers. */ -static void rt2x00pci_rxdone_entry(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry) -{ - struct sk_buff *skb; - struct skb_frame_desc *skbdesc; - struct rxdone_entry_desc rxdesc; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; - - /* - * Allocate a new sk_buffer. If no new buffer available, drop the - * received frame and reuse the existing buffer. - */ - skb = rt2x00queue_alloc_skb(entry->queue); - if (!skb) - return; - - /* - * Extract the RXD details. - */ - memset(&rxdesc, 0, sizeof(rxdesc)); - rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); - - /* - * Copy the received data to the entries' skb. - */ - memcpy(entry->skb->data, entry_priv->data, rxdesc.size); - skb_trim(entry->skb, rxdesc.size); - - /* - * Fill in skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->desc = entry_priv->desc; - skbdesc->desc_len = entry->queue->desc_size; - skbdesc->entry = entry; - - /* - * Send the frame to rt2x00lib for further processing. - */ - rt2x00lib_rxdone(entry, &rxdesc); - - /* - * Replace the entries' skb with the newly allocated one. - */ - entry->skb = skb; -} - void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue = rt2x00dev->rx; struct queue_entry *entry; struct queue_entry_priv_pci *entry_priv; + struct skb_frame_desc *skbdesc; u32 word; while (1) { @@ -137,12 +90,22 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) break; - rt2x00pci_rxdone_entry(rt2x00dev, entry); + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = entry_priv->desc; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(rt2x00dev, entry); - if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { - rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); - rt2x00_desc_write(entry_priv->desc, 0, word); - } + /* + * Reset the RXD for this entry. + */ + rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); rt2x00queue_index_inc(queue, Q_INDEX); } @@ -156,6 +119,11 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); u32 word; + /* + * Unmap the skb. + */ + rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + rt2x00lib_txdone(entry, txdesc); /* @@ -185,33 +153,6 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); /* * Device initialization handlers. */ -#define desc_size(__queue) \ -({ \ - ((__queue)->limit * (__queue)->desc_size);\ -}) - -#define data_size(__queue) \ -({ \ - ((__queue)->limit * (__queue)->data_size);\ -}) - -#define dma_size(__queue) \ -({ \ - data_size(__queue) + desc_size(__queue);\ -}) - -#define desc_offset(__queue, __base, __i) \ -({ \ - (__base) + data_size(__queue) + \ - ((__i) * (__queue)->desc_size); \ -}) - -#define data_offset(__queue, __base, __i) \ -({ \ - (__base) + \ - ((__i) * (__queue)->data_size); \ -}) - static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, struct data_queue *queue) { @@ -223,22 +164,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, /* * Allocate DMA memory for descriptor and buffer. */ - addr = dma_alloc_coherent(rt2x00dev->dev, dma_size(queue), &dma, - GFP_KERNEL | GFP_DMA); + addr = dma_alloc_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + &dma, GFP_KERNEL | GFP_DMA); if (!addr) return -ENOMEM; - memset(addr, 0, dma_size(queue)); + memset(addr, 0, queue->limit * queue->desc_size); /* * Initialize all queue entries to contain valid addresses. */ for (i = 0; i < queue->limit; i++) { entry_priv = queue->entries[i].priv_data; - entry_priv->desc = desc_offset(queue, addr, i); - entry_priv->desc_dma = desc_offset(queue, dma, i); - entry_priv->data = data_offset(queue, addr, i); - entry_priv->data_dma = data_offset(queue, dma, i); + entry_priv->desc = addr + i * queue->desc_size; + entry_priv->desc_dma = dma + i * queue->desc_size; } return 0; @@ -250,10 +190,11 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, struct queue_entry_priv_pci *entry_priv = queue->entries[0].priv_data; - if (entry_priv->data) - dma_free_coherent(rt2x00dev->dev, dma_size(queue), - entry_priv->data, entry_priv->data_dma); - entry_priv->data = NULL; + if (entry_priv->desc) + dma_free_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + entry_priv->desc, entry_priv->desc_dma); + entry_priv->desc = NULL; } int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 87c4a0cd78d..7e5708dca73 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry); struct queue_entry_priv_pci { __le32 *desc; dma_addr_t desc_dma; - - void *data; - dma_addr_t data_dma; }; /** diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 278f1a1ac92..29d2b912853 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -25,21 +25,24 @@ #include #include +#include #include "rt2x00.h" #include "rt2x00lib.h" -struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) +struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry) { - struct sk_buff *skb; unsigned int frame_size; unsigned int reserved_size; + struct sk_buff *skb; + struct skb_frame_desc *skbdesc; /* * The frame size includes descriptor size, because the * hardware directly receive the frame into the skbuffer. */ - frame_size = queue->data_size + queue->desc_size; + frame_size = entry->queue->data_size + entry->queue->desc_size; /* * Reserve a few bytes extra headroom to allow drivers some moving @@ -57,12 +60,67 @@ struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) skb_reserve(skb, reserved_size); skb_put(skb, frame_size); + /* + * Populate skbdesc. + */ + skbdesc = get_skb_frame_desc(skb); + memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->entry = entry; + + if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { + skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, + skb->data, + skb->len, + DMA_FROM_DEVICE); + skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; + } + return skb; } -EXPORT_SYMBOL_GPL(rt2x00queue_alloc_skb); +EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); -void rt2x00queue_free_skb(struct sk_buff *skb) +void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { + struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + + skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; +} +EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); + +void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +{ + struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + + if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { + dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + DMA_FROM_DEVICE); + skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; + } + + if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { + dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + DMA_TO_DEVICE); + skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; + } +} +EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); + +void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +{ + struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + + if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { + dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + DMA_FROM_DEVICE); + } + + if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { + dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + DMA_TO_DEVICE); + } + dev_kfree_skb_any(skb); } EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); @@ -421,7 +479,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return 0; } -static void rt2x00queue_free_skbs(struct data_queue *queue) +static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) { unsigned int i; @@ -430,27 +489,27 @@ static void rt2x00queue_free_skbs(struct data_queue *queue) for (i = 0; i < queue->limit; i++) { if (queue->entries[i].skb) - rt2x00queue_free_skb(queue->entries[i].skb); + rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); } } -static int rt2x00queue_alloc_skbs(struct data_queue *queue) +static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) { unsigned int i; struct sk_buff *skb; for (i = 0; i < queue->limit; i++) { - skb = rt2x00queue_alloc_skb(queue); + skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); if (!skb) goto exit; - queue->entries[i].skb = skb; } return 0; exit: - rt2x00queue_free_skbs(queue); + rt2x00queue_free_skbs(rt2x00dev, queue); return -ENOMEM; } @@ -481,7 +540,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) goto exit; } - status = rt2x00queue_alloc_skbs(rt2x00dev->rx); + status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); if (status) goto exit; @@ -499,7 +558,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - rt2x00queue_free_skbs(rt2x00dev->rx); + rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); queue_for_each(rt2x00dev, queue) { kfree(queue->entries); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index fcf52520b01..192b6e789a7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -83,9 +83,10 @@ enum data_queue_qid { * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc * */ -//enum skb_frame_desc_flags { -// TEMPORARILY EMPTY -//}; +enum skb_frame_desc_flags { + SKBDESC_DMA_MAPPED_RX = (1 << 0), + SKBDESC_DMA_MAPPED_TX = (1 << 1), +}; /** * struct skb_frame_desc: Descriptor information for the skb buffer @@ -94,19 +95,20 @@ enum data_queue_qid { * this structure should not exceed the size of that array (40 bytes). * * @flags: Frame flags, see &enum skb_frame_desc_flags. - * @data: Pointer to data part of frame (Start of ieee80211 header). + * @desc_len: Length of the frame descriptor. * @desc: Pointer to descriptor part of the frame. * Note that this pointer could point to something outside * of the scope of the skb->data pointer. - * @data_len: Length of the frame data. - * @desc_len: Length of the frame descriptor. + * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. * @entry: The entry to which this sk buffer belongs. */ struct skb_frame_desc { unsigned int flags; - void *desc; unsigned int desc_len; + void *desc; + + dma_addr_t skb_dma; struct queue_entry *entry; }; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 29dba86c8cf..552f0e94f80 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -266,9 +266,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct sk_buff *skb; - struct skb_frame_desc *skbdesc; - struct rxdone_entry_desc rxdesc; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u8 rxd[32]; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || @@ -284,36 +282,19 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) goto skip_entry; /* - * Fill in skb descriptor + * Fill in desc fields of the skb descriptor */ - skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->entry = entry; skbdesc->desc = rxd; skbdesc->desc_len = entry->queue->desc_size; - memset(&rxdesc, 0, sizeof(rxdesc)); - rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); - - /* - * Allocate a new sk buffer to replace the current one. - * If allocation fails, we should drop the current frame - * so we can recycle the existing sk buffer for the new frame. - */ - skb = rt2x00queue_alloc_skb(entry->queue); - if (!skb) - goto skip_entry; - /* * Send the frame to rt2x00lib for further processing. */ - rt2x00lib_rxdone(entry, &rxdesc); + rt2x00lib_rxdone(rt2x00dev, entry); /* - * Replace current entry's skb with the newly allocated one, - * and reinitialize the urb. + * Reinitialize the urb. */ - entry->skb = skb; urb->transfer_buffer = entry->skb->data; urb->transfer_buffer_length = entry->skb->len; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2a7f3062035..c9f6d484413 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1030,11 +1030,12 @@ static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; rt2x00_desc_read(entry_priv->desc, 5, &word); rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, - entry_priv->data_dma); + skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 5, word); rt2x00_desc_read(entry_priv->desc, 0, &word); @@ -1522,7 +1523,6 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, 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; @@ -1557,7 +1557,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_read(txd, 6, &word); rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, - entry_priv->data_dma); + skbdesc->skb_dma); rt2x00_desc_write(txd, 6, word); if (skbdesc->desc_len > TXINFO_SIZE) { @@ -2302,9 +2302,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) rt61pci_probe_hw_mode(rt2x00dev); /* - * This device requires firmware. + * This device requires firmware and DMA mapped skbs. */ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); /* * Set the rssi offset. -- cgit v1.2.3 From d74f5ba473b915e5d4ea1ed391984bb62d9de8b1 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 16 Jun 2008 19:56:54 +0200 Subject: rt2x00: Cleanup symbol exports With a bit of code moving to rt2x00lib within the TX and RX paths we can now remove a lot of EXPORT_SYMBOL_GPL() statements. This cleans up the interface between rt2x00lib and the drivers and has the additional benefit that rt2x00pci and rt2x00usb are trimmed down in size as well since they have less to do. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 34 --------------------- drivers/net/wireless/rt2x00/rt2x00dev.c | 29 ++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00lib.h | 51 +++++++++++++++++++++++++++++-- drivers/net/wireless/rt2x00/rt2x00pci.c | 49 ----------------------------- drivers/net/wireless/rt2x00/rt2x00pci.h | 9 ------ drivers/net/wireless/rt2x00/rt2x00queue.c | 15 ++++++--- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 ++ drivers/net/wireless/rt2x00/rt2x00usb.c | 42 +++++-------------------- drivers/net/wireless/rt2x00/rt61pci.c | 4 +-- 11 files changed, 102 insertions(+), 137 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index de2dd336f23..b3dffcfed83 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1154,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); - rt2x00pci_txdone(rt2x00dev, entry, &txdesc); + rt2x00lib_txdone(entry, &txdesc); } } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5077b62dcc5..0423c251c78 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1312,7 +1312,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); - rt2x00pci_txdone(rt2x00dev, entry, &txdesc); + rt2x00lib_txdone(entry, &txdesc); } } diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 28c9026bb56..94b7c9bd09e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -899,14 +899,6 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) return ((size * 8 * 10) % rate); } -/** - * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @queue: The queue for which the skb will be applicable. - */ -struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); - /** * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. * @rt2x00dev: Pointer to &struct rt2x00_dev. @@ -914,20 +906,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, */ 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_free_skb - free a skb - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to free. - */ -void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); - /** * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input * @entry: The entry which will be used to transfer the TX frame. @@ -977,18 +955,6 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index); -/** - * rt2x00queue_index_inc - Index incrementation function - * @queue: Queue (&struct data_queue) to perform the action on. - * @index: Index type (&enum queue_index) to perform the action on. - * - * This function will increase the requested index on the queue, - * it will grab the appropriate locks and handle queue overflow events by - * resetting the index to the start of the queue. - */ -void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); - - /* * Interrupt context handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 99b14ba99d9..2a63a7b911b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -504,6 +504,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); + enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); + + /* + * Unmap the skb. + */ + rt2x00queue_unmap_skb(rt2x00dev, entry->skb); /* * Send frame to debugfs immediately, after this call is completed @@ -552,7 +558,25 @@ void rt2x00lib_txdone(struct queue_entry *entry, ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); else dev_kfree_skb_irq(entry->skb); + + /* + * Make this entry available for reuse. + */ entry->skb = NULL; + entry->flags = 0; + + rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); + + __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + + /* + * If the data queue was below the threshold before the txdone + * handler we must make sure the packet queue in the mac80211 stack + * is reenabled when the txdone handler has finished. + */ + if (!rt2x00queue_threshold(entry->queue)) + ieee80211_wake_queue(rt2x00dev->hw, qid); } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); @@ -657,6 +681,11 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, * Replace the skb with the freshly allocated one. */ entry->skb = skb; + entry->flags = 0; + + rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); + + rt2x00queue_index_inc(entry->queue, Q_INDEX); } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 558f45bf27e..1d1f0749375 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -98,10 +98,57 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, const int force_config); -/* - * Queue handlers. +/** + * DOC: Queue handlers + */ + +/** + * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @queue: The queue for which the skb will be applicable. + */ +struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, + 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 + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @skb: The skb to free. + */ +void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); + +/** + * rt2x00queue_free_skb - free a skb + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @skb: The skb to free. + */ +void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); + +/** + * rt2x00queue_write_tx_frame - Write TX frame to hardware + * @queue: Queue over which the frame should be send + * @skb: The skb to send */ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); + +/** + * rt2x00queue_index_inc - Index incrementation function + * @queue: Queue (&struct data_queue) to perform the action on. + * @index: Index type (&enum queue_index) to perform the action on. + * + * This function will increase the requested index on the queue, + * it will grab the appropriate locks and handle queue overflow events by + * resetting the index to the start of the queue. + */ +void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); + void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index f9d0d76f870..adf2876ed8a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -60,12 +60,8 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry) * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); skbdesc->desc = entry_priv->desc; skbdesc->desc_len = entry->queue->desc_size; - skbdesc->entry = entry; - - rt2x00queue_map_txskb(entry->queue->rt2x00dev, entry->skb); return 0; } @@ -101,55 +97,10 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) * Send the frame to rt2x00lib for further processing. */ rt2x00lib_rxdone(rt2x00dev, entry); - - /* - * Reset the RXD for this entry. - */ - rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); - - rt2x00queue_index_inc(queue, Q_INDEX); } } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); -void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, - struct txdone_entry_desc *txdesc) -{ - struct queue_entry_priv_pci *entry_priv = entry->priv_data; - enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); - u32 word; - - /* - * Unmap the skb. - */ - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); - - rt2x00lib_txdone(entry, txdesc); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - - rt2x00_desc_read(entry_priv->desc, 0, &word); - rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); - rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); - rt2x00_desc_write(entry_priv->desc, 0, word); - - __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); - - /* - * If the data queue was below the threshold before the txdone - * handler we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - if (!rt2x00queue_threshold(entry->queue)) - ieee80211_wake_queue(rt2x00dev->hw, qid); - -} -EXPORT_SYMBOL_GPL(rt2x00pci_txdone); - /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 7e5708dca73..50c6df4f81d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -115,15 +115,6 @@ struct queue_entry_priv_pci { */ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); -/** - * rt2x00pci_txdone - Handle TX done events - * @rt2x00dev: Device pointer, see &struct rt2x00_dev. - * @entry: Entry which has completed the transmission of a frame. - * @desc: TX done descriptor - */ -void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, - struct txdone_entry_desc *desc); - /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 29d2b912853..49d3bb84ab6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -77,7 +77,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, return skb; } -EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { @@ -105,7 +104,6 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; } } -EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { @@ -123,7 +121,6 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) dev_kfree_skb_any(skb); } -EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) @@ -289,6 +286,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) { struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct txentry_desc txdesc; + struct skb_frame_desc *skbdesc; if (unlikely(rt2x00queue_full(queue))) return -EINVAL; @@ -309,11 +307,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) entry->skb = skb; rt2x00queue_create_tx_descriptor(entry, &txdesc); + /* + * skb->cb array is now ours and we are free to use it. + */ + skbdesc = get_skb_frame_desc(entry->skb); + memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->entry = entry; + if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); return -EIO; } + if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) + rt2x00queue_map_txskb(queue->rt2x00dev, skb); + __set_bit(ENTRY_DATA_PENDING, &entry->flags); rt2x00queue_index_inc(queue, Q_INDEX); @@ -389,7 +397,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) spin_unlock_irqrestore(&queue->lock, irqflags); } -EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); static void rt2x00queue_reset(struct data_queue *queue) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 192b6e789a7..14ce8d4e139 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -82,6 +82,8 @@ enum data_queue_qid { /** * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc * + * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX + * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX */ enum skb_frame_desc_flags { SKBDESC_DMA_MAPPED_RX = (1 << 0), diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 552f0e94f80..b94c461fbaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -131,10 +131,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; - enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || - !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -158,20 +157,6 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); - - /* - * If the data queue was below the threshold before the txdone - * handler we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - if (!rt2x00queue_threshold(entry->queue)) - ieee80211_wake_queue(rt2x00dev->hw, qid); } int rt2x00usb_write_tx_data(struct queue_entry *entry) @@ -193,10 +178,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry) * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); skbdesc->desc = entry->skb->data; skbdesc->desc_len = entry->queue->desc_size; - skbdesc->entry = entry; /* * USB devices cannot blindly pass the skb->len as the @@ -270,7 +253,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) u8 rxd[32]; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -278,8 +261,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * to be actually valid, or if the urb is signaling * a problem. */ - if (urb->actual_length < entry->queue->desc_size || urb->status) - goto skip_entry; + if (urb->actual_length < entry->queue->desc_size || urb->status) { + __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + usb_submit_urb(urb, GFP_ATOMIC); + return; + } /* * Fill in desc fields of the skb descriptor @@ -291,20 +277,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Send the frame to rt2x00lib for further processing. */ rt2x00lib_rxdone(rt2x00dev, entry); - - /* - * Reinitialize the urb. - */ - urb->transfer_buffer = entry->skb->data; - urb->transfer_buffer_length = entry->skb->len; - -skip_entry: - if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { - __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(urb, GFP_ATOMIC); - } - - rt2x00queue_index_inc(entry->queue, Q_INDEX); } /* diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index c9f6d484413..bbf1048f640 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1767,7 +1767,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) __set_bit(TXDONE_UNKNOWN, &txdesc.flags); txdesc.retry = 0; - rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); + rt2x00lib_txdone(entry_done, &txdesc); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); } @@ -1787,7 +1787,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) } txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); - rt2x00pci_txdone(rt2x00dev, entry, &txdesc); + rt2x00lib_txdone(entry, &txdesc); } } -- cgit v1.2.3 From c1d35dfa0f7d75ba14c442143a9ad8e232d3edfb Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 16 Jun 2008 19:57:11 +0200 Subject: rt2x00: Fix sparse warning on nested container_of() Sparse produces warnings about nested contain_of() statements, this means that lines like: interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); will upset sparse. Add a new macro to rt2x00usb.h which will convert to device structure to the usb_device pointer in 2 steps to prevent this sparse warning. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 3 +-- drivers/net/wireless/rt2x00/rt2x00usb.c | 9 +++------ drivers/net/wireless/rt2x00/rt2x00usb.h | 6 ++++++ 3 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6b6e7b93d2a..d0958008c01 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1672,8 +1672,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct usb_device *usb_dev = - interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 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_usb_bcn *bcn_priv; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index b94c461fbaf..5593b9a8310 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -40,8 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, void *buffer, const u16 buffer_length, const int timeout) { - struct usb_device *usb_dev = - interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); int status; unsigned int i; unsigned int pipe = @@ -162,8 +161,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) int rt2x00usb_write_tx_data(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct usb_device *usb_dev = - interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc; u32 length; @@ -319,8 +317,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { - struct usb_device *usb_dev = - interface_to_usbdev(to_usb_interface(rt2x00dev->dev)); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; usb_fill_bulk_urb(entry_priv->urb, usb_dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index b1187c812e7..aad794adf52 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -26,6 +26,12 @@ #ifndef RT2X00USB_H #define RT2X00USB_H +#define to_usb_device_intf(d) \ +({ \ + struct usb_interface *intf = to_usb_interface(d); \ + interface_to_usbdev(intf); \ +}) + /* * This variable should be used with the * usb_driver structure initialization. -- cgit v1.2.3 From f529932ce27e809e8c9bab5d744df5aef8a89157 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 16 Jun 2008 19:57:40 +0200 Subject: rt2x00: Increase queue size Without the preallocated DMA we can now safely increase the queue size withotu negative impact on the memory requirements of rt2x00. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 14ce8d4e139..5dd9cca3c62 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -42,15 +42,18 @@ /** * DOC: Number of entries per queue * - * After research it was concluded that 12 entries in a RX and TX - * queue would be sufficient. Although this is almost one third of - * the amount the legacy driver allocated, the queues aren't getting - * filled to the maximum even when working with the maximum rate. + * Under normal load without fragmentation 12 entries are sufficient + * without the queue being filled up to the maximum. When using fragmentation + * and the queue threshold code we need to add some additional margins to + * make sure the queue will never (or only under extreme load) fill up + * completely. + * Since we don't use preallocated DMA having a large number of queue entries + * will have only minimal impact on the memory requirements for the queue. */ -#define RX_ENTRIES 12 -#define TX_ENTRIES 12 +#define RX_ENTRIES 24 +#define TX_ENTRIES 24 #define BEACON_ENTRIES 1 -#define ATIM_ENTRIES 1 +#define ATIM_ENTRIES 8 /** * enum data_queue_qid: Queue identification -- cgit v1.2.3 From 8160465dc7197dc1abc426852bb3fa00108923f4 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 16 Jun 2008 19:58:00 +0200 Subject: rt2x00: Release rt2x00 2.1.8 Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94b7c9bd09e..d2ddab179c9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -44,7 +44,7 @@ /* * Module information. */ -#define DRV_VERSION "2.1.7" +#define DRV_VERSION "2.1.8" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" /* -- cgit v1.2.3 From 61243d8e79de67d703b192fae2c4ab80fc0fac34 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 20 Jun 2008 22:10:53 +0200 Subject: rt2x00: Remove duplicate deinitialization When rt2x00queue_alloc_rxskbs() fails rt2x00queue_unitialize() will be called which will free all rxskb. So we don't need to do this in the rt2x00queue_alloc_rxskb() function as well. rt2x00queue_free_skb() unmaps the DMA but doesn't clear the allocation flag. Since the code is copied from rt2x00queue_unmap_skb() anyway (and that function does clear the flag) we might as well use that function directly. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 49d3bb84ab6..8e86611791f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -107,18 +107,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - - if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, - DMA_FROM_DEVICE); - } - - if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, - DMA_TO_DEVICE); - } - + rt2x00queue_unmap_skb(rt2x00dev, skb); dev_kfree_skb_any(skb); } @@ -509,16 +498,11 @@ static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, for (i = 0; i < queue->limit; i++) { skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); if (!skb) - goto exit; + return -ENOMEM; queue->entries[i].skb = skb; } return 0; - -exit: - rt2x00queue_free_skbs(rt2x00dev, queue); - - return -ENOMEM; } int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) -- cgit v1.2.3 From 40af48ce501ea9ad9c485504a6fa0740801fa051 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Jun 2008 19:56:50 +0200 Subject: rt2x00: kill URB for all TX queues during disable_radio() During rt2x00usb_disable_radio() all pending urb's should be killed and not only those from the RX queue. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 5593b9a8310..83862e7f7ae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -284,6 +284,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) { struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; + struct data_queue *queue; unsigned int i; rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, @@ -292,9 +293,11 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Cancel all queues. */ - for (i = 0; i < rt2x00dev->rx->limit; i++) { - entry_priv = rt2x00dev->rx->entries[i].priv_data; - usb_kill_urb(entry_priv->urb); + queue_for_each(rt2x00dev, queue) { + for (i = 0; i < queue->limit; i++) { + entry_priv = queue->entries[i].priv_data; + usb_kill_urb(entry_priv->urb); + } } /* -- cgit v1.2.3 From ff28bd94e307c67abb1bccda5d3a9018bd798e08 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 27 Jun 2008 10:27:47 -0400 Subject: wireless: remove RFKILL_STATE_HARD_BLOCKED warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC [M] drivers/net/wireless/b43/rfkill.o drivers/net/wireless/b43/rfkill.c: In function ‘b43_rfkill_soft_toggle’: drivers/net/wireless/b43/rfkill.c:90: warning: enumeration value ‘RFKILL_STATE_HARD_BLOCKED’ not handled in switch CC [M] drivers/net/wireless/b43legacy/rfkill.o drivers/net/wireless/b43legacy/rfkill.c: In function ‘b43legacy_rfkill_soft_toggle’: drivers/net/wireless/b43legacy/rfkill.c:92: warning: enumeration value ‘RFKILL_STATE_HARD_BLOCKED’ not handled in switch CC [M] drivers/net/wireless/iwlwifi/iwl-rfkill.o drivers/net/wireless/iwlwifi/iwl-rfkill.c: In function ‘iwl_rfkill_soft_rf_kill’: drivers/net/wireless/iwlwifi/iwl-rfkill.c:56: warning: enumeration value ‘RFKILL_STATE_HARD_BLOCKED’ not handled in switch Also handle RFKILL_STATE_{ON,OFF} -> RFKILL_STATE_{UNBLOCKED,SOFT_BLOCKED} conversion since I'm already here... Signed-off-by: John W. Linville --- drivers/net/wireless/b43/rfkill.c | 7 +++++-- drivers/net/wireless/b43legacy/rfkill.c | 8 ++++++-- drivers/net/wireless/iwlwifi/iwl-rfkill.c | 7 +++++-- drivers/net/wireless/rt2x00/rt2x00rfkill.c | 7 +++++-- 4 files changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/rt2x00') diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 11f53cb1139..4cca203992e 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) goto out_unlock; err = 0; switch (state) { - case RFKILL_STATE_ON: + case RFKILL_STATE_UNBLOCKED: if (!dev->radio_hw_enable) { /* No luck. We can't toggle the hardware RF-kill * button from software. */ @@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) if (!dev->phy.radio_on) b43_radio_turn_on(dev); break; - case RFKILL_STATE_OFF: + case RFKILL_STATE_SOFT_BLOCKED: if (dev->phy.radio_on) b43_radio_turn_off(dev, 0); break; + default: + b43warn(wl, "Received unexpected rfkill state %d.\n", state); + break; } out_unlock: mutex_unlock(&wl->mutex); diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index d178dfbb1c9..8935a302b22 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -90,7 +90,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) goto out_unlock; err = 0; switch (state) { - case RFKILL_STATE_ON: + case RFKILL_STATE_UNBLOCKED: if (!dev->radio_hw_enable) { /* No luck. We can't toggle the hardware RF-kill * button from software. */ @@ -100,10 +100,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) if (!dev->phy.radio_on) b43legacy_radio_turn_on(dev); break; - case RFKILL_STATE_OFF: + case RFKILL_STATE_SOFT_BLOCKED: if (dev->phy.radio_on) b43legacy_radio_turn_off(dev, 0); break; + default: + b43legacywarn(wl, "Received unexpected rfkill state %d.\n", + state); + break; } out_unlock: diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 4624ac7b498..ffefbb487e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -54,17 +54,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) mutex_lock(&priv->mutex); switch (state) { - case RFKILL_STATE_ON: + case RFKILL_STATE_UNBLOCKED: iwl_radio_kill_sw_enable_radio(priv); /* if HW rf-kill is set dont allow ON state */ if (iwl_is_rfkill(priv)) err = -EBUSY; break; - case RFKILL_STATE_OFF: + case RFKILL_STATE_SOFT_BLOCKED: iwl_radio_kill_sw_disable_radio(priv); if (!iwl_is_rfkill(priv)) err = -EBUSY; break; + default: + IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); + break; } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index fcef9885ab5..207281cfa8b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -45,14 +45,17 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) return 0; - if (state == RFKILL_STATE_ON) { + if (state == RFKILL_STATE_UNBLOCKED) { INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); retval = rt2x00lib_enable_radio(rt2x00dev); - } else if (state == RFKILL_STATE_OFF) { + } else if (state == RFKILL_STATE_SOFT_BLOCKED) { INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); rt2x00lib_disable_radio(rt2x00dev); + } else { + WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n", + state); } return retval; -- cgit v1.2.3