diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-10-07 11:31:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-07 11:31:56 -0400 |
commit | a6d27d2ac89359f84c1a559b5530967ff671d269 (patch) | |
tree | 46062804362f97f29ad904d18d8314f780e0b108 /drivers/net/wireless/rtl818x | |
parent | 494486f8fd0eec956c5df823581df5dcf5409a6f (diff) |
Revert "rtl8180: use NAPI for bottom-half processing"
This reverts commit 030725d2c7c1fafec7ede618647bf30ed79601f0.
This commit relies on commit 5ed3bc7288487bd4f891f420a07319e0b538b4fe
("mac80211: use netif_receive_skb in ieee80211_tx_status callpath")
Unfortunately not all drivers are calling ieee80211_tx_status from a
compatible context, so that commit needs to be reverted in 2.6.36.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8180_dev.c | 128 |
1 files changed, 59 insertions, 69 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 05c6badbe201..707c688da618 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
@@ -99,66 +99,19 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | static void rtl8180_handle_tx(struct ieee80211_hw *dev) | 102 | static void rtl8180_handle_rx(struct ieee80211_hw *dev) |
103 | { | 103 | { |
104 | struct rtl8180_priv *priv = dev->priv; | 104 | struct rtl8180_priv *priv = dev->priv; |
105 | struct rtl8180_tx_ring *ring; | 105 | unsigned int count = 32; |
106 | int prio; | ||
107 | |||
108 | spin_lock(&priv->lock); | ||
109 | |||
110 | for (prio = 3; prio >= 0; prio--) { | ||
111 | ring = &priv->tx_ring[prio]; | ||
112 | |||
113 | while (skb_queue_len(&ring->queue)) { | ||
114 | struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; | ||
115 | struct sk_buff *skb; | ||
116 | struct ieee80211_tx_info *info; | ||
117 | u32 flags = le32_to_cpu(entry->flags); | ||
118 | |||
119 | if (flags & RTL818X_TX_DESC_FLAG_OWN) | ||
120 | break; | ||
121 | |||
122 | ring->idx = (ring->idx + 1) % ring->entries; | ||
123 | skb = __skb_dequeue(&ring->queue); | ||
124 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), | ||
125 | skb->len, PCI_DMA_TODEVICE); | ||
126 | |||
127 | info = IEEE80211_SKB_CB(skb); | ||
128 | ieee80211_tx_info_clear_status(info); | ||
129 | |||
130 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
131 | (flags & RTL818X_TX_DESC_FLAG_TX_OK)) | ||
132 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
133 | |||
134 | info->status.rates[0].count = (flags & 0xFF) + 1; | ||
135 | info->status.rates[1].idx = -1; | ||
136 | |||
137 | ieee80211_tx_status(dev, skb); | ||
138 | if (ring->entries - skb_queue_len(&ring->queue) == 2) | ||
139 | ieee80211_wake_queue(dev, prio); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | spin_unlock(&priv->lock); | ||
144 | } | ||
145 | |||
146 | static int rtl8180_poll(struct ieee80211_hw *dev, int budget) | ||
147 | { | ||
148 | struct rtl8180_priv *priv = dev->priv; | ||
149 | unsigned int count = 0; | ||
150 | u8 signal, agc, sq; | 106 | u8 signal, agc, sq; |
151 | 107 | ||
152 | /* handle pending Tx queue cleanup */ | 108 | while (count--) { |
153 | rtl8180_handle_tx(dev); | ||
154 | |||
155 | while (count++ < budget) { | ||
156 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 109 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; |
157 | struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; | 110 | struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; |
158 | u32 flags = le32_to_cpu(entry->flags); | 111 | u32 flags = le32_to_cpu(entry->flags); |
159 | 112 | ||
160 | if (flags & RTL818X_RX_DESC_FLAG_OWN) | 113 | if (flags & RTL818X_RX_DESC_FLAG_OWN) |
161 | break; | 114 | return; |
162 | 115 | ||
163 | if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | | 116 | if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | |
164 | RTL818X_RX_DESC_FLAG_FOF | | 117 | RTL818X_RX_DESC_FLAG_FOF | |
@@ -198,7 +151,7 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget) | |||
198 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; | 151 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; |
199 | 152 | ||
200 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | 153 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); |
201 | ieee80211_rx(dev, skb); | 154 | ieee80211_rx_irqsafe(dev, skb); |
202 | 155 | ||
203 | skb = new_skb; | 156 | skb = new_skb; |
204 | priv->rx_buf[priv->rx_idx] = skb; | 157 | priv->rx_buf[priv->rx_idx] = skb; |
@@ -215,16 +168,41 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget) | |||
215 | entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); | 168 | entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); |
216 | priv->rx_idx = (priv->rx_idx + 1) % 32; | 169 | priv->rx_idx = (priv->rx_idx + 1) % 32; |
217 | } | 170 | } |
171 | } | ||
172 | |||
173 | static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) | ||
174 | { | ||
175 | struct rtl8180_priv *priv = dev->priv; | ||
176 | struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; | ||
218 | 177 | ||
219 | if (count < budget) { | 178 | while (skb_queue_len(&ring->queue)) { |
220 | /* disable polling */ | 179 | struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; |
221 | ieee80211_napi_complete(dev); | 180 | struct sk_buff *skb; |
181 | struct ieee80211_tx_info *info; | ||
182 | u32 flags = le32_to_cpu(entry->flags); | ||
222 | 183 | ||
223 | /* enable interrupts */ | 184 | if (flags & RTL818X_TX_DESC_FLAG_OWN) |
224 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); | 185 | return; |
225 | } | 186 | |
187 | ring->idx = (ring->idx + 1) % ring->entries; | ||
188 | skb = __skb_dequeue(&ring->queue); | ||
189 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), | ||
190 | skb->len, PCI_DMA_TODEVICE); | ||
191 | |||
192 | info = IEEE80211_SKB_CB(skb); | ||
193 | ieee80211_tx_info_clear_status(info); | ||
194 | |||
195 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
196 | (flags & RTL818X_TX_DESC_FLAG_TX_OK)) | ||
197 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
198 | |||
199 | info->status.rates[0].count = (flags & 0xFF) + 1; | ||
200 | info->status.rates[1].idx = -1; | ||
226 | 201 | ||
227 | return count; | 202 | ieee80211_tx_status_irqsafe(dev, skb); |
203 | if (ring->entries - skb_queue_len(&ring->queue) == 2) | ||
204 | ieee80211_wake_queue(dev, prio); | ||
205 | } | ||
228 | } | 206 | } |
229 | 207 | ||
230 | static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) | 208 | static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) |
@@ -233,17 +211,31 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) | |||
233 | struct rtl8180_priv *priv = dev->priv; | 211 | struct rtl8180_priv *priv = dev->priv; |
234 | u16 reg; | 212 | u16 reg; |
235 | 213 | ||
214 | spin_lock(&priv->lock); | ||
236 | reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); | 215 | reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); |
237 | if (unlikely(reg == 0xFFFF)) | 216 | if (unlikely(reg == 0xFFFF)) { |
217 | spin_unlock(&priv->lock); | ||
238 | return IRQ_HANDLED; | 218 | return IRQ_HANDLED; |
219 | } | ||
239 | 220 | ||
240 | rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); | 221 | rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); |
241 | 222 | ||
242 | /* disable interrupts */ | 223 | if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) |
243 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); | 224 | rtl8180_handle_tx(dev, 3); |
225 | |||
226 | if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) | ||
227 | rtl8180_handle_tx(dev, 2); | ||
228 | |||
229 | if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) | ||
230 | rtl8180_handle_tx(dev, 1); | ||
244 | 231 | ||
245 | /* enable polling */ | 232 | if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) |
246 | ieee80211_napi_schedule(dev); | 233 | rtl8180_handle_tx(dev, 0); |
234 | |||
235 | if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) | ||
236 | rtl8180_handle_rx(dev); | ||
237 | |||
238 | spin_unlock(&priv->lock); | ||
247 | 239 | ||
248 | return IRQ_HANDLED; | 240 | return IRQ_HANDLED; |
249 | } | 241 | } |
@@ -255,6 +247,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
255 | struct rtl8180_priv *priv = dev->priv; | 247 | struct rtl8180_priv *priv = dev->priv; |
256 | struct rtl8180_tx_ring *ring; | 248 | struct rtl8180_tx_ring *ring; |
257 | struct rtl8180_tx_desc *entry; | 249 | struct rtl8180_tx_desc *entry; |
250 | unsigned long flags; | ||
258 | unsigned int idx, prio; | 251 | unsigned int idx, prio; |
259 | dma_addr_t mapping; | 252 | dma_addr_t mapping; |
260 | u32 tx_flags; | 253 | u32 tx_flags; |
@@ -301,7 +294,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
301 | plcp_len |= 1 << 15; | 294 | plcp_len |= 1 << 15; |
302 | } | 295 | } |
303 | 296 | ||
304 | spin_lock(&priv->lock); | 297 | spin_lock_irqsave(&priv->lock, flags); |
305 | 298 | ||
306 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 299 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
307 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 300 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
@@ -325,7 +318,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
325 | if (ring->entries - skb_queue_len(&ring->queue) < 2) | 318 | if (ring->entries - skb_queue_len(&ring->queue) < 2) |
326 | ieee80211_stop_queue(dev, prio); | 319 | ieee80211_stop_queue(dev, prio); |
327 | 320 | ||
328 | spin_unlock(&priv->lock); | 321 | spin_unlock_irqrestore(&priv->lock, flags); |
329 | 322 | ||
330 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); | 323 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); |
331 | 324 | ||
@@ -871,7 +864,6 @@ static const struct ieee80211_ops rtl8180_ops = { | |||
871 | .prepare_multicast = rtl8180_prepare_multicast, | 864 | .prepare_multicast = rtl8180_prepare_multicast, |
872 | .configure_filter = rtl8180_configure_filter, | 865 | .configure_filter = rtl8180_configure_filter, |
873 | .get_tsf = rtl8180_get_tsf, | 866 | .get_tsf = rtl8180_get_tsf, |
874 | .napi_poll = rtl8180_poll, | ||
875 | }; | 867 | }; |
876 | 868 | ||
877 | static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 869 | static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) |
@@ -1003,8 +995,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
1003 | dev->queues = 1; | 995 | dev->queues = 1; |
1004 | dev->max_signal = 65; | 996 | dev->max_signal = 65; |
1005 | 997 | ||
1006 | dev->napi_weight = 64; | ||
1007 | |||
1008 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); | 998 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); |
1009 | reg &= RTL818X_TX_CONF_HWVER_MASK; | 999 | reg &= RTL818X_TX_CONF_HWVER_MASK; |
1010 | switch (reg) { | 1000 | switch (reg) { |