/* Host AP driver Info Frame processing (part of hostap.o module) */
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
/* Called only as a tasklet (software IRQ) */
static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf,
{
struct hfa384x_join_request req;
struct net_device *dev = local->dev;
- struct hfa384x_scan_result *selected, *entry;
+ struct hfa384x_hostscan_result *selected, *entry;
int i;
unsigned long flags;
int left)
{
u16 *pos;
- int new_count;
+ int new_count, i;
unsigned long flags;
- struct hfa384x_scan_result *results, *prev;
+ struct hfa384x_scan_result *res;
+ struct hfa384x_hostscan_result *results, *prev;
if (left < 4) {
printk(KERN_DEBUG "%s: invalid scanresult info frame "
left -= 4;
new_count = left / sizeof(struct hfa384x_scan_result);
- results = kmalloc(new_count * sizeof(struct hfa384x_scan_result),
+ results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
GFP_ATOMIC);
if (results == NULL)
return;
- memcpy(results, pos, new_count * sizeof(struct hfa384x_scan_result));
+
+ /* Convert to hostscan result format. */
+ res = (struct hfa384x_scan_result *) pos;
+ for (i = 0; i < new_count; i++) {
+ memcpy(&results[i], &res[i],
+ sizeof(struct hfa384x_scan_result));
+ results[i].atim = 0;
+ }
spin_lock_irqsave(&local->lock, flags);
local->last_scan_type = PRISM2_SCAN;
spin_lock_irqsave(&local->lock, flags);
local->last_scan_type = PRISM2_HOSTSCAN;
- prev = local->last_hostscan_results;
- local->last_hostscan_results = results;
- local->last_hostscan_results_count = new_count;
+ prev = local->last_scan_results;
+ local->last_scan_results = results;
+ local->last_scan_results_count = new_count;
spin_unlock_irqrestore(&local->lock, flags);
kfree(prev);
{
if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA)
prism2_host_roaming(local);
+
+ if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA &&
+ memcmp(local->preferred_ap, "\x00\x00\x00\x00\x00\x00",
+ ETH_ALEN) != 0) {
+ /*
+ * Firmware seems to be getting into odd state in host_roaming
+ * mode 2 when hostscan is used without join command, so try
+ * to fix this by re-joining the current AP. This does not
+ * actually trigger a new association if the current AP is
+ * still in the scan results.
+ */
+ prism2_host_roaming(local);
+ }
}
/* Called only as scheduled task after receiving info frames (used to avoid
* pending too much time in HW IRQ handler). */
-static void handle_info_queue(void *data)
+static void handle_info_queue(struct work_struct *work)
{
- local_info_t *local = (local_info_t *) data;
+ local_info_t *local = container_of(work, local_info_t, info_queue);
if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS,
&local->pending_info))
{
skb_queue_head_init(&local->info_list);
#ifndef PRISM2_NO_STATION_MODES
- INIT_WORK(&local->info_queue, handle_info_queue, local);
+ INIT_WORK(&local->info_queue, handle_info_queue);
#endif /* PRISM2_NO_STATION_MODES */
}