]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/libertas/scan.c
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / libertas / scan.c
index 8aaac5f6c9dec47739be8ac385424933db72a27c..c3043dcb541ea0c1cb129f0b1a8d9988ebf56cc2 100644 (file)
@@ -59,8 +59,8 @@
 //! Scan time specified in the channel TLV for each channel for active scans
 #define MRVDRV_ACTIVE_SCAN_CHAN_TIME   100
 
-const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
 static inline void clear_bss_descriptor (struct bss_descriptor * bss)
 {
@@ -99,7 +99,6 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
 {
        if (  !secinfo->wep_enabled
           && secinfo->WPAenabled
-          && !secinfo->WPA2enabled
           && (match_bss->wpa_ie[0] == WPA_IE)
           /* privacy bit may NOT be set in some APs like LinkSys WRT54G
              && bss->privacy */
@@ -113,7 +112,6 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
                        struct bss_descriptor * match_bss)
 {
        if (  !secinfo->wep_enabled
-          && !secinfo->WPAenabled
           && secinfo->WPA2enabled
           && (match_bss->rsn_ie[0] == WPA2_IE)
           /* privacy bit may NOT be set in some APs like LinkSys WRT54G
@@ -216,37 +214,6 @@ done:
        return matched;
 }
 
-/**
- *  @brief Post process the scan table after a new scan command has completed
- *
- *  Inspect each entry of the scan table and try to find an entry that
- *    matches our current associated/joined network from the scan.  If
- *    one is found, update the stored copy of the bssdescriptor for our
- *    current network.
- *
- *  Debug dump the current scan table contents if compiled accordingly.
- *
- *  @param priv   A pointer to wlan_private structure
- *
- *  @return       void
- */
-static void wlan_scan_process_results(wlan_private * priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       struct bss_descriptor * iter_bss;
-
-       if (adapter->connect_status == libertas_connected)
-               return;
-
-       mutex_lock(&adapter->lock);
-       list_for_each_entry (iter_bss, &adapter->network_list, list) {
-               lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
-                      i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi,
-                      iter_bss->ssid.ssid);
-       }
-       mutex_unlock(&adapter->lock);
-}
-
 /**
  *  @brief Create a channel list for the driver to scan based on region info
  *
@@ -325,14 +292,12 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
 
                        if (scantype == cmd_scan_type_passive) {
                                scanchanlist[chanidx].maxscantime =
-                                   cpu_to_le16
-                                   (MRVDRV_PASSIVE_SCAN_CHAN_TIME);
+                                   cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
                                scanchanlist[chanidx].chanscanmode.passivescan =
                                    1;
                        } else {
                                scanchanlist[chanidx].maxscantime =
-                                   cpu_to_le16
-                                   (MRVDRV_ACTIVE_SCAN_CHAN_TIME);
+                                   cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
                                scanchanlist[chanidx].chanscanmode.passivescan =
                                    0;
                        }
@@ -489,16 +454,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
        /* If the input config or adapter has the number of Probes set, add tlv */
        if (numprobes) {
                pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
-               pnumprobestlv->header.type =
-                   cpu_to_le16(TLV_TYPE_NUMPROBES);
-               pnumprobestlv->header.len = sizeof(pnumprobestlv->numprobes);
+               pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
+               pnumprobestlv->header.len = cpu_to_le16(2);
                pnumprobestlv->numprobes = cpu_to_le16(numprobes);
 
-               ptlvpos +=
-                   sizeof(pnumprobestlv->header) + pnumprobestlv->header.len;
-
-               pnumprobestlv->header.len =
-                   cpu_to_le16(pnumprobestlv->header.len);
+               ptlvpos += sizeof(*pnumprobestlv);
        }
 
        /*
@@ -657,8 +617,11 @@ static int wlan_scan_channel_list(wlan_private * priv,
                               ptmpchan, sizeof(pchantlvout->chanscanparam));
 
                        /* Increment the TLV header length by the size appended */
-                       pchantlvout->header.len +=
-                           sizeof(pchantlvout->chanscanparam);
+                       /* Ew, it would be _so_ nice if we could just declare the
+                          variable little-endian and let GCC handle it for us */
+                       pchantlvout->header.len =
+                               cpu_to_le16(le16_to_cpu(pchantlvout->header.len) +
+                                           sizeof(pchantlvout->chanscanparam));
 
                        /*
                         *  The tlv buffer length is set to the number of bytes of the
@@ -672,7 +635,7 @@ static int wlan_scan_channel_list(wlan_private * priv,
                        /*  Add the size of the channel tlv header and the data length */
                        pscancfgout->tlvbufferlen +=
                            (sizeof(pchantlvout->header)
-                            + pchantlvout->header.len);
+                            + le16_to_cpu(pchantlvout->header.len));
 
                        /* Increment the index to the channel tlv we are constructing */
                        tlvidx++;
@@ -707,19 +670,19 @@ static int wlan_scan_channel_list(wlan_private * priv,
                ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0,
                                            0, 0, pscancfgout);
                if (scanned >= 2 && !full_scan) {
-                       priv->adapter->last_scanned_channel = ptmpchan->channumber;
                        ret = 0;
                        goto done;
                }
                scanned = 0;
        }
 
+done:
        priv->adapter->last_scanned_channel = ptmpchan->channumber;
 
+       /* Tell userspace the scan table has been updated */
        memset(&wrqu, 0, sizeof(union iwreq_data));
        wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
 
-done:
        lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
        return ret;
 }
