Author: adrian
Date: Mon Oct  3 16:30:18 2011
New Revision: 225941
URL: http://svn.freebsd.org/changeset/base/225941

Log:
  Fix an unaligned access issue; tidy up OFDM/DS rate decoding from the PLCP.
  
  This fixes a panic on PPC.
  
  Submitted by: novel
  Obtained from:        OpenBSD, sys/dev/ic/bwi.c r1.89

Modified:
  head/sys/dev/bwi/if_bwi.c

Modified: head/sys/dev/bwi/if_bwi.c
==============================================================================
--- head/sys/dev/bwi/if_bwi.c   Mon Oct  3 16:23:20 2011        (r225940)
+++ head/sys/dev/bwi/if_bwi.c   Mon Oct  3 16:30:18 2011        (r225941)
@@ -118,8 +118,7 @@ static void bwi_calibrate(void *);
 
 static int     bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
 static int     bwi_calc_noise(struct bwi_softc *);
-static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
-static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
+static __inline uint8_t bwi_plcp2rate(uint32_t, enum ieee80211_phymode);
 static void    bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
                        struct bwi_rxbuf_hdr *, const void *, int, int, int);
 
@@ -2629,7 +2628,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_
                struct ieee80211_frame_min *wh;
                struct ieee80211_node *ni;
                struct mbuf *m;
-               const void *plcp;
+               uint32_t plcp;
                uint16_t flags2;
                int buflen, wh_ofs, hdr_extra, rssi, noise, type, rate;
 
@@ -2659,7 +2658,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_
                        goto next;
                }
 
-               plcp = ((const uint8_t *)(hdr + 1) + hdr_extra);
+               bcopy((uint8_t *)(hdr + 1) + hdr_extra, &plcp, sizeof(plcp));   
                rssi = bwi_calc_rssi(sc, hdr);
                noise = bwi_calc_noise(sc);
 
@@ -2668,13 +2667,13 @@ bwi_rxeof(struct bwi_softc *sc, int end_
                m_adj(m, sizeof(*hdr) + wh_ofs);
 
                if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
-                       rate = bwi_ofdm_plcp2rate(plcp);
+                       rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11G);
                else
-                       rate = bwi_ds_plcp2rate(plcp);
+                       rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11B);
 
                /* RX radio tap */
                if (ieee80211_radiotap_active(ic))
-                       bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi, noise);
+                       bwi_rx_radiotap(sc, m, hdr, &plcp, rate, rssi, noise);
 
                m_adj(m, -IEEE80211_CRC_LEN);
 
@@ -3802,20 +3801,10 @@ bwi_calc_noise(struct bwi_softc *sc)
 }
 
 static __inline uint8_t
-bwi_ofdm_plcp2rate(const uint32_t *plcp0)
+bwi_plcp2rate(const uint32_t plcp0, enum ieee80211_phymode phymode)
 {
-       uint32_t plcp;
-       uint8_t plcp_rate;
-
-       plcp = le32toh(*plcp0);
-       plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK);
-       return ieee80211_plcp2rate(plcp_rate, IEEE80211_T_OFDM);
-}
-
-static __inline uint8_t
-bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr)
-{
-       return ieee80211_plcp2rate(hdr->i_signal, IEEE80211_T_DS);
+       uint32_t plcp = le32toh(plcp0) & IEEE80211_OFDM_PLCP_RATE_MASK;
+       return (ieee80211_plcp2rate(plcp, phymode));
 }
 
 static void
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to