diff options
Diffstat (limited to 'drivers/net/wireless/p54/p54usb.c')
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 68f1b80f04d9..88fb65046c71 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -135,6 +135,16 @@ static void p54u_rx_cb(struct urb *urb) | |||
135 | usb_submit_urb(urb, GFP_ATOMIC); | 135 | usb_submit_urb(urb, GFP_ATOMIC); |
136 | } | 136 | } |
137 | 137 | ||
138 | static void p54u_tx_reuse_skb_cb(struct urb *urb) | ||
139 | { | ||
140 | struct sk_buff *skb = urb->context; | ||
141 | struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *) | ||
142 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv; | ||
143 | |||
144 | skb_pull(skb, priv->common.tx_hdr_len); | ||
145 | usb_free_urb(urb); | ||
146 | } | ||
147 | |||
138 | static void p54u_tx_cb(struct urb *urb) | 148 | static void p54u_tx_cb(struct urb *urb) |
139 | { | 149 | { |
140 | usb_free_urb(urb); | 150 | usb_free_urb(urb); |
@@ -146,6 +156,16 @@ static void p54u_tx_free_cb(struct urb *urb) | |||
146 | usb_free_urb(urb); | 156 | usb_free_urb(urb); |
147 | } | 157 | } |
148 | 158 | ||
159 | static void p54u_tx_free_skb_cb(struct urb *urb) | ||
160 | { | ||
161 | struct sk_buff *skb = urb->context; | ||
162 | struct ieee80211_hw *dev = (struct ieee80211_hw *) | ||
163 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
164 | |||
165 | p54_free_skb(dev, skb); | ||
166 | usb_free_urb(urb); | ||
167 | } | ||
168 | |||
149 | static int p54u_init_urbs(struct ieee80211_hw *dev) | 169 | static int p54u_init_urbs(struct ieee80211_hw *dev) |
150 | { | 170 | { |
151 | struct p54u_priv *priv = dev->priv; | 171 | struct p54u_priv *priv = dev->priv; |
@@ -192,8 +212,8 @@ static void p54u_free_urbs(struct ieee80211_hw *dev) | |||
192 | } | 212 | } |
193 | } | 213 | } |
194 | 214 | ||
195 | static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 215 | static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb, |
196 | size_t len, int free_on_tx) | 216 | int free_on_tx) |
197 | { | 217 | { |
198 | struct p54u_priv *priv = dev->priv; | 218 | struct p54u_priv *priv = dev->priv; |
199 | struct urb *addr_urb, *data_urb; | 219 | struct urb *addr_urb, *data_urb; |
@@ -209,11 +229,14 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, | |||
209 | } | 229 | } |
210 | 230 | ||
211 | usb_fill_bulk_urb(addr_urb, priv->udev, | 231 | usb_fill_bulk_urb(addr_urb, priv->udev, |
212 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id, | 232 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
213 | sizeof(data->req_id), p54u_tx_cb, dev); | 233 | &((struct p54_control_hdr *)skb->data)->req_id, 4, |
234 | p54u_tx_cb, dev); | ||
214 | usb_fill_bulk_urb(data_urb, priv->udev, | 235 | usb_fill_bulk_urb(data_urb, priv->udev, |
215 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len, | 236 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
216 | free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); | 237 | skb->data, skb->len, |
238 | free_on_tx ? p54u_tx_free_skb_cb : | ||
239 | p54u_tx_reuse_skb_cb, skb); | ||
217 | 240 | ||
218 | usb_submit_urb(addr_urb, GFP_ATOMIC); | 241 | usb_submit_urb(addr_urb, GFP_ATOMIC); |
219 | usb_submit_urb(data_urb, GFP_ATOMIC); | 242 | usb_submit_urb(data_urb, GFP_ATOMIC); |
@@ -232,31 +255,35 @@ static __le32 p54u_lm87_chksum(const u32 *data, size_t length) | |||
232 | return cpu_to_le32(chk); | 255 | return cpu_to_le32(chk); |
233 | } | 256 | } |
234 | 257 | ||
235 | static void p54u_tx_lm87(struct ieee80211_hw *dev, | 258 | static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb, |
236 | struct p54_control_hdr *data, | 259 | int free_on_tx) |
237 | size_t len, int free_on_tx) | ||
238 | { | 260 | { |
239 | struct p54u_priv *priv = dev->priv; | 261 | struct p54u_priv *priv = dev->priv; |
240 | struct urb *data_urb; | 262 | struct urb *data_urb; |
241 | struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr); | 263 | struct lm87_tx_hdr *hdr; |
264 | __le32 checksum; | ||
265 | __le32 addr = ((struct p54_control_hdr *)skb->data)->req_id; | ||
242 | 266 | ||
243 | data_urb = usb_alloc_urb(0, GFP_ATOMIC); | 267 | data_urb = usb_alloc_urb(0, GFP_ATOMIC); |
244 | if (!data_urb) | 268 | if (!data_urb) |
245 | return; | 269 | return; |
246 | 270 | ||
247 | hdr->chksum = p54u_lm87_chksum((u32 *)data, len); | 271 | checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len); |
248 | hdr->device_addr = data->req_id; | 272 | hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
273 | hdr->chksum = checksum; | ||
274 | hdr->device_addr = addr; | ||
249 | 275 | ||
250 | usb_fill_bulk_urb(data_urb, priv->udev, | 276 | usb_fill_bulk_urb(data_urb, priv->udev, |
251 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, | 277 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
252 | len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, | 278 | skb->data, skb->len, |
253 | dev); | 279 | free_on_tx ? p54u_tx_free_skb_cb : |
280 | p54u_tx_reuse_skb_cb, skb); | ||
254 | 281 | ||
255 | usb_submit_urb(data_urb, GFP_ATOMIC); | 282 | usb_submit_urb(data_urb, GFP_ATOMIC); |
256 | } | 283 | } |
257 | 284 | ||
258 | static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 285 | static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb, |
259 | size_t len, int free_on_tx) | 286 | int free_on_tx) |
260 | { | 287 | { |
261 | struct p54u_priv *priv = dev->priv; | 288 | struct p54u_priv *priv = dev->priv; |
262 | struct urb *int_urb, *data_urb; | 289 | struct urb *int_urb, *data_urb; |
@@ -284,11 +311,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da | |||
284 | reg->addr = cpu_to_le32(P54U_DEV_BASE); | 311 | reg->addr = cpu_to_le32(P54U_DEV_BASE); |
285 | reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); | 312 | reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); |
286 | 313 | ||
287 | len += sizeof(*data); | 314 | hdr = (void *)skb_push(skb, sizeof(*hdr)); |
288 | hdr = (void *)data - sizeof(*hdr); | ||
289 | memset(hdr, 0, sizeof(*hdr)); | 315 | memset(hdr, 0, sizeof(*hdr)); |
290 | hdr->device_addr = data->req_id; | 316 | hdr->device_addr = ((struct p54_control_hdr *)skb->data)->req_id; |
291 | hdr->len = cpu_to_le16(len); | 317 | hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_control_hdr)); |
292 | 318 | ||
293 | usb_fill_bulk_urb(int_urb, priv->udev, | 319 | usb_fill_bulk_urb(int_urb, priv->udev, |
294 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), | 320 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), |
@@ -296,8 +322,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da | |||
296 | usb_submit_urb(int_urb, GFP_ATOMIC); | 322 | usb_submit_urb(int_urb, GFP_ATOMIC); |
297 | 323 | ||
298 | usb_fill_bulk_urb(data_urb, priv->udev, | 324 | usb_fill_bulk_urb(data_urb, priv->udev, |
299 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr), | 325 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
300 | free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); | 326 | skb->data, skb->len, |
327 | free_on_tx ? p54u_tx_free_skb_cb : | ||
328 | p54u_tx_reuse_skb_cb, skb); | ||
301 | usb_submit_urb(data_urb, GFP_ATOMIC); | 329 | usb_submit_urb(data_urb, GFP_ATOMIC); |
302 | } | 330 | } |
303 | 331 | ||