netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andreas Mohr <andim2@users.sourceforge.net>
To: acx100-devel@lists.sourceforge.net
Cc: netdev@vger.kernel.org
Subject: [PATCH] WLAN acx100: OOPS fix, KERN_xxx, misc.
Date: Mon, 16 Jan 2006 15:02:33 +0100	[thread overview]
Message-ID: <20060116140233.GA8170@rhlx01.fht-esslingen.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 833 bytes --]

Hi all (and especially Denis),

acx-20060116_misc.diff:
- fix OOPS in acx_l_rxmonitor() (wrong ndev->type setting leading to memcpy
  of negative size) by reworking monitor mode type setup and adding
  missing sanity checks
- rename acx1XX_ie_powermgmt_t to more correct acx1XX_ie_powersave_t
- fix format string compile warnings
- add <linux/compiler.h> include apparently required for __iomem define
  around Linux 2.6.8
- rework eCPU init by replacing static msleep with faster, more intelligent
  (hopefully) busy-wait

acx-20060116_KERN_xxx.diff (too large: gzipped):
- add proper KERN_xxx prefixes to printk() as requested recently

Note that both patches are based on acx-20060116 proper (rediffed from
acx-20060113), smallish conflicts may result; apply acx-20060116_KERN_xxx.diff after acx-20060116_misc.diff.

Andreas Mohr

