rx_status.flag = 0;
        rx_status.mactime = le64_to_cpu(rx_end->timestamp);
-       rx_status.freq =
-               ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
        rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
                                IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+       rx_status.freq =
+               ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel),
+                                              rx_status.band);
 
        rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
        if (rx_status.band == IEEE80211_BAND_5GHZ)
 
 
        /* rx_status carries information about the packet to mac80211 */
        rx_status.mactime = le64_to_cpu(phy_res->timestamp);
-       rx_status.freq =
-               ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
        rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
                                IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+       rx_status.freq =
+               ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
+                                              rx_status.band);
        rx_status.rate_idx =
                iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
        rx_status.flag = 0;
 
                geo_ch = &sband->channels[sband->n_channels++];
 
                geo_ch->center_freq =
-                               ieee80211_channel_to_frequency(ch->channel);
+                               ieee80211_channel_to_frequency(ch->channel,
+                                                              sband->band);
                geo_ch->max_power = ch->max_power_avg;
                geo_ch->max_antenna_gain = 0xff;
                geo_ch->hw_value = ch->channel;
 
                        return -EINVAL;
                }
 
-               freq = ieee80211_channel_to_frequency(umac_bss->channel);
+               freq = ieee80211_channel_to_frequency(umac_bss->channel,
+                                                     band->band);
                channel = ieee80211_get_channel(wiphy, freq);
                signal = umac_bss->rssi * 100;
 
 
        switch (le32_to_cpu(complete->status)) {
        case UMAC_ASSOC_COMPLETE_SUCCESS:
                chan = ieee80211_get_channel(wiphy,
-                       ieee80211_channel_to_frequency(complete->channel));
+                       ieee80211_channel_to_frequency(complete->channel,
+                               complete->band == UMAC_BAND_2GHZ ?
+                                       IEEE80211_BAND_2GHZ :
+                                       IEEE80211_BAND_5GHZ));
                if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
                        /* Associated to a unallowed channel, disassociate. */
                        __iwm_invalidate_mlme_profile(iwm);
                goto err;
        }
 
-       freq = ieee80211_channel_to_frequency(umac_bss->channel);
+       freq = ieee80211_channel_to_frequency(umac_bss->channel, band->band);
        channel = ieee80211_get_channel(wiphy, freq);
        signal = umac_bss->rssi * 100;
 
 
                /* No channel, no luck */
                if (chan_no != -1) {
                        struct wiphy *wiphy = priv->wdev->wiphy;
-                       int freq = ieee80211_channel_to_frequency(chan_no);
+                       int freq = ieee80211_channel_to_frequency(chan_no,
+                                                       IEEE80211_BAND_2GHZ);
                        struct ieee80211_channel *channel =
                                ieee80211_get_channel(wiphy, freq);
 
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        survey->channel = ieee80211_get_channel(wiphy,
-               ieee80211_channel_to_frequency(priv->channel));
+               ieee80211_channel_to_frequency(priv->channel,
+                                              IEEE80211_BAND_2GHZ));
 
        ret = lbs_get_rssi(priv, &signal, &noise);
        if (ret == 0) {
 
        } else {
                status->band = IEEE80211_BAND_2GHZ;
        }
-       status->freq = ieee80211_channel_to_frequency(rxd->channel);
+       status->freq = ieee80211_channel_to_frequency(rxd->channel,
+                                                     status->band);
 
        *qos = rxd->qos_control;
 
        } else {
                status->band = IEEE80211_BAND_2GHZ;
        }
-       status->freq = ieee80211_channel_to_frequency(rxd->channel);
+       status->freq = ieee80211_channel_to_frequency(rxd->channel,
+                                                     status->band);
 
        *qos = rxd->qos_control;
        if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) &&
 
                              const int channel, const int tx_power,
                              const int value)
 {
-       entry->center_freq = ieee80211_channel_to_frequency(channel);
+       /* XXX: this assumption about the band is wrong for 802.11j */
+       entry->band = channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+       entry->center_freq = ieee80211_channel_to_frequency(channel,
+                                                           entry->band);
        entry->hw_value = value;
        entry->max_power = tx_power;
        entry->max_antenna_gain = 0xff;
 
         */
        wl->noise = desc->rssi - desc->snr / 2;
 
-       status->freq = ieee80211_channel_to_frequency(desc->channel);
+       status->freq = ieee80211_channel_to_frequency(desc->channel,
+                                                     status->band);
 
        status->flag |= RX_FLAG_TSFT;
 
 
         */
        wl->noise = desc->rssi - (desc->snr >> 1);
 
-       status->freq = ieee80211_channel_to_frequency(desc->channel);
+       status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);
 
        if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
                status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
 
 /**
  * ieee80211_channel_to_frequency - convert channel number to frequency
  * @chan: channel number
+ * @band: band, necessary due to channel number overlap
  */
