]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/ipw2100.c
Merge branch 'locks' of git://linux-nfs.org/~bfields/linux
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / ipw2100.c
index 92314c365afdc05b7504182968bc1c0f6072ffb1..2ab107f457937b96b339711d6c7eaa6ffa8f79c0 100644 (file)
@@ -1267,7 +1267,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
                                       IPW2100_INTA_FATAL_ERROR |
                                       IPW2100_INTA_PARITY_ERROR);
                }
-       } while (i--);
+       } while (--i);
 
        /* Clear out any pending INTAs since we aren't supposed to have
         * interrupts enabled at this point... */
@@ -1339,7 +1339,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
 
                if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
                        break;
-       } while (i--);
+       } while (--i);
 
        priv->status &= ~STATUS_RESET_PENDING;
 
@@ -1769,7 +1769,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
                if (priv->stop_rf_kill) {
                        priv->stop_rf_kill = 0;
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                }
 
                deferred = 1;
@@ -2086,7 +2086,30 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
        /* Make sure the RF Kill check timer is running */
        priv->stop_rf_kill = 0;
        cancel_delayed_work(&priv->rf_kill);
-       queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
+       queue_delayed_work(priv->workqueue, &priv->rf_kill,
+                          round_jiffies_relative(HZ));
+}
+
+static void send_scan_event(void *data)
+{
+       struct ipw2100_priv *priv = data;
+       union iwreq_data wrqu;
+
+       wrqu.data.length = 0;
+       wrqu.data.flags = 0;
+       wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static void ipw2100_scan_event_later(struct work_struct *work)
+{
+       send_scan_event(container_of(work, struct ipw2100_priv,
+                                       scan_event_later.work));
+}
+
+static void ipw2100_scan_event_now(struct work_struct *work)
+{
+       send_scan_event(container_of(work, struct ipw2100_priv,
+                                       scan_event_now));
 }
 
 static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
@@ -2095,6 +2118,18 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
        /* Age the scan results... */
        priv->ieee->scans++;
        priv->status &= ~STATUS_SCANNING;
+
+       /* Only userspace-requested scan completion events go out immediately */
+       if (!priv->user_requested_scan) {
+               if (!delayed_work_pending(&priv->scan_event_later))
+                       queue_delayed_work(priv->workqueue,
+                                       &priv->scan_event_later,
+                                       round_jiffies_relative(msecs_to_jiffies(4000)));
+       } else {
+               priv->user_requested_scan = 0;
+               cancel_delayed_work(&priv->scan_event_later);
+               queue_work(priv->workqueue, &priv->scan_event_now);
+       }
 }
 
 #ifdef CONFIG_IPW2100_DEBUG
@@ -2474,9 +2509,9 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
 
        ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
-       ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */
+       ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr)); /* total hdr+data */
 
-       ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
+       ipw_rt->rt_hdr.it_present = cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
 
        ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;
 
@@ -2523,7 +2558,7 @@ static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
 #ifdef CONFIG_IPW2100_MONITOR
                return 0;
 #else
-               switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
+               switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
                case IEEE80211_FTYPE_MGMT:
                case IEEE80211_FTYPE_CTL:
                        return 0;
@@ -2642,7 +2677,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 #endif
                        if (stats.len < sizeof(struct ieee80211_hdr_3addr))
                                break;
-                       switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
+                       switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
                        case IEEE80211_FTYPE_MGMT:
                                ieee80211_rx_mgt(priv->ieee,
                                                 &u->rx_data.header, &stats);
@@ -4208,7 +4243,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
                        priv->stop_rf_kill = 0;
                        cancel_delayed_work(&priv->rf_kill);
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                } else
                        schedule_reset(priv);
        }
@@ -4349,6 +4384,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
                cancel_delayed_work(&priv->wx_event_work);
                cancel_delayed_work(&priv->hang_check);
                cancel_delayed_work(&priv->rf_kill);
+               cancel_delayed_work(&priv->scan_event_later);
                destroy_workqueue(priv->workqueue);
                priv->workqueue = NULL;
        }
@@ -5946,7 +5982,7 @@ static void ipw2100_rf_kill(struct work_struct *work)
                IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
                if (!priv->stop_rf_kill)
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                goto exit_unlock;
        }
 
@@ -6092,6 +6128,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
        INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
        INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
+       INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
+       INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
 
        tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
                     ipw2100_irq_tasklet, (unsigned long)priv);
@@ -6553,8 +6591,7 @@ static const long ipw2100_frequencies[] = {
        2472, 2484
 };
 
-#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
-                    sizeof(ipw2100_frequencies[0]))
+#define FREQ_COUNT     ARRAY_SIZE(ipw2100_frequencies)
 
 static const long ipw2100_rates_11b[] = {
        1000000,
@@ -7396,6 +7433,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
        }
 
        IPW_DEBUG_WX("Initiating scan...\n");
+
+       priv->user_requested_scan = 1;
        if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
                IPW_DEBUG_WX("Start scan failed.\n");
 
@@ -7756,7 +7795,7 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
 {
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
-       u16 reason;
+       __le16 reason;
 
        reason = cpu_to_le16(mlme->reason_code);