]> git.karo-electronics.de Git - linux-beck.git/blobdiff - drivers/net/wireless/iwlwifi/iwl3945-base.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-beck.git] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index e0f52e264418a5dfad706f1f7081745b562e2df3..92d1b2e312d4076af8ceaef762f75744585d6da0 100644 (file)
@@ -2217,7 +2217,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
        }
 
        IWL_DEBUG_INFO("Starting scan...\n");
-       priv->scan_bands = 2;
+       if (priv->cfg->sku & IWL_SKU_G)
+               priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+       if (priv->cfg->sku & IWL_SKU_A)
+               priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
        set_bit(STATUS_SCANNING, &priv->status);
        priv->scan_start = jiffies;
        priv->scan_pass_start = priv->scan_start;
@@ -2431,15 +2434,15 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
 {
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
 
        cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                tx_flags |= TX_CMD_FLG_ACK_MSK;
-               if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
+               if (ieee80211_is_mgmt(fc))
                        tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
-               if (ieee80211_is_probe_response(fc) &&
+               if (ieee80211_is_probe_resp(fc) &&
                    !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
                        tx_flags |= TX_CMD_FLG_TSF_MSK;
        } else {
@@ -2448,11 +2451,11 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
        }
 
        cmd->cmd.tx.sta_id = std_id;
-       if (ieee80211_get_morefrag(hdr))
+       if (ieee80211_has_morefrags(fc))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
 
-       if (ieee80211_is_qos_data(fc)) {
-               u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
+       if (ieee80211_is_data_qos(fc)) {
+               u8 *qc = ieee80211_get_qos_ctl(hdr);
                cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
        } else {
@@ -2471,9 +2474,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
 
        tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
-       if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
-               if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
-                   (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
+       if (ieee80211_is_mgmt(fc)) {
+               if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
                        cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
                else
                        cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
@@ -2564,7 +2566,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
        u8 sta_id;
        u8 tid = 0;
        u16 seq_number = 0;
-       u16 fc;
+       __le16 fc;
        u8 wait_write_ptr = 0;
        u8 *qc = NULL;
        unsigned long flags;
@@ -2589,28 +2591,28 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
        unicast = !is_multicast_ether_addr(hdr->addr1);
        id = 0;
 
-       fc = le16_to_cpu(hdr->frame_control);
+       fc = hdr->frame_control;
 
 #ifdef CONFIG_IWL3945_DEBUG
        if (ieee80211_is_auth(fc))
                IWL_DEBUG_TX("Sending AUTH frame\n");
-       else if (ieee80211_is_assoc_request(fc))
+       else if (ieee80211_is_assoc_req(fc))
                IWL_DEBUG_TX("Sending ASSOC frame\n");
-       else if (ieee80211_is_reassoc_request(fc))
+       else if (ieee80211_is_reassoc_req(fc))
                IWL_DEBUG_TX("Sending REASSOC frame\n");
 #endif
 
        /* drop all data frame if we are not associated */
        if ((!iwl3945_is_associated(priv) ||
             ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
-           ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+           ieee80211_is_data(fc)) {
                IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
                goto drop_unlock;
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       hdr_len = ieee80211_get_hdrlen(fc);
+       hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
 
        /* Find (or create) index into station table for destination station */
        sta_id = iwl3945_get_sta_id(priv, hdr);
@@ -2624,8 +2626,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 
        IWL_DEBUG_RATE("station Id %d\n", sta_id);
 
-       if (ieee80211_is_qos_data(fc)) {
-               qc = ieee80211_get_qos_ctrl(hdr, hdr_len);
+       if (ieee80211_is_data_qos(fc)) {
+               qc = ieee80211_get_qos_ctl(hdr);
                tid = qc[0] & 0xf;
                seq_number = priv->stations[sta_id].tid[tid].seq_number &
                                IEEE80211_SCTL_SEQ;
@@ -2732,7 +2734,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
 
-       if (!ieee80211_get_morefrag(hdr)) {
+       if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
                if (qc) {
                        priv->stations[sta_id].tid[tid].seq_number = seq_number;
@@ -2746,7 +2748,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
                           sizeof(out_cmd->cmd.tx));
 
        iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
-                          ieee80211_get_hdrlen(fc));
+                          ieee80211_get_hdrlen(le16_to_cpu(fc)));
 
        /* Tell device the write index *just past* this latest filled TFD */
        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -2875,7 +2877,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
                return;
        }
 
-       queue_work(priv->workqueue, &priv->restart);
+       if (priv->is_open)
+               queue_work(priv->workqueue, &priv->restart);
        return;
 }
 
@@ -3342,13 +3345,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
        cancel_delayed_work(&priv->scan_check);
 
        IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
-                      (priv->scan_bands == 2) ? "2.4" : "5.2",
+                      (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+                                                       "2.4" : "5.2",
                       jiffies_to_msecs(elapsed_jiffies
                                        (priv->scan_pass_start, jiffies)));
 
-       /* Remove this scanned band from the list
-        * of pending bands to scan */
-       priv->scan_bands--;
+       /* Remove this scanned band from the list of pending
+        * bands to scan, band G precedes A in order of scanning
+        * as seen in iwl3945_bg_request_scan */
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+       else if (priv->scan_bands &  BIT(IEEE80211_BAND_5GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
 
        /* If a request to abort was given, or the scan did not succeed
         * then we reset the scan state machine and terminate,
@@ -4961,7 +4969,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
 
                ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+                       IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
                                       scan_ch->channel);
                        continue;
                }
@@ -5847,9 +5855,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
        /* Configure the adapter for unassociated operation */
        iwl3945_commit_rxon(priv);
 
-       /* At this point, the NIC is initialized and operational */
-       priv->notif_missed_beacons = 0;
-
        iwl3945_reg_txpower_periodic(priv);
 
        iwl3945_led_register(priv);
@@ -6319,21 +6324,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        /* flags + rate selection */
 
-       switch (priv->scan_bands) {
-       case 2:
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
                scan->good_CRC_th = 0;
                band = IEEE80211_BAND_2GHZ;
-               break;
-
-       case 1:
+       } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
                band = IEEE80211_BAND_5GHZ;
-               break;
-
-       default:
+       } else {
                IWL_WARNING("Invalid scan band count\n");
                goto done;
        }
@@ -6773,7 +6773,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
                                           conf->channel->hw_value);
        if (!is_channel_valid(ch_info)) {
-               IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
+               IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
                               conf->channel->hw_value, conf->channel->band);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -8260,7 +8260,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 
        iwl3945_free_channel_map(priv);
        iwl3945_free_geos(priv);
-
+       kfree(priv->scan);
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);