-extern int ieee80211_channel_to_frequency(int chan);
+extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);
 
 /**
  * ieee80211_frequency_to_channel - convert frequency to channel number
 
        enum ieee80211_band band = rx_status->band;
 
        if (elems->ds_params && elems->ds_params_len == 1)
-               freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
+               freq = ieee80211_channel_to_frequency(elems->ds_params[0],
+                                                     band);
        else
                freq = rx_status->freq;
 
 
                               &elems);
 
        if (elems.ds_params && elems.ds_params_len == 1)
-               freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
+               freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
        else
                freq = rx_status->freq;
 
 
 
        /* check that channel matches the right operating channel */
        if (local->hw.conf.channel->center_freq !=
-           ieee80211_channel_to_frequency(hti->control_chan))
+           ieee80211_channel_to_frequency(hti->control_chan, sband->band))
                enable_ht = false;
 
        if (enable_ht) {
                container_of((void *)bss, struct cfg80211_bss, priv);
        struct ieee80211_channel *new_ch;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
+       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
+                                                     cbss->channel->band);
 
        ASSERT_MGD_MTX(ifmgd);
 
        }
 
        if (elems->ds_params && elems->ds_params_len == 1)
-               freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
+               freq = ieee80211_channel_to_frequency(elems->ds_params[0],
+                                                     rx_status->band);
        else
                freq = rx_status->freq;
 
 
        ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
 
        if (elems.ds_params && elems.ds_params_len == 1)
-               freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
+               freq = ieee80211_channel_to_frequency(elems.ds_params[0],
+                                                     rx_status->band);
        else
                freq = rx_status->freq;
 
 
 
 static bool freq_is_chan_12_13_14(u16 freq)
 {
-       if (freq == ieee80211_channel_to_frequency(12) ||
-           freq == ieee80211_channel_to_frequency(13) ||
-           freq == ieee80211_channel_to_frequency(14))
+       if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
+           freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
+           freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
                return true;
        return false;
 }
 
 }
 EXPORT_SYMBOL(ieee80211_get_response_rate);
 
-int ieee80211_channel_to_frequency(int chan)
+int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
 {
-       if (chan < 14)
-               return 2407 + chan * 5;
-
-       if (chan == 14)
-               return 2484;
-
-       /* FIXME: 802.11j 17.3.8.3.2 */
-       return (chan + 1000) * 5;
+       /* see 802.11 17.3.8.3.2 and Annex J
+        * there are overlapping channel numbers in 5GHz and 2GHz bands */
+       if (band == IEEE80211_BAND_5GHZ) {
+               if (chan >= 182 && chan <= 196)
+                       return 4000 + chan * 5;
+               else
+                       return 5000 + chan * 5;
+       } else { /* IEEE80211_BAND_2GHZ */
+               if (chan == 14)
+                       return 2484;
+               else if (chan < 14)
+                       return 2407 + chan * 5;
+               else
+                       return 0; /* not supported */
+       }
 }
 EXPORT_SYMBOL(ieee80211_channel_to_frequency);
 
 int ieee80211_frequency_to_channel(int freq)
 {
+       /* see 802.11 17.3.8.3.2 and Annex J */
        if (freq == 2484)
                return 14;
-
-       if (freq < 2484)
+       else if (freq < 2484)
                return (freq - 2407) / 5;
-
-       /* FIXME: 802.11j 17.3.8.3.2 */
-       return freq/5 - 1000;
+       else if (freq >= 4910 && freq <= 4980)
+               return (freq - 4000) / 5;
+       else
+               return (freq - 5000) / 5;
 }
 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
 
 
         * -EINVAL for impossible things.
         */
        if (freq->e == 0) {
+               enum ieee80211_band band = IEEE80211_BAND_2GHZ;
                if (freq->m < 0)
                        return 0;
-               return ieee80211_channel_to_frequency(freq->m);
+               if (freq->m > 14)
+                       band = IEEE80211_BAND_5GHZ;
+               return ieee80211_channel_to_frequency(freq->m, band);
        } else {
                int i, div = 1000000;
                for (i = 0; i < freq->e; i++)