Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0300b3321d9ed73a0c3f575f2df250c577852356
Commit:     0300b3321d9ed73a0c3f575f2df250c577852356
Parent:     851b3e5e3de0feea7bfee634f99a940648de58c8
Author:     Al Viro <[EMAIL PROTECTED]>
AuthorDate: Wed Dec 19 22:38:33 2007 -0500
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 15:08:50 2008 -0800

    airo: bug in airo_interrupt() handling on incoming 802.11
    
    On big-endian we end up with swapped first two bytes in packet,
    due to earlier conversion to host-endian and forgotten conversion
    back.
    
    The code we calculated that host-endian for had been duplicated
    several time - it finds the 802.11 MAC header length by the first
    two bytes of packet; taken into a new helper (header_len(__le16 ctl)).
    
    Signed-off-by: Al Viro <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
 drivers/net/wireless/airo.c |   74 +++++++++++++-----------------------------
 1 files changed, 23 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 6d4cc68..9d3f335 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -3177,6 +3177,21 @@ static int airo_thread(void *data) {
        return 0;
 }
 
+static int header_len(__le16 ctl)
+{
+       u16 fc = le16_to_cpu(ctl);
+       switch (fc & 0xc) {
+       case 4:
+               if ((fc & 0xe0) == 0xc0)
+                       return 10;      /* one-address control packet */
+               return 16;      /* two-address control packet */
+       case 8:
+               if ((fc & 0x300) == 0x300)
+                       return 30;      /* WDS packet */
+       }
+       return 24;
+}
+
 static irqreturn_t airo_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
@@ -3330,23 +3345,8 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id)
                                goto badrx;
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
-                               bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
-                               fc = le16_to_cpu(fc);
-                               switch (fc & 0xc) {
-                                       case 4:
-                                               if ((fc & 0xe0) == 0xc0)
-                                                       hdrlen = 10;
-                                               else
-                                                       hdrlen = 16;
-                                               break;
-                                       case 8:
-                                               if ((fc&0x300)==0x300){
-                                                       hdrlen = 30;
-                                                       break;
-                                               }
-                                       default:
-                                               hdrlen = 24;
-                               }
+                               bap_read (apriv, &fc, sizeof(fc), BAP0);
+                               hdrlen = header_len(fc);
                        } else
                                hdrlen = ETH_ALEN * 2;
 
@@ -3677,7 +3677,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
 {
        RxFid rxd;
        struct sk_buff *skb = NULL;
-       u16 fc, len, hdrlen = 0;
+       u16 len, hdrlen = 0;
+       __le16 fc;
 #pragma pack(1)
        struct {
                u16 status, len;
@@ -3707,23 +3708,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
        if (len == 0)
                goto badrx;
 
-       memcpy ((char *)&fc, ptr, sizeof(fc));
-       fc = le16_to_cpu(fc);
-       switch (fc & 0xc) {
-               case 4:
-                       if ((fc & 0xe0) == 0xc0)
-                               hdrlen = 10;
-                       else
-                               hdrlen = 16;
-                       break;
-               case 8:
-                       if ((fc&0x300)==0x300){
-                               hdrlen = 30;
-                               break;
-                       }
-               default:
-                       hdrlen = 24;
-       }
+       fc = get_unaligned((__le16 *)ptr);
+       hdrlen = header_len(fc);
 
        skb = dev_alloc_skb( len + hdrlen + 2 );
        if ( !skb ) {
@@ -4370,22 +4356,8 @@ static int transmit_802_11_packet(struct airo_info *ai, 
int len, char *pPacket)
        u16 txFid = len;
        len >>= 16;
 
-       fc = le16_to_cpu(*(const u16*)pPacket);
-       switch (fc & 0xc) {
-               case 4:
-                       if ((fc & 0xe0) == 0xc0)
-                               hdrlen = 10;
-                       else
-                               hdrlen = 16;
-                       break;
-               case 8:
-                       if ((fc&0x300)==0x300){
-                               hdrlen = 30;
-                               break;
-                       }
-               default:
-                       hdrlen = 24;
-       }
+       fc = *(__le16*)pPacket;
+       hdrlen = header_len(fc);
 
        if (len < hdrlen) {
                airo_print_warn(ai->dev->name, "Short packet %d", len);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to