@@ -753,8 +716,8 @@ clear_selected_scan_list_entries(wlan_adapter * adapter,
 
                /* Check for an SSID match */
                if (   clear_ssid_flag
-                   && (bss->ssid.ssidlength == scan_cfg->ssid_len)
-                   && !memcmp(bss->ssid.ssid, scan_cfg->ssid, bss->ssid.ssidlength))
+                   && (bss->ssid_len == scan_cfg->ssid_len)
+                   && !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len))
                        clear = 1;
 
                /* Check for a BSSID match */
@@ -796,6 +759,10 @@ int wlan_scan_networks(wlan_private * priv,
        u8 scancurrentchanonly;
        int maxchanperscan;
        int ret;
+#ifdef CONFIG_LIBERTAS_DEBUG
+       struct bss_descriptor * iter_bss;
+       int i = 0;
+#endif
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
@@ -837,11 +804,16 @@ int wlan_scan_networks(wlan_private * priv,
                                     puserscanin,
                                     full_scan);
 
-       /*  Process the resulting scan table:
-        *    - Remove any bad ssids
-        *    - Update our current BSS information from scan data
-        */
-       wlan_scan_process_results(priv);
+#ifdef CONFIG_LIBERTAS_DEBUG
+       /* Dump the scan table */
+       mutex_lock(&adapter->lock);
+       list_for_each_entry (iter_bss, &adapter->network_list, list) {
+               lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
+                      i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi,
+                      escape_essid(iter_bss->ssid, iter_bss->ssid_len));
+       }
+       mutex_unlock(&adapter->lock);
+#endif
 
        if (priv->adapter->connect_status == libertas_connected) {
                netif_carrier_on(priv->dev);
@@ -957,8 +929,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
        if (*bytesleft >= sizeof(beaconsize)) {
                /* Extract & convert beacon size from the command buffer */
-               memcpy(&beaconsize, *pbeaconinfo, sizeof(beaconsize));
-               beaconsize = le16_to_cpu(beaconsize);
+               beaconsize = le16_to_cpup((void *)*pbeaconinfo);
                *bytesleft -= sizeof(beaconsize);
                *pbeaconinfo += sizeof(beaconsize);
        }
@@ -997,28 +968,25 @@ static int libertas_process_bss(struct bss_descriptor * bss,
         */
 
        /* RSSI is 1 byte long */
-       bss->rssi = le32_to_cpu((long)(*pcurrentptr));
+       bss->rssi = *pcurrentptr;
        lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
        pcurrentptr += 1;
        bytesleftforcurrentbeacon -= 1;
 
        /* time stamp is 8 bytes long */
-       memcpy(fixedie.timestamp, pcurrentptr, 8);
-       memcpy(bss->timestamp, pcurrentptr, 8);
+       fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr);
        pcurrentptr += 8;
        bytesleftforcurrentbeacon -= 8;
 
        /* beacon interval is 2 bytes long */
-       memcpy(&fixedie.beaconinterval, pcurrentptr, 2);
-       bss->beaconperiod = le16_to_cpu(fixedie.beaconinterval);
+       fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
        pcurrentptr += 2;
        bytesleftforcurrentbeacon -= 2;
 
        /* capability information is 2 bytes long */
-       memcpy(&fixedie.capabilities, pcurrentptr, 2);
+        memcpy(&fixedie.capabilities, pcurrentptr, 2);
        lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n",
               fixedie.capabilities);