[-- Attachment #2: acx-20060116_misc.diff --]
[-- Type: text/plain, Size: 9559 bytes --]

diff -urN acx-20060116.orig/acx_struct.h acx-20060116_misc/acx_struct.h
--- acx-20060116.orig/acx_struct.h	2006-01-15 12:03:38.000000000 +0100
+++ acx-20060116_misc/acx_struct.h	2006-01-16 14:12:04.000000000 +0100
@@ -1202,6 +1202,7 @@
 	u8		ap[ETH_ALEN];		/* The AP we want, FF:FF:FF:FF:FF:FF is any */
 	u16		aid;			/* The Association ID sent from the AP / last used AID if we're an AP */
 	u16		mode;			/* mode from iwconfig */
+	int		monitor_type;		/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
 	u16		status;			/* 802.11 association status */
 	u8		essid_active;		/* specific ESSID active, or select any? */
 	u8		essid_len;		/* to avoid dozens of strlen() */
@@ -1623,7 +1624,7 @@
 #define PS_OPT_TX_PSPOLL	0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */
 #define PS_OPT_STILL_RCV_BCASTS	0x01
 
-typedef struct acx100_ie_powermgmt {
+typedef struct acx100_ie_powersave {
 	u16	type ACX_PACKED;
 	u16	len ACX_PACKED;
 	u8	wakeup_cfg ACX_PACKED;
@@ -1631,9 +1632,9 @@
 	u8	options ACX_PACKED;
 	u8	hangover_period ACX_PACKED; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
 	u16	enhanced_ps_transition_time ACX_PACKED; /* rem. wake time for Enh. PS */
-} acx100_ie_powermgmt_t;
+} acx100_ie_powersave_t;
 
-typedef struct acx111_ie_powermgmt {
+typedef struct acx111_ie_powersave {
 	u16	type ACX_PACKED;
 	u16	len ACX_PACKED;
 	u8	wakeup_cfg ACX_PACKED;
@@ -1642,7 +1643,7 @@
 	u8	hangover_period ACX_PACKED; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
 	u32	beacon_rx_time ACX_PACKED;
 	u32	enhanced_ps_transition_time ACX_PACKED; /* rem. wake time for Enh. PS */
-} acx111_ie_powermgmt_t;
+} acx111_ie_powersave_t;
 
 
 /***********************************************************************
diff -urN acx-20060116.orig/common.c acx-20060116_misc/common.c
--- acx-20060116.orig/common.c	2006-01-15 12:38:43.000000000 +0100
+++ acx-20060116_misc/common.c	2006-01-16 14:22:02.000000000 +0100
@@ -183,7 +183,7 @@
 		diff -= adev->lock_time;
 		if (diff > max_lock_time) {
 			where = sanitize_str(where);
-			printk("max lock hold time %d CPU ticks from %s "
+			printk("max lock hold time %ld CPU ticks from %s "
 				"to %s\n", diff, adev->last_lock, where);
 			max_lock_time = diff;
 		}
@@ -230,7 +230,7 @@
 		unsigned long diff = jiffies - adev->sem_time;
 		if (diff > max_sem_time) {
 			where = sanitize_str(where);
-			printk("max sem hold time %d jiffies from %s "
+			printk("max sem hold time %ld jiffies from %s "
 				"to %s\n", diff, adev->last_sem, where);
 			max_sem_time = diff;
 		}
@@ -838,7 +838,7 @@
 acx100_ie_len[] = {
 	0,
 	ACX100_IE_ACX_TIMER_LEN,
-	sizeof(acx100_ie_powermgmt_t)-4, /* is that 6 or 8??? */
+	sizeof(acx100_ie_powersave_t)-4, /* is that 6 or 8??? */
 	ACX1xx_IE_QUEUE_CONFIG_LEN,
 	ACX100_IE_BLOCK_SIZE_LEN,
 	ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
@@ -889,7 +889,7 @@
 acx111_ie_len[] = {
 	0,
 	ACX100_IE_ACX_TIMER_LEN,
-	sizeof(acx111_ie_powermgmt_t)-4,
+	sizeof(acx111_ie_powersave_t)-4,
 	ACX1xx_IE_QUEUE_CONFIG_LEN,
 	ACX100_IE_BLOCK_SIZE_LEN,
 	ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
@@ -2156,6 +2156,7 @@
 	adev->listen_interval = 100;
 	adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
 	adev->mode = ACX_MODE_2_STA;
+	adev->monitor_type = ARPHRD_IEEE80211_PRISM;
 	adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
 
 	adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
@@ -2347,10 +2348,11 @@
 
 	skb_put(skb, skb_len);
 
+	if (adev->ndev->type == ARPHRD_IEEE80211) {
 		/* when in raw 802.11 mode, just copy frame as-is */
-	if (adev->ndev->type == ARPHRD_IEEE80211)
 		datap = skb->data;
-	else { /* otherwise, emulate prism header */
+	} else if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) {
+		/* emulate prism header */
 		msg = (wlansniffrm_t*)skb->data;
 		datap = msg + 1;
 
@@ -2410,8 +2412,20 @@
 		msg->frmlen.status = WLANITEM_STATUS_data_ok;
 		msg->frmlen.len = 4;
 		msg->frmlen.data = skb_len;
+	} else {
+		printk(KERN_ERR "unsupported netdev type %d!\n",
+			adev->ndev->type);
+		dev_kfree_skb(skb);
+		return;
 	}
 
+	/* sanity check (keep it here) */
+	if (unlikely((int)skb_len < 0))
+	{
+		printk(KERN_ERR "skb_len bug (%d)!! Aborting...\n", (int)skb_len);
+		dev_kfree_skb(skb);
+		return;
+	}
 	memcpy(datap, ((unsigned char*)rxbuf)+payload_offset, skb_len);
 
 	skb->dev = adev->ndev;
@@ -2425,6 +2439,7 @@
 
 	adev->stats.rx_packets++;
 	adev->stats.rx_bytes += skb->len;
+
 end:
 	FN_EXIT0;
 }
@@ -5816,8 +5831,8 @@
 {
 	/* merge both structs in a union to be able to have common code */
 	union {
-		acx111_ie_powermgmt_t acx111;
-		acx100_ie_powermgmt_t acx100;
+		acx111_ie_powersave_t acx111;
+		acx100_ie_powersave_t acx100;
 	} pm;
 
 	/* change 802.11 power save mode settings */
@@ -6246,7 +6261,8 @@
 	}
 
 	if (adev->set_mask & GETSET_MODE) {
-		adev->ndev->type = ARPHRD_ETHER;
+		adev->ndev->type = (adev->mode == ACX_MODE_MONITOR) ?
+			adev->monitor_type : ARPHRD_ETHER;
 
 		switch (adev->mode) {
 		case ACX_MODE_3_AP:
@@ -6265,9 +6281,6 @@
 			acx_s_cmd_join_bssid(adev, adev->bssid);
 			break;
 		case ACX_MODE_MONITOR:
-			/* adev->ndev->type = ARPHRD_ETHER; */
-			/* adev->ndev->type = ARPHRD_IEEE80211; */
-			adev->ndev->type = ARPHRD_IEEE80211_PRISM;
 			acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER);
 			/* this stops beacons */
 			acx_s_cmd_join_bssid(adev, adev->bssid);
diff -urN acx-20060116.orig/ioctl.c acx-20060116_misc/ioctl.c
--- acx-20060116.orig/ioctl.c	2006-01-15 12:02:26.000000000 +0100
+++ acx-20060116_misc/ioctl.c	2006-01-16 14:21:46.000000000 +0100
@@ -2078,13 +2078,14 @@
 
 	switch (params[0]) {
 	case 0:
-		adev->ndev->type = ARPHRD_ETHER;
+		/* no monitor mode. hmm, should we simply ignore it
+		 * or go back to enabling adev->netdev->type ARPHRD_ETHER? */
 		break;
 	case 1:
-		adev->ndev->type = ARPHRD_IEEE80211_PRISM;
+		adev->monitor_type = ARPHRD_IEEE80211_PRISM;
 		break;
 	case 2:
-		adev->ndev->type = ARPHRD_IEEE80211;
+		adev->monitor_type = ARPHRD_IEEE80211;
 		break;
 	}
 
diff -urN acx-20060116.orig/pci.c acx-20060116_misc/pci.c
--- acx-20060116.orig/pci.c	2006-01-15 12:01:41.000000000 +0100
+++ acx-20060116_misc/pci.c	2006-01-16 14:21:13.000000000 +0100
@@ -33,6 +33,7 @@
 
 #include <linux/config.h>
 #include <linux/version.h>
+#include <linux/compiler.h> /* required for Lx 2.6.8 ?? */
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -354,8 +355,9 @@
 		write_flush(adev);
 		write_reg32(adev, IO_ACX_EEPROM_CTL, 1);
 
+		count = 0xffff;
 		while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
-			if (unlikely(++count > 0xffff)) {
+			if (unlikely(!--count)) {
 				printk("WARNING, DANGER!!! "
 					"Timeout waiting for EEPROM write\n");
 				goto end;
@@ -369,13 +371,13 @@
 	write_flush(adev);
 
 	/* now start a verification run */
-	count = 0xffff;
 	for (i = 0; i < len; i++) {
 		write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
 		write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
 		write_flush(adev);
 		write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
 
+		count = 0xffff;
 		while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
 			if (unlikely(!--count)) {
 				printk("timeout waiting for EEPROM read\n");
@@ -747,18 +749,17 @@
 	temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1;
 	write_reg16(adev, IO_ACX_ECPU_CTRL, temp);
 
-	/* now do soft reset of eCPU */
+	/* now do soft reset of eCPU, set bit */
 	temp = read_reg16(adev, IO_ACX_SOFT_RESET) | 0x1;
 	log(L_DEBUG, "%s: enable soft reset...\n", __func__);
 	write_reg16(adev, IO_ACX_SOFT_RESET, temp);
 	write_flush(adev);
 
-	/* now reset bit again */
+	/* now clear bit again: deassert eCPU reset */
 	log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__);
-	/* deassert eCPU reset */
 	write_reg16(adev, IO_ACX_SOFT_RESET, temp & ~0x1);
 
-	/* now start a burst read from initial flash EEPROM */
+	/* now start a burst read from initial EEPROM */
 	temp = read_reg16(adev, IO_ACX_EE_START) | 0x1;
 	write_reg16(adev, IO_ACX_EE_START, temp);
 	write_flush(adev);
@@ -893,6 +894,7 @@
 	int result = NOT_OK;
 	u16 hardware_info;
 	u16 ecpu_ctrl;
+	int count;
 
 	FN_ENTER;
 
@@ -927,12 +929,24 @@
 
 	acx_unlock(adev, flags);
 
-	/* without this delay acx100 may fail to report hardware_info
-	** (see below). Most probably eCPU runs some init code */
-	acx_s_msleep(10);
-
 	/* need to know radio type before fw load */
-	hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION);
+ 	/* Need to wait for arrival of this information in a loop,
+ 	 * most probably since eCPU runs some init code from EEPROM
+ 	 * (started burst read in reset_mac()) which also
+ 	 * sets the radio type ID */
+ 
+ 	count = 0xffff;
+ 	do {
+ 		hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION);
+ 		if (!--count)
+ 		{
+ 			msg = "eCPU didn't indicate radio type";
+ 			goto end_fail;
+ 		}
+ 		cpu_relax();
+ 	} while (!(hardware_info & 0xff00)); /* radio type still zero? */
+ 
+ 	/* printk("DEBUG: count %d\n", count); */
 	adev->form_factor = hardware_info & 0xff;
 	adev->radio_type = hardware_info >> 8;
 
@@ -940,11 +954,11 @@
 	if (OK != acxpci_s_upload_fw(adev))
 		goto end_fail;
 
-	acx_s_msleep(10);
+	/* acx_s_msleep(10);	this one really shouldn't be required */
 
 	/* now start eCPU by clearing bit */
-	log(L_DEBUG, "booted eCPU up and waiting for completion...\n");
 	write_reg16(adev, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1);
+	log(L_DEBUG, "booted eCPU up and waiting for completion...\n");
 
 	/* wait for eCPU bootup */
 	if (OK != acxpci_s_verify_init(adev)) {

[-- Attachment #3: acx-20060116_KERN_xxx.diff.gz --]
[-- Type: application/x-gzip, Size: 18122 bytes --]

             reply	other threads:[~2006-01-16 14:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-16 14:02 Andreas Mohr [this message]
2006-01-16 14:34 ` [PATCH] WLAN acx100: OOPS fix, KERN_xxx, misc Denis Vlasenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060116140233.GA8170@rhlx01.fht-esslingen.de \
    --to=andim2@users.sourceforge.net \
    --cc=acx100-devel@lists.sourceforge.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).