diff options
Diffstat (limited to 'drivers/net/wireless/orinoco/main.c')
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 307 |
1 files changed, 181 insertions, 126 deletions
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 413e9ab6cab3..ca71f08709bc 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -254,7 +254,7 @@ void set_port_type(struct orinoco_private *priv) | |||
254 | /* Device methods */ | 254 | /* Device methods */ |
255 | /********************************************************************/ | 255 | /********************************************************************/ |
256 | 256 | ||
257 | static int orinoco_open(struct net_device *dev) | 257 | int orinoco_open(struct net_device *dev) |
258 | { | 258 | { |
259 | struct orinoco_private *priv = ndev_priv(dev); | 259 | struct orinoco_private *priv = ndev_priv(dev); |
260 | unsigned long flags; | 260 | unsigned long flags; |
@@ -272,8 +272,9 @@ static int orinoco_open(struct net_device *dev) | |||
272 | 272 | ||
273 | return err; | 273 | return err; |
274 | } | 274 | } |
275 | EXPORT_SYMBOL(orinoco_open); | ||
275 | 276 | ||
276 | static int orinoco_stop(struct net_device *dev) | 277 | int orinoco_stop(struct net_device *dev) |
277 | { | 278 | { |
278 | struct orinoco_private *priv = ndev_priv(dev); | 279 | struct orinoco_private *priv = ndev_priv(dev); |
279 | int err = 0; | 280 | int err = 0; |
@@ -281,25 +282,27 @@ static int orinoco_stop(struct net_device *dev) | |||
281 | /* We mustn't use orinoco_lock() here, because we need to be | 282 | /* We mustn't use orinoco_lock() here, because we need to be |
282 | able to close the interface even if hw_unavailable is set | 283 | able to close the interface even if hw_unavailable is set |
283 | (e.g. as we're released after a PC Card removal) */ | 284 | (e.g. as we're released after a PC Card removal) */ |
284 | spin_lock_irq(&priv->lock); | 285 | orinoco_lock_irq(priv); |
285 | 286 | ||
286 | priv->open = 0; | 287 | priv->open = 0; |
287 | 288 | ||
288 | err = __orinoco_down(priv); | 289 | err = __orinoco_down(priv); |
289 | 290 | ||
290 | spin_unlock_irq(&priv->lock); | 291 | orinoco_unlock_irq(priv); |
291 | 292 | ||
292 | return err; | 293 | return err; |
293 | } | 294 | } |
295 | EXPORT_SYMBOL(orinoco_stop); | ||
294 | 296 | ||
295 | static struct net_device_stats *orinoco_get_stats(struct net_device *dev) | 297 | struct net_device_stats *orinoco_get_stats(struct net_device *dev) |
296 | { | 298 | { |
297 | struct orinoco_private *priv = ndev_priv(dev); | 299 | struct orinoco_private *priv = ndev_priv(dev); |
298 | 300 | ||
299 | return &priv->stats; | 301 | return &priv->stats; |
300 | } | 302 | } |
303 | EXPORT_SYMBOL(orinoco_get_stats); | ||
301 | 304 | ||
302 | static void orinoco_set_multicast_list(struct net_device *dev) | 305 | void orinoco_set_multicast_list(struct net_device *dev) |
303 | { | 306 | { |
304 | struct orinoco_private *priv = ndev_priv(dev); | 307 | struct orinoco_private *priv = ndev_priv(dev); |
305 | unsigned long flags; | 308 | unsigned long flags; |
@@ -313,8 +316,9 @@ static void orinoco_set_multicast_list(struct net_device *dev) | |||
313 | __orinoco_set_multicast_list(dev); | 316 | __orinoco_set_multicast_list(dev); |
314 | orinoco_unlock(priv, &flags); | 317 | orinoco_unlock(priv, &flags); |
315 | } | 318 | } |
319 | EXPORT_SYMBOL(orinoco_set_multicast_list); | ||
316 | 320 | ||
317 | static int orinoco_change_mtu(struct net_device *dev, int new_mtu) | 321 | int orinoco_change_mtu(struct net_device *dev, int new_mtu) |
318 | { | 322 | { |
319 | struct orinoco_private *priv = ndev_priv(dev); | 323 | struct orinoco_private *priv = ndev_priv(dev); |
320 | 324 | ||
@@ -330,23 +334,115 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu) | |||
330 | 334 | ||
331 | return 0; | 335 | return 0; |
332 | } | 336 | } |
337 | EXPORT_SYMBOL(orinoco_change_mtu); | ||
333 | 338 | ||
334 | /********************************************************************/ | 339 | /********************************************************************/ |
335 | /* Tx path */ | 340 | /* Tx path */ |
336 | /********************************************************************/ | 341 | /********************************************************************/ |
337 | 342 | ||
343 | /* Add encapsulation and MIC to the existing SKB. | ||
344 | * The main xmit routine will then send the whole lot to the card. | ||
345 | * Need 8 bytes headroom | ||
346 | * Need 8 bytes tailroom | ||
347 | * | ||
348 | * With encapsulated ethernet II frame | ||
349 | * -------- | ||
350 | * 803.3 header (14 bytes) | ||
351 | * dst[6] | ||
352 | * -------- src[6] | ||
353 | * 803.3 header (14 bytes) len[2] | ||
354 | * dst[6] 803.2 header (8 bytes) | ||
355 | * src[6] encaps[6] | ||
356 | * len[2] <- leave alone -> len[2] | ||
357 | * -------- -------- <-- 0 | ||
358 | * Payload Payload | ||
359 | * ... ... | ||
360 | * | ||
361 | * -------- -------- | ||
362 | * MIC (8 bytes) | ||
363 | * -------- | ||
364 | * | ||
365 | * returns 0 on success, -ENOMEM on error. | ||
366 | */ | ||
367 | int orinoco_process_xmit_skb(struct sk_buff *skb, | ||
368 | struct net_device *dev, | ||
369 | struct orinoco_private *priv, | ||
370 | int *tx_control, | ||
371 | u8 *mic_buf) | ||
372 | { | ||
373 | struct orinoco_tkip_key *key; | ||
374 | struct ethhdr *eh; | ||
375 | int do_mic; | ||
376 | |||
377 | key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key; | ||
378 | |||
379 | do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) && | ||
380 | (key != NULL)); | ||
381 | |||
382 | if (do_mic) | ||
383 | *tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | | ||
384 | HERMES_TXCTRL_MIC; | ||
385 | |||
386 | eh = (struct ethhdr *)skb->data; | ||
387 | |||
388 | /* Encapsulate Ethernet-II frames */ | ||
389 | if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ | ||
390 | struct header_struct { | ||
391 | struct ethhdr eth; /* 802.3 header */ | ||
392 | u8 encap[6]; /* 802.2 header */ | ||
393 | } __attribute__ ((packed)) hdr; | ||
394 | int len = skb->len + sizeof(encaps_hdr) - (2 * ETH_ALEN); | ||
395 | |||
396 | if (skb_headroom(skb) < ENCAPS_OVERHEAD) { | ||
397 | if (net_ratelimit()) | ||
398 | printk(KERN_ERR | ||
399 | "%s: Not enough headroom for 802.2 headers %d\n", | ||
400 | dev->name, skb_headroom(skb)); | ||
401 | return -ENOMEM; | ||
402 | } | ||
403 | |||
404 | /* Fill in new header */ | ||
405 | memcpy(&hdr.eth, eh, 2 * ETH_ALEN); | ||
406 | hdr.eth.h_proto = htons(len); | ||
407 | memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr)); | ||
408 | |||
409 | /* Make room for the new header, and copy it in */ | ||
410 | eh = (struct ethhdr *) skb_push(skb, ENCAPS_OVERHEAD); | ||
411 | memcpy(eh, &hdr, sizeof(hdr)); | ||
412 | } | ||
413 | |||
414 | /* Calculate Michael MIC */ | ||
415 | if (do_mic) { | ||
416 | size_t len = skb->len - ETH_HLEN; | ||
417 | u8 *mic = &mic_buf[0]; | ||
418 | |||
419 | /* Have to write to an even address, so copy the spare | ||
420 | * byte across */ | ||
421 | if (skb->len % 2) { | ||
422 | *mic = skb->data[skb->len - 1]; | ||
423 | mic++; | ||
424 | } | ||
425 | |||
426 | orinoco_mic(priv->tx_tfm_mic, key->tx_mic, | ||
427 | eh->h_dest, eh->h_source, 0 /* priority */, | ||
428 | skb->data + ETH_HLEN, | ||
429 | len, mic); | ||
430 | } | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | EXPORT_SYMBOL(orinoco_process_xmit_skb); | ||
435 | |||
338 | static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | 436 | static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) |
339 | { | 437 | { |
340 | struct orinoco_private *priv = ndev_priv(dev); | 438 | struct orinoco_private *priv = ndev_priv(dev); |
341 | struct net_device_stats *stats = &priv->stats; | 439 | struct net_device_stats *stats = &priv->stats; |
342 | struct orinoco_tkip_key *key; | ||
343 | hermes_t *hw = &priv->hw; | 440 | hermes_t *hw = &priv->hw; |
344 | int err = 0; | 441 | int err = 0; |
345 | u16 txfid = priv->txfid; | 442 | u16 txfid = priv->txfid; |
346 | struct ethhdr *eh; | ||
347 | int tx_control; | 443 | int tx_control; |
348 | unsigned long flags; | 444 | unsigned long flags; |
349 | int do_mic; | 445 | u8 mic_buf[MICHAEL_MIC_LEN+1]; |
350 | 446 | ||
351 | if (!netif_running(dev)) { | 447 | if (!netif_running(dev)) { |
352 | printk(KERN_ERR "%s: Tx on stopped device!\n", | 448 | printk(KERN_ERR "%s: Tx on stopped device!\n", |
@@ -378,16 +474,12 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
378 | if (skb->len < ETH_HLEN) | 474 | if (skb->len < ETH_HLEN) |
379 | goto drop; | 475 | goto drop; |
380 | 476 | ||
381 | key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key; | ||
382 | |||
383 | do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) && | ||
384 | (key != NULL)); | ||
385 | |||
386 | tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; | 477 | tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; |
387 | 478 | ||
388 | if (do_mic) | 479 | err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control, |
389 | tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | | 480 | &mic_buf[0]); |
390 | HERMES_TXCTRL_MIC; | 481 | if (err) |
482 | goto drop; | ||
391 | 483 | ||
392 | if (priv->has_alt_txcntl) { | 484 | if (priv->has_alt_txcntl) { |
393 | /* WPA enabled firmwares have tx_cntl at the end of | 485 | /* WPA enabled firmwares have tx_cntl at the end of |
@@ -400,8 +492,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
400 | memset(&desc, 0, sizeof(desc)); | 492 | memset(&desc, 0, sizeof(desc)); |
401 | 493 | ||
402 | *txcntl = cpu_to_le16(tx_control); | 494 | *txcntl = cpu_to_le16(tx_control); |
403 | err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), | 495 | err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), |
404 | txfid, 0); | 496 | txfid, 0); |
405 | if (err) { | 497 | if (err) { |
406 | if (net_ratelimit()) | 498 | if (net_ratelimit()) |
407 | printk(KERN_ERR "%s: Error %d writing Tx " | 499 | printk(KERN_ERR "%s: Error %d writing Tx " |
@@ -414,8 +506,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
414 | memset(&desc, 0, sizeof(desc)); | 506 | memset(&desc, 0, sizeof(desc)); |
415 | 507 | ||
416 | desc.tx_control = cpu_to_le16(tx_control); | 508 | desc.tx_control = cpu_to_le16(tx_control); |
417 | err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), | 509 | err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), |
418 | txfid, 0); | 510 | txfid, 0); |
419 | if (err) { | 511 | if (err) { |
420 | if (net_ratelimit()) | 512 | if (net_ratelimit()) |
421 | printk(KERN_ERR "%s: Error %d writing Tx " | 513 | printk(KERN_ERR "%s: Error %d writing Tx " |
@@ -430,68 +522,24 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
430 | HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); | 522 | HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); |
431 | } | 523 | } |
432 | 524 | ||
433 | eh = (struct ethhdr *)skb->data; | 525 | err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len, |
434 | 526 | txfid, HERMES_802_3_OFFSET); | |
435 | /* Encapsulate Ethernet-II frames */ | ||
436 | if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ | ||
437 | struct header_struct { | ||
438 | struct ethhdr eth; /* 802.3 header */ | ||
439 | u8 encap[6]; /* 802.2 header */ | ||
440 | } __attribute__ ((packed)) hdr; | ||
441 | |||
442 | /* Strip destination and source from the data */ | ||
443 | skb_pull(skb, 2 * ETH_ALEN); | ||
444 | |||
445 | /* And move them to a separate header */ | ||
446 | memcpy(&hdr.eth, eh, 2 * ETH_ALEN); | ||
447 | hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len); | ||
448 | memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr)); | ||
449 | |||
450 | /* Insert the SNAP header */ | ||
451 | if (skb_headroom(skb) < sizeof(hdr)) { | ||
452 | printk(KERN_ERR | ||
453 | "%s: Not enough headroom for 802.2 headers %d\n", | ||
454 | dev->name, skb_headroom(skb)); | ||
455 | goto drop; | ||
456 | } | ||
457 | eh = (struct ethhdr *) skb_push(skb, sizeof(hdr)); | ||
458 | memcpy(eh, &hdr, sizeof(hdr)); | ||
459 | } | ||
460 | |||
461 | err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, | ||
462 | txfid, HERMES_802_3_OFFSET); | ||
463 | if (err) { | 527 | if (err) { |
464 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", | 528 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", |
465 | dev->name, err); | 529 | dev->name, err); |
466 | goto busy; | 530 | goto busy; |
467 | } | 531 | } |
468 | 532 | ||
469 | /* Calculate Michael MIC */ | 533 | if (tx_control & HERMES_TXCTRL_MIC) { |
470 | if (do_mic) { | 534 | size_t offset = HERMES_802_3_OFFSET + skb->len; |
471 | u8 mic_buf[MICHAEL_MIC_LEN + 1]; | 535 | size_t len = MICHAEL_MIC_LEN; |
472 | u8 *mic; | ||
473 | size_t offset; | ||
474 | size_t len; | ||
475 | 536 | ||
476 | if (skb->len % 2) { | 537 | if (offset % 2) { |
477 | /* MIC start is on an odd boundary */ | 538 | offset--; |
478 | mic_buf[0] = skb->data[skb->len - 1]; | 539 | len++; |
479 | mic = &mic_buf[1]; | ||
480 | offset = skb->len - 1; | ||
481 | len = MICHAEL_MIC_LEN + 1; | ||
482 | } else { | ||
483 | mic = &mic_buf[0]; | ||
484 | offset = skb->len; | ||
485 | len = MICHAEL_MIC_LEN; | ||
486 | } | 540 | } |
487 | 541 | err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len, | |
488 | orinoco_mic(priv->tx_tfm_mic, key->tx_mic, | 542 | txfid, offset); |
489 | eh->h_dest, eh->h_source, 0 /* priority */, | ||
490 | skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); | ||
491 | |||
492 | /* Write the MIC */ | ||
493 | err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len, | ||
494 | txfid, HERMES_802_3_OFFSET + offset); | ||
495 | if (err) { | 543 | if (err) { |
496 | printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", | 544 | printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", |
497 | dev->name, err); | 545 | dev->name, err); |
@@ -502,7 +550,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
502 | /* Finally, we actually initiate the send */ | 550 | /* Finally, we actually initiate the send */ |
503 | netif_stop_queue(dev); | 551 | netif_stop_queue(dev); |
504 | 552 | ||
505 | err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, | 553 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, |
506 | txfid, NULL); | 554 | txfid, NULL); |
507 | if (err) { | 555 | if (err) { |
508 | netif_start_queue(dev); | 556 | netif_start_queue(dev); |
@@ -512,7 +560,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
512 | goto busy; | 560 | goto busy; |
513 | } | 561 | } |
514 | 562 | ||
515 | dev->trans_start = jiffies; | ||
516 | stats->tx_bytes += HERMES_802_3_OFFSET + skb->len; | 563 | stats->tx_bytes += HERMES_802_3_OFFSET + skb->len; |
517 | goto ok; | 564 | goto ok; |
518 | 565 | ||
@@ -572,9 +619,9 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
572 | return; /* Nothing's really happened */ | 619 | return; /* Nothing's really happened */ |
573 | 620 | ||
574 | /* Read part of the frame header - we need status and addr1 */ | 621 | /* Read part of the frame header - we need status and addr1 */ |
575 | err = hermes_bap_pread(hw, IRQ_BAP, &hdr, | 622 | err = hw->ops->bap_pread(hw, IRQ_BAP, &hdr, |
576 | sizeof(struct hermes_txexc_data), | 623 | sizeof(struct hermes_txexc_data), |
577 | fid, 0); | 624 | fid, 0); |
578 | 625 | ||
579 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); | 626 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); |
580 | stats->tx_errors++; | 627 | stats->tx_errors++; |
@@ -615,7 +662,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
615 | netif_wake_queue(dev); | 662 | netif_wake_queue(dev); |
616 | } | 663 | } |
617 | 664 | ||
618 | static void orinoco_tx_timeout(struct net_device *dev) | 665 | void orinoco_tx_timeout(struct net_device *dev) |
619 | { | 666 | { |
620 | struct orinoco_private *priv = ndev_priv(dev); | 667 | struct orinoco_private *priv = ndev_priv(dev); |
621 | struct net_device_stats *stats = &priv->stats; | 668 | struct net_device_stats *stats = &priv->stats; |
@@ -630,6 +677,7 @@ static void orinoco_tx_timeout(struct net_device *dev) | |||
630 | 677 | ||
631 | schedule_work(&priv->reset_work); | 678 | schedule_work(&priv->reset_work); |
632 | } | 679 | } |
680 | EXPORT_SYMBOL(orinoco_tx_timeout); | ||
633 | 681 | ||
634 | /********************************************************************/ | 682 | /********************************************************************/ |
635 | /* Rx path (data frames) */ | 683 | /* Rx path (data frames) */ |
@@ -764,9 +812,9 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, | |||
764 | 812 | ||
765 | /* If any, copy the data from the card to the skb */ | 813 | /* If any, copy the data from the card to the skb */ |
766 | if (datalen > 0) { | 814 | if (datalen > 0) { |
767 | err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), | 815 | err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), |
768 | ALIGN(datalen, 2), rxfid, | 816 | ALIGN(datalen, 2), rxfid, |
769 | HERMES_802_2_OFFSET); | 817 | HERMES_802_2_OFFSET); |
770 | if (err) { | 818 | if (err) { |
771 | printk(KERN_ERR "%s: error %d reading monitor frame\n", | 819 | printk(KERN_ERR "%s: error %d reading monitor frame\n", |
772 | dev->name, err); | 820 | dev->name, err); |
@@ -792,7 +840,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, | |||
792 | stats->rx_dropped++; | 840 | stats->rx_dropped++; |
793 | } | 841 | } |
794 | 842 | ||
795 | static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | 843 | void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) |
796 | { | 844 | { |
797 | struct orinoco_private *priv = ndev_priv(dev); | 845 | struct orinoco_private *priv = ndev_priv(dev); |
798 | struct net_device_stats *stats = &priv->stats; | 846 | struct net_device_stats *stats = &priv->stats; |
@@ -814,8 +862,8 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | |||
814 | 862 | ||
815 | rxfid = hermes_read_regn(hw, RXFID); | 863 | rxfid = hermes_read_regn(hw, RXFID); |
816 | 864 | ||
817 | err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), | 865 | err = hw->ops->bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), |
818 | rxfid, 0); | 866 | rxfid, 0); |
819 | if (err) { | 867 | if (err) { |
820 | printk(KERN_ERR "%s: error %d reading Rx descriptor. " | 868 | printk(KERN_ERR "%s: error %d reading Rx descriptor. " |
821 | "Frame dropped.\n", dev->name, err); | 869 | "Frame dropped.\n", dev->name, err); |
@@ -882,9 +930,9 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | |||
882 | nothing is removed. 2 is for aligning the IP header. */ | 930 | nothing is removed. 2 is for aligning the IP header. */ |
883 | skb_reserve(skb, ETH_HLEN + 2); | 931 | skb_reserve(skb, ETH_HLEN + 2); |
884 | 932 | ||
885 | err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), | 933 | err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, length), |
886 | ALIGN(length, 2), rxfid, | 934 | ALIGN(length, 2), rxfid, |
887 | HERMES_802_2_OFFSET); | 935 | HERMES_802_2_OFFSET); |
888 | if (err) { | 936 | if (err) { |
889 | printk(KERN_ERR "%s: error %d reading frame. " | 937 | printk(KERN_ERR "%s: error %d reading frame. " |
890 | "Frame dropped.\n", dev->name, err); | 938 | "Frame dropped.\n", dev->name, err); |
@@ -913,6 +961,7 @@ update_stats: | |||
913 | out: | 961 | out: |
914 | kfree(desc); | 962 | kfree(desc); |
915 | } | 963 | } |
964 | EXPORT_SYMBOL(__orinoco_ev_rx); | ||
916 | 965 | ||
917 | static void orinoco_rx(struct net_device *dev, | 966 | static void orinoco_rx(struct net_device *dev, |
918 | struct hermes_rx_descriptor *desc, | 967 | struct hermes_rx_descriptor *desc, |
@@ -1145,9 +1194,9 @@ static void orinoco_join_ap(struct work_struct *work) | |||
1145 | goto out; | 1194 | goto out; |
1146 | 1195 | ||
1147 | /* Read scan results from the firmware */ | 1196 | /* Read scan results from the firmware */ |
1148 | err = hermes_read_ltv(hw, USER_BAP, | 1197 | err = hw->ops->read_ltv(hw, USER_BAP, |
1149 | HERMES_RID_SCANRESULTSTABLE, | 1198 | HERMES_RID_SCANRESULTSTABLE, |
1150 | MAX_SCAN_LEN, &len, buf); | 1199 | MAX_SCAN_LEN, &len, buf); |
1151 | if (err) { | 1200 | if (err) { |
1152 | printk(KERN_ERR "%s: Cannot read scan results\n", | 1201 | printk(KERN_ERR "%s: Cannot read scan results\n", |
1153 | dev->name); | 1202 | dev->name); |
@@ -1194,8 +1243,8 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv) | |||
1194 | union iwreq_data wrqu; | 1243 | union iwreq_data wrqu; |
1195 | int err; | 1244 | int err; |
1196 | 1245 | ||
1197 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, | 1246 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, |
1198 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); | 1247 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); |
1199 | if (err != 0) | 1248 | if (err != 0) |
1200 | return; | 1249 | return; |
1201 | 1250 | ||
@@ -1217,8 +1266,8 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv) | |||
1217 | if (!priv->has_wpa) | 1266 | if (!priv->has_wpa) |
1218 | return; | 1267 | return; |
1219 | 1268 | ||
1220 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, | 1269 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, |
1221 | sizeof(buf), NULL, &buf); | 1270 | sizeof(buf), NULL, &buf); |
1222 | if (err != 0) | 1271 | if (err != 0) |
1223 | return; | 1272 | return; |
1224 | 1273 | ||
@@ -1247,8 +1296,9 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv) | |||
1247 | if (!priv->has_wpa) | 1296 | if (!priv->has_wpa) |
1248 | return; | 1297 | return; |
1249 | 1298 | ||
1250 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO, | 1299 | err = hw->ops->read_ltv(hw, USER_BAP, |
1251 | sizeof(buf), NULL, &buf); | 1300 | HERMES_RID_CURRENT_ASSOC_RESP_INFO, |
1301 | sizeof(buf), NULL, &buf); | ||
1252 | if (err != 0) | 1302 | if (err != 0) |
1253 | return; | 1303 | return; |
1254 | 1304 | ||
@@ -1353,7 +1403,7 @@ static void orinoco_process_scan_results(struct work_struct *work) | |||
1353 | spin_unlock_irqrestore(&priv->scan_lock, flags); | 1403 | spin_unlock_irqrestore(&priv->scan_lock, flags); |
1354 | } | 1404 | } |
1355 | 1405 | ||
1356 | static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | 1406 | void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) |
1357 | { | 1407 | { |
1358 | struct orinoco_private *priv = ndev_priv(dev); | 1408 | struct orinoco_private *priv = ndev_priv(dev); |
1359 | u16 infofid; | 1409 | u16 infofid; |
@@ -1371,8 +1421,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1371 | infofid = hermes_read_regn(hw, INFOFID); | 1421 | infofid = hermes_read_regn(hw, INFOFID); |
1372 | 1422 | ||
1373 | /* Read the info frame header - don't try too hard */ | 1423 | /* Read the info frame header - don't try too hard */ |
1374 | err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), | 1424 | err = hw->ops->bap_pread(hw, IRQ_BAP, &info, sizeof(info), |
1375 | infofid, 0); | 1425 | infofid, 0); |
1376 | if (err) { | 1426 | if (err) { |
1377 | printk(KERN_ERR "%s: error %d reading info frame. " | 1427 | printk(KERN_ERR "%s: error %d reading info frame. " |
1378 | "Frame dropped.\n", dev->name, err); | 1428 | "Frame dropped.\n", dev->name, err); |
@@ -1393,8 +1443,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1393 | len = sizeof(tallies); | 1443 | len = sizeof(tallies); |
1394 | } | 1444 | } |
1395 | 1445 | ||
1396 | err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, | 1446 | err = hw->ops->bap_pread(hw, IRQ_BAP, &tallies, len, |
1397 | infofid, sizeof(info)); | 1447 | infofid, sizeof(info)); |
1398 | if (err) | 1448 | if (err) |
1399 | break; | 1449 | break; |
1400 | 1450 | ||
@@ -1429,8 +1479,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1429 | break; | 1479 | break; |
1430 | } | 1480 | } |
1431 | 1481 | ||
1432 | err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, | 1482 | err = hw->ops->bap_pread(hw, IRQ_BAP, &linkstatus, len, |
1433 | infofid, sizeof(info)); | 1483 | infofid, sizeof(info)); |
1434 | if (err) | 1484 | if (err) |
1435 | break; | 1485 | break; |
1436 | newstatus = le16_to_cpu(linkstatus.linkstatus); | 1486 | newstatus = le16_to_cpu(linkstatus.linkstatus); |
@@ -1494,8 +1544,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1494 | } | 1544 | } |
1495 | 1545 | ||
1496 | /* Read scan data */ | 1546 | /* Read scan data */ |
1497 | err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, | 1547 | err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) buf, len, |
1498 | infofid, sizeof(info)); | 1548 | infofid, sizeof(info)); |
1499 | if (err) { | 1549 | if (err) { |
1500 | kfree(buf); | 1550 | kfree(buf); |
1501 | qabort_scan(priv); | 1551 | qabort_scan(priv); |
@@ -1547,8 +1597,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1547 | break; | 1597 | break; |
1548 | 1598 | ||
1549 | /* Read scan data */ | 1599 | /* Read scan data */ |
1550 | err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len, | 1600 | err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) bss, len, |
1551 | infofid, sizeof(info)); | 1601 | infofid, sizeof(info)); |
1552 | if (err) | 1602 | if (err) |
1553 | kfree(bss); | 1603 | kfree(bss); |
1554 | else | 1604 | else |
@@ -1568,9 +1618,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1568 | /* We don't actually do anything about it */ | 1618 | /* We don't actually do anything about it */ |
1569 | break; | 1619 | break; |
1570 | } | 1620 | } |
1571 | |||
1572 | return; | ||
1573 | } | 1621 | } |
1622 | EXPORT_SYMBOL(__orinoco_ev_info); | ||
1574 | 1623 | ||
1575 | static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) | 1624 | static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) |
1576 | { | 1625 | { |
@@ -1647,7 +1696,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv) | |||
1647 | struct hermes *hw = &priv->hw; | 1696 | struct hermes *hw = &priv->hw; |
1648 | int err; | 1697 | int err; |
1649 | 1698 | ||
1650 | err = hermes_init(hw); | 1699 | err = hw->ops->init(hw); |
1651 | if (priv->do_fw_download && !err) { | 1700 | if (priv->do_fw_download && !err) { |
1652 | err = orinoco_download(priv); | 1701 | err = orinoco_download(priv); |
1653 | if (err) | 1702 | if (err) |
@@ -1735,7 +1784,7 @@ void orinoco_reset(struct work_struct *work) | |||
1735 | } | 1784 | } |
1736 | 1785 | ||
1737 | /* This has to be called from user context */ | 1786 | /* This has to be called from user context */ |
1738 | spin_lock_irq(&priv->lock); | 1787 | orinoco_lock_irq(priv); |
1739 | 1788 | ||
1740 | priv->hw_unavailable--; | 1789 | priv->hw_unavailable--; |
1741 | 1790 | ||
@@ -1750,7 +1799,7 @@ void orinoco_reset(struct work_struct *work) | |||
1750 | dev->trans_start = jiffies; | 1799 | dev->trans_start = jiffies; |
1751 | } | 1800 | } |
1752 | 1801 | ||
1753 | spin_unlock_irq(&priv->lock); | 1802 | orinoco_unlock_irq(priv); |
1754 | 1803 | ||
1755 | return; | 1804 | return; |
1756 | disable: | 1805 | disable: |
@@ -1984,7 +2033,7 @@ int orinoco_init(struct orinoco_private *priv) | |||
1984 | priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; | 2033 | priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; |
1985 | 2034 | ||
1986 | /* Initialize the firmware */ | 2035 | /* Initialize the firmware */ |
1987 | err = hermes_init(hw); | 2036 | err = hw->ops->init(hw); |
1988 | if (err != 0) { | 2037 | if (err != 0) { |
1989 | dev_err(dev, "Failed to initialize firmware (err = %d)\n", | 2038 | dev_err(dev, "Failed to initialize firmware (err = %d)\n", |
1990 | err); | 2039 | err); |
@@ -2067,9 +2116,9 @@ int orinoco_init(struct orinoco_private *priv) | |||
2067 | 2116 | ||
2068 | /* Make the hardware available, as long as it hasn't been | 2117 | /* Make the hardware available, as long as it hasn't been |
2069 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ | 2118 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ |
2070 | spin_lock_irq(&priv->lock); | 2119 | orinoco_lock_irq(priv); |
2071 | priv->hw_unavailable--; | 2120 | priv->hw_unavailable--; |
2072 | spin_unlock_irq(&priv->lock); | 2121 | orinoco_unlock_irq(priv); |
2073 | 2122 | ||
2074 | dev_dbg(dev, "Ready\n"); | 2123 | dev_dbg(dev, "Ready\n"); |
2075 | 2124 | ||
@@ -2192,7 +2241,8 @@ EXPORT_SYMBOL(alloc_orinocodev); | |||
2192 | */ | 2241 | */ |
2193 | int orinoco_if_add(struct orinoco_private *priv, | 2242 | int orinoco_if_add(struct orinoco_private *priv, |
2194 | unsigned long base_addr, | 2243 | unsigned long base_addr, |
2195 | unsigned int irq) | 2244 | unsigned int irq, |
2245 | const struct net_device_ops *ops) | ||
2196 | { | 2246 | { |
2197 | struct wiphy *wiphy = priv_to_wiphy(priv); | 2247 | struct wiphy *wiphy = priv_to_wiphy(priv); |
2198 | struct wireless_dev *wdev; | 2248 | struct wireless_dev *wdev; |
@@ -2211,16 +2261,21 @@ int orinoco_if_add(struct orinoco_private *priv, | |||
2211 | 2261 | ||
2212 | /* Setup / override net_device fields */ | 2262 | /* Setup / override net_device fields */ |
2213 | dev->ieee80211_ptr = wdev; | 2263 | dev->ieee80211_ptr = wdev; |
2214 | dev->netdev_ops = &orinoco_netdev_ops; | ||
2215 | dev->watchdog_timeo = HZ; /* 1 second timeout */ | 2264 | dev->watchdog_timeo = HZ; /* 1 second timeout */ |
2216 | dev->wireless_handlers = &orinoco_handler_def; | 2265 | dev->wireless_handlers = &orinoco_handler_def; |
2217 | #ifdef WIRELESS_SPY | 2266 | #ifdef WIRELESS_SPY |
2218 | dev->wireless_data = &priv->wireless_data; | 2267 | dev->wireless_data = &priv->wireless_data; |
2219 | #endif | 2268 | #endif |
2269 | /* Default to standard ops if not set */ | ||
2270 | if (ops) | ||
2271 | dev->netdev_ops = ops; | ||
2272 | else | ||
2273 | dev->netdev_ops = &orinoco_netdev_ops; | ||
2274 | |||
2220 | /* we use the default eth_mac_addr for setting the MAC addr */ | 2275 | /* we use the default eth_mac_addr for setting the MAC addr */ |
2221 | 2276 | ||
2222 | /* Reserve space in skb for the SNAP header */ | 2277 | /* Reserve space in skb for the SNAP header */ |
2223 | dev->hard_header_len += ENCAPS_OVERHEAD; | 2278 | dev->needed_headroom = ENCAPS_OVERHEAD; |
2224 | 2279 | ||
2225 | netif_carrier_off(dev); | 2280 | netif_carrier_off(dev); |
2226 | 2281 | ||
@@ -2305,7 +2360,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2305 | unsigned long flags; | 2360 | unsigned long flags; |
2306 | int err; | 2361 | int err; |
2307 | 2362 | ||
2308 | spin_lock_irqsave(&priv->lock, flags); | 2363 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2309 | 2364 | ||
2310 | err = orinoco_reinit_firmware(priv); | 2365 | err = orinoco_reinit_firmware(priv); |
2311 | if (err) { | 2366 | if (err) { |
@@ -2325,7 +2380,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2325 | } | 2380 | } |
2326 | 2381 | ||
2327 | exit: | 2382 | exit: |
2328 | spin_unlock_irqrestore(&priv->lock, flags); | 2383 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2329 | 2384 | ||
2330 | return 0; | 2385 | return 0; |
2331 | } | 2386 | } |
@@ -2337,7 +2392,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2337 | unsigned long flags; | 2392 | unsigned long flags; |
2338 | int err; | 2393 | int err; |
2339 | 2394 | ||
2340 | spin_lock_irqsave(&priv->lock, flags); | 2395 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2341 | err = __orinoco_down(priv); | 2396 | err = __orinoco_down(priv); |
2342 | if (err) | 2397 | if (err) |
2343 | printk(KERN_WARNING "%s: Error %d downing interface\n", | 2398 | printk(KERN_WARNING "%s: Error %d downing interface\n", |
@@ -2345,7 +2400,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2345 | 2400 | ||
2346 | netif_device_detach(dev); | 2401 | netif_device_detach(dev); |
2347 | priv->hw_unavailable++; | 2402 | priv->hw_unavailable++; |
2348 | spin_unlock_irqrestore(&priv->lock, flags); | 2403 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2349 | } | 2404 | } |
2350 | EXPORT_SYMBOL(orinoco_down); | 2405 | EXPORT_SYMBOL(orinoco_down); |
2351 | 2406 | ||