-       fixedie.capabilities = le16_to_cpu(fixedie.capabilities);
        pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities;
        memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo));
        pcurrentptr += 2;
@@ -1058,9 +1026,11 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
                switch (elemID) {
                case SSID:
-                       bss->ssid.ssidlength = elemlen;
-                       memcpy(bss->ssid.ssid, (pcurrentptr + 2), elemlen);
-                       lbs_deb_scan("ssid '%s'\n", bss->ssid.ssid);
+                       bss->ssid_len = elemlen;
+                       memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
+                       lbs_deb_scan("ssid '%s', ssid length %u\n",
+                                    escape_essid(bss->ssid, bss->ssid_len),
+                                    bss->ssid_len);
                        break;
 
                case SUPPORTED_RATES:
@@ -1079,8 +1049,10 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                        pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
                        memmove(&bss->phyparamset.fhparamset, pFH,
                                sizeof(struct ieeetypes_fhparamset));
+#if 0 /* I think we can store these LE */
                        bss->phyparamset.fhparamset.dwelltime
                            = le16_to_cpu(bss->phyparamset.fhparamset.dwelltime);
+#endif
                        break;
 
                case DS_PARAM_SET:
@@ -1101,8 +1073,10 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                        bss->atimwindow = le32_to_cpu(pibss->atimwindow);
                        memmove(&bss->ssparamset.ibssparamset, pibss,
                                sizeof(struct ieeetypes_ibssparamset));
+#if 0
                        bss->ssparamset.ibssparamset.atimwindow
                            = le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow);
+#endif
                        break;
 
                        /* Handle Country Info IE */
@@ -1200,15 +1174,12 @@ done:
  *
  *  @return         0--ssid is same, otherwise is different
  */
-int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2)
+int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
 {
-       if (!ssid1 || !ssid2)
-               return -1;
-
-       if (ssid1->ssidlength != ssid2->ssidlength)
+       if (ssid1_len != ssid2_len)
                return -1;
 
-       return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssidlength);
+       return memcmp(ssid1, ssid2, ssid1_len);
 }
 
 /**
@@ -1220,7 +1191,7 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
  *
  *  @return         index in BSSID list, or error return code (< 0)
  */
-struct bss_descriptor * libertas_find_BSSID_in_list(wlan_adapter * adapter,
+struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
                u8 * bssid, u8 mode)
 {
        struct bss_descriptor * iter_bss;
@@ -1267,8 +1238,9 @@ struct bss_descriptor * libertas_find_BSSID_in_list(wlan_adapter * adapter,
  *
  *  @return         index in BSSID list
  */
-struct bss_descriptor * libertas_find_SSID_in_list(wlan_adapter * adapter,
-                  struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
+struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
+                  u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
+                  int channel)
 {
        u8 bestrssi = 0;
        struct bss_descriptor * iter_bss = NULL;
@@ -1282,10 +1254,13 @@ struct bss_descriptor * libertas_find_SSID_in_list(wlan_adapter * adapter,
                    || (iter_bss->last_scanned < tmp_oldest->last_scanned))
                        tmp_oldest = iter_bss;
 
-               if (libertas_SSID_cmp(&iter_bss->ssid, ssid) != 0)
+               if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
+                                     ssid, ssid_len) != 0)
                        continue; /* ssid doesn't match */
                if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
                        continue; /* bssid doesn't match */
+               if ((channel > 0) && (iter_bss->channel != channel))
+                       continue; /* channel doesn't match */
 
                switch (mode) {
                case IW_MODE_INFRA:
@@ -1329,7 +1304,7 @@ out:
  *
  *  @return         index in BSSID list
  */
-struct bss_descriptor * libertas_find_best_SSID_in_list(wlan_adapter * adapter,
+struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
                u8 mode)
 {
        u8 bestrssi = 0;
@@ -1371,9 +1346,8 @@ struct bss_descriptor * libertas_find_best_SSID_in_list(wlan_adapter * adapter,
  *
  *  @return             0--success, otherwise--fail
  */
-int libertas_find_best_network_SSID(wlan_private * priv,
-                                    struct WLAN_802_11_SSID *ssid,
-                                    u8 preferred_mode, u8 *out_mode)
+int libertas_find_best_network_ssid(wlan_private * priv,
+               u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode)
 {
        wlan_adapter *adapter = priv->adapter;
        int ret = -1;
@@ -1381,17 +1355,16 @@ int libertas_find_best_network_SSID(wlan_private * priv,
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       memset(ssid, 0, sizeof(struct WLAN_802_11_SSID));
-
        wlan_scan_networks(priv, NULL, 1);
        if (adapter->surpriseremoved)
                return -1;
 
        wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
 
-       found = libertas_find_best_SSID_in_list(adapter, preferred_mode);
-       if (found && (found->ssid.ssidlength > 0)) {
-               memcpy(ssid, &found->ssid, sizeof(struct WLAN_802_11_SSID));
+       found = libertas_find_best_ssid_in_list(adapter, preferred_mode);
+       if (found && (found->ssid_len > 0)) {
+               memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
+               *out_ssid_len = found->ssid_len;
                *out_mode = found->mode;
                ret = 0;
        }
@@ -1436,9 +1409,8 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
  *
  *  @return                0-success, otherwise fail
  */
-int libertas_send_specific_SSID_scan(wlan_private * priv,
-                        struct WLAN_802_11_SSID *prequestedssid,
-                        u8 clear_ssid)
+int libertas_send_specific_ssid_scan(wlan_private * priv,
+                       u8 *ssid, u8 ssid_len, u8 clear_ssid)
 {
        wlan_adapter *adapter = priv->adapter;
        struct wlan_ioctl_user_scan_cfg scancfg;
@@ -1446,12 +1418,12 @@ int libertas_send_specific_SSID_scan(wlan_private * priv,
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       if (prequestedssid == NULL)
+       if (!ssid_len)
                goto out;
 
        memset(&scancfg, 0x00, sizeof(scancfg));
-       memcpy(scancfg.ssid, prequestedssid->ssid, prequestedssid->ssidlength);
-       scancfg.ssid_len = prequestedssid->ssidlength;
+       memcpy(scancfg.ssid, ssid, ssid_len);
+       scancfg.ssid_len = ssid_len;
        scancfg.clear_ssid = clear_ssid;
 
        wlan_scan_networks(priv, &scancfg, 1);
@@ -1473,7 +1445,7 @@ out:
  *
  *  @return          0-success, otherwise fail
  */
-int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
+int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
 {
        struct wlan_ioctl_user_scan_cfg scancfg;
 
@@ -1526,8 +1498,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
        /* SSID */
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.flags = 1;
-       iwe.u.data.length = min(bss->ssid.ssidlength, (u32) IW_ESSID_MAX_SIZE);
-       start = iwe_stream_add_point(start, stop, &iwe, bss->ssid.ssid);
+       iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
+       start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
 
        /* Mode */
        iwe.cmd = SIOCGIWMODE;
@@ -1566,7 +1538,9 @@ static inline char *libertas_translate_scan(wlan_private *priv,
         */
        if ((adapter->mode == IW_MODE_ADHOC)
            && adapter->adhoccreate
-           && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid)) {
+           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
+                                 adapter->curbssparams.ssid_len,
+                                 bss->ssid, bss->ssid_len)) {
                int snr, nf;
                snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
                nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
@@ -1582,7 +1556,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        }
        iwe.u.data.length = 0;
-       start = iwe_stream_add_point(start, stop, &iwe, bss->ssid.ssid);
+       start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
 
        current_val = start + IW_EV_LCP_LEN;
 
@@ -1601,7 +1575,9 @@ static inline char *libertas_translate_scan(wlan_private *priv,
                                         stop, &iwe, IW_EV_PARAM_LEN);
        }
        if ((bss->mode == IW_MODE_ADHOC)
-           && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid)
+           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
+                                 adapter->curbssparams.ssid_len,
+                                 bss->ssid, bss->ssid_len)
            && adapter->adhoccreate) {
                iwe.u.bitrate.value = 22 * 500000;
                current_val = iwe_stream_add_value(start, current_val,
@@ -1661,7 +1637,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
                wlan_scan_networks(priv, NULL, 0);
 
        /* Update RSSI if current BSS is a locally created ad-hoc BSS */
-       if ((adapter->inframode == wlan802_11ibss) && adapter->adhoccreate) {
+       if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) {
                libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
                                        cmd_option_waitforrsp, 0, NULL);
        }
@@ -1743,7 +1719,8 @@ int libertas_cmd_80211_scan(wlan_private * priv,
                                     + pscancfg->tlvbufferlen + S_DS_GEN);
 
        lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
-              cmd->command, cmd->size, cmd->seqnum);
+                    le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
+                    le16_to_cpu(cmd->seqnum));
 
        lbs_deb_leave(LBS_DEB_ASSOC);
        return 0;
@@ -1755,10 +1732,10 @@ static inline int is_same_network(struct bss_descriptor *src,
        /* A network is only a duplicate if the channel, BSSID, and ESSID
         * all match.  We treat all <hidden> with the same BSSID and channel
         * as one network */
-       return ((src->ssid.ssidlength == dst->ssid.ssidlength) &&
+       return ((src->ssid_len == dst->ssid_len) &&
                (src->channel == dst->channel) &&
                !compare_ether_addr(src->bssid, dst->bssid) &&
-               !memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssidlength));
+               !memcmp(src->ssid, dst->ssid, src->ssid_len));
 }
 
 /**
@@ -1798,7 +1775,6 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
        int bytesleft;
        int idx;
        int tlvbufsize;
-       u64 tsfval;
        int ret;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
@@ -1854,7 +1830,6 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
        for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) {
                struct bss_descriptor new;
                struct bss_descriptor * found = NULL;
-               struct bss_descriptor * iter_bss = NULL;
                struct bss_descriptor * oldest = NULL;
 
                /* Process the data fields and IEs returned for this BSS */
@@ -1905,9 +1880,7 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
                 *   beacon or probe response was received.
                 */
                if (ptsftlv) {
-                       memcpy(&tsfval, &ptsftlv->tsftable[idx], sizeof(tsfval));
-                       tsfval = le64_to_cpu(tsfval);
-                       memcpy(&new.networktsf, &tsfval, sizeof(new.networktsf));
+                       new.networktsf = le64_to_cpup(&ptsftlv->tsftable[idx]);
                }
 
                /* Copy the locally created newbssentry to the scan table */