* [PATCH, RFT] bcm43xx: AccessPoint mode
@ 2006-06-19 9:07 Michael Buesch
2006-06-22 15:30 ` Jiri Benc
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Michael Buesch @ 2006-06-19 9:07 UTC (permalink / raw)
To: bcm43xx-dev; +Cc: netdev, Alexander Tsvyashchenko, Francois Barre
[-- Attachment #1: Type: text/plain, Size: 25787 bytes --]
Hi,
This patch enables the usage of a bcm43xx card as AP with
the Devicescape 802.11 stack.
Well, it does not work 100%, but at least it's very promising.
We are able to create a bssid and correctly send beacon frames out.
This patch is tested on BE and LE machines.
There seem to be issues with Devicescape and/or hostap.
Trying to authenticate from a STA to the AP does not work. The
packet is simply not processed. I was able to catch the auth
request on the AP (using the wonderful dscape virtual interfaces).
So the AP receives the packet, but loses it somewhere in the
stack or hostapd.
Well, thanks to Alexander Tsvyashchenko and the OpenWRT team for
the hard work to figure out how this all works.
My part on this patch is mainly endianess fixes.
Please give it a testrun.
Final note about hostapd:
"hostapd snapshot 0.5-2006-06-10" seems to "work" in the sense
that it is able to bring up the device.
"hostapd snapshot 0.5-2006-06-11" seems to fail.
I did not look into this more close, yet.
Important notes from Alexander Tsvyashchenko's initial mail follow:
------
1) This version deals with TIM in cleaner way (though, PS mode is still
not supported) - instead of patching dscape stack to skip TIM
generation, it strips TIM when writing probe response template and
leaves it when writing beacon template.
2) As in current dscape stack management interface seems to be no longer
passed to the driver, all interface handling is left as it is, no
changes there should be made anymore.
...
Known limitations:
1) PS mode is not supported.
Testing instructions:
Although my previous patch to hostapd to make it interoperable with
bcm43xx & dscape has been merged already in their CVS version, due to
the subsequent changes in dscape stack current hostapd is again
incompartible :-( So, to test this patch, the patch to hostapd should be
applied.
I used hostapd snapshot 0.5-2006-06-10, patch for it is attached.
The patch is very hacky and requires tricky way to bring everything up,
but as dscape stack is changed quite constantly, I just do not want to
waste time fixing it in "proper" way only to find a week later that
dscape handling of master interface was changed completely once more and
everything is broken again ;-)
The patch for dscape stack that is attached is not 100% necessary, but it
seems to allow operating clients that request PS mode to be enabled at
AP (verified with PDA client), the only thing it contains is disabling
actual PS handling in dscape.
So, the following sequence should be used to test AP mode:
1) take hostapd snapshot 0.5-2006-06-10 (other recent versions should
work OK also, though), apply the hostapd patch attached.
2) Insert modules (80211, rate_control and bcm43xx-d80211)
3) "iwconfig wlan0 mode master"
4) "ifconfig wlan0 up" (this should be done by hostapd actually, but
its operation with current dscape stack seems to be broken)
5) Start hostapd (f.e. "hostapd -B /etc/hostapd.conf"), config file can
look like:
=====
interface=wlan0
driver=devicescape
ssid=OpenWrt
channel=1
send_probe_response=0
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
debug=4
=====
6) "iwconfig wlan0 essid <your-SSID-name>" (this also should not be
required, but current combination of hostapd + dscape doesn't seem to
generate config_interface callback when setting beacon, so this is
required just to force call of config_interface).
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-17 21:26:10.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-18 23:36:31.000000000 +0200
@@ -152,7 +152,7 @@
u32 status;
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
+ if (status & BCM43xx_SBF_XFER_REG_BYTESWAP)
val = swab32(val);
bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
@@ -312,7 +312,7 @@
}
}
-void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+static void bcm43xx_time_lock(struct bcm43xx_private *bcm)
{
u32 status;
@@ -320,7 +320,19 @@
status |= BCM43xx_SBF_TIME_UPDATE;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
+}
+
+static void bcm43xx_time_unlock(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
+ status &= ~BCM43xx_SBF_TIME_UPDATE;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+}
+static void bcm43xx_tsf_write_locked(struct bcm43xx_private *bcm, u64 tsf)
+{
/* Be careful with the in-progress timer.
* First zero out the low register, so we have a full
* register-overflow duration to complete the operation.
@@ -350,10 +362,13 @@
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
}
+}
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status &= ~BCM43xx_SBF_TIME_UPDATE;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+{
+ bcm43xx_time_lock(bcm);
+ bcm43xx_tsf_write_locked(bcm, tsf);
+ bcm43xx_time_unlock(bcm);
}
static void bcm43xx_measure_channel_change_time(struct bcm43xx_private *bcm)
@@ -415,10 +430,11 @@
static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
- const u8 *mac = NULL;
- const u8 *bssid = NULL;
+ const u8 *mac;
+ const u8 *bssid;
u8 mac_bssid[ETH_ALEN * 2];
int i;
+ u32 tmp;
bssid = bcm->interface.bssid;
if (!bssid)
@@ -431,12 +447,13 @@
memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
/* Write our MAC address and BSSID to template ram */
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
+ for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) {
+ tmp = (u32)(mac_bssid[i + 0]);
+ tmp |= (u32)(mac_bssid[i + 1]) << 8;
+ tmp |= (u32)(mac_bssid[i + 2]) << 16;
+ tmp |= (u32)(mac_bssid[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, 0x20 + i, tmp);
+ }
}
static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
@@ -460,49 +477,6 @@
bcm->short_slot = 0;
}
-/* FIXME: To get the MAC-filter working, we need to implement the
- * following functions (and rename them :)
- */
-#if 0
-static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
-
- bcm43xx_ram_write(bcm, 0x0026, 0x0000);
- bcm43xx_ram_write(bcm, 0x0028, 0x0000);
- bcm43xx_ram_write(bcm, 0x007E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0080, 0x0000);
- bcm43xx_ram_write(bcm, 0x047E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0480, 0x0000);
-
- if (bcm->current_core->rev < 3) {
- bcm43xx_write16(bcm, 0x0610, 0x8000);
- bcm43xx_write16(bcm, 0x060E, 0x0000);
- } else
- bcm43xx_write32(bcm, 0x0188, 0x80000000);
-
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
-
-#if 0
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
- ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
- bcm43xx_short_slot_timing_enable(bcm);
-#endif
-
- bcm43xx_mac_enable(bcm);
-}
-
-static void bcm43xx_associate(struct bcm43xx_private *bcm,
- const u8 *mac)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
- bcm43xx_write_mac_bssid_templates(bcm);
- bcm43xx_mac_enable(bcm);
-}
-#endif
-
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
* Returns the _previously_ enabled IRQ mask.
*/
@@ -758,12 +732,29 @@
return -ENODEV;
}
+#ifdef CONFIG_BCM947XX
+static void bcm43xx_aton(const char *str, char *dest)
+{
+ int i = 0;
+ u16 *d = (u16 *)dest;
+
+ for (;;) {
+ dest[i++] = (char)simple_strtoul(str, NULL, 16);
+ str += 2;
+ if (!*str++ || i == 6)
+ break;
+ }
+ for (i = 0; i < 3; i++)
+ d[i] = be16_to_cpu(d[i]);
+}
+#endif
+
static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
{
u16 value;
u16 *sprom;
#ifdef CONFIG_BCM947XX
- char *c;
+ const char *c;
#endif
sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
@@ -772,27 +763,46 @@
printk(KERN_ERR PFX "sprom_extract OOM\n");
return -ENOMEM;
}
-#ifdef CONFIG_BCM947XX
- sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
- sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
-
- if ((c = nvram_get("il0macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
-
- if ((c = nvram_get("et1macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
-
- sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
- sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
- sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
-
- sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
- sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
- sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
- sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
-#else
bcm43xx_sprom_read(bcm, sprom);
+
+#ifdef CONFIG_BCM947XX
+ /* In the case some settings are found in nvram, use them
+ * to override those read from sprom.
+ */
+ c = nvram_get("boardflags2");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardflags");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("il0macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_IL0MACADDR]));
+ c = nvram_get("et1macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_ET1MACADDR]));
+ c = nvram_get("pa0b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardrev");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDREV] = simple_strtoul(c, NULL, 0);
#endif
/* boardflags2 */
@@ -914,21 +924,21 @@
u16 value = 0;
u32 buffer[5] = {
0x00000000,
- 0x0000D400,
+ 0x00D40000,
0x00000000,
- 0x00000001,
+ 0x01000000,
0x00000000,
};
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
max_loop = 0x1E;
- buffer[0] = 0xCC010200;
+ buffer[0] = 0x000201CC;
break;
case BCM43xx_PHYTYPE_B:
case BCM43xx_PHYTYPE_G:
max_loop = 0xFA;
- buffer[0] = 0x6E840B00;
+ buffer[0] = 0x000B846E;
break;
default:
assert(0);
@@ -1521,48 +1531,274 @@
bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
}
+static void bcm43xx_write_template_common(struct bcm43xx_private *bcm,
+ const u8* data, u16 size,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u32 i, tmp;
+ struct bcm43xx_plcp_hdr4 plcp;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ bcm43xx_ram_write(bcm, ram_offset, le32_to_cpu(plcp.data));
+ ram_offset += sizeof(u32);
+ /* The PLCP is 6 bytes long, but we only wrote 4 bytes, yet.
+ * So leave the first two bytes of the next write blank.
+ */
+ tmp = (u32)(data[0]) << 16;
+ tmp |= (u32)(data[1]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset, tmp);
+ ram_offset += sizeof(u32);
+ for (i = 2; i < size; i += sizeof(u32)) {
+ tmp = (u32)(data[i + 0]);
+ if (i + 1 < size)
+ tmp |= (u32)(data[i + 1]) << 8;
+ if (i + 2 < size)
+ tmp |= (u32)(data[i + 2]) << 16;
+ if (i + 3 < size)
+ tmp |= (u32)(data[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset + i, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset,
+ size + sizeof(struct bcm43xx_plcp_hdr6));
+}
+
static void bcm43xx_write_beacon_template(struct bcm43xx_private *bcm,
u16 ram_offset,
- u16 shm_size_offset)
+ u16 shm_size_offset, u8 rate)
{
- u32 tmp;
- u16 i, size;
+ int len;
const u8 *data;
+ assert(bcm->cached_beacon);
+ len = min((size_t)bcm->cached_beacon->len,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
data = (const u8 *)(bcm->cached_beacon->data);
- size = min(bcm->cached_beacon->len, (unsigned int)17);
+ bcm43xx_write_template_common(bcm, data,
+ len, ram_offset,
+ shm_size_offset, rate);
+}
- for (i = 0; i < size; i += sizeof(u32)) {
- tmp = (u32)((data + i)[0]);
- tmp |= (u32)((data + i)[1]) << 8;
- tmp |= (u32)((data + i)[2]) << 16;
- tmp |= (u32)((data + i)[3]) << 24;
- bcm43xx_ram_write(bcm, ram_offset + i, tmp);
+static void bcm43xx_write_probe_resp_plcp(struct bcm43xx_private *bcm,
+ u16 shm_offset, u16 size, u8 rate)
+{
+ struct bcm43xx_plcp_hdr4 plcp;
+ u32 tmp;
+ u16 packet_time;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ /*
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 timings calculation.
+ *
+ * FIXME: long preamble assumed!
+ *
+ */
+ packet_time = 202 + (size + FCS_LEN) * 16 / rate;
+ if ((size + FCS_LEN) * 16 % rate >= rate / 2)
+ ++packet_time;
+
+ /* Write PLCP in two parts and timing for packet transfer */
+ tmp = le32_to_cpu(plcp.data);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset,
+ tmp & 0xFFFF);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 2,
+ tmp >> 16);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 6,
+ packet_time);
+}
+
+/* Instead of using custom probe response template, this function
+ * just patches custom beacon template by:
+ * 1) Changing packet type
+ * 2) Patching duration field
+ * 3) Stripping TIM
+ */
+static u8 * bcm43xx_generate_probe_resp(struct bcm43xx_private *bcm,
+ u16* dest_size, u8 rate)
+{
+ const u8 *src_data;
+ u8 *dest_data;
+ u16 src_size, elem_size, src_pos, dest_pos, tmp;
+
+ assert(bcm->cached_beacon);
+ src_size = bcm->cached_beacon->len;
+ src_data = (const u8*)bcm->cached_beacon->data;
+
+ if (unlikely(src_size < 0x24)) {
+ dprintk(KERN_ERR PFX "bcm43xx_generate_probe_resp: "
+ "invalid beacon\n");
+ return NULL;
+ }
+
+ dest_data = kmalloc(src_size, GFP_ATOMIC);
+ if (unlikely(!dest_data))
+ return NULL;
+
+ /* 0x24 is offset of first variable-len Information-Element
+ * in beacon frame.
+ */
+ memcpy(dest_data, src_data, 0x24);
+ src_pos = dest_pos = 0x24;
+ for ( ; src_pos < src_size - 2; src_pos += elem_size) {
+ elem_size = src_data[src_pos + 1] + 2;
+ if (src_data[src_pos] != 0x05) { /* TIM */
+ memcpy(dest_data + dest_pos, src_data + src_pos,
+ elem_size);
+ dest_pos += elem_size;
+ }
}
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
+ *dest_size = dest_pos;
+
+ /* Set the frame control. */
+ dest_data[0] = ((WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_PROBE_RESP << 4));
+ dest_data[1] = 0;
+
+ /* Set the duration field.
+ *
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 timings calculation.
+ *
+ * FIXME: long preamble assumed!
+ *
+ */
+ tmp = 202 + (14 + FCS_LEN) * 16 / rate;
+ if ((14 + FCS_LEN) * 16 % rate >= rate / 2)
+ ++tmp;
+
+ dest_data[2] = tmp & 0xFF;
+ dest_data[3] = (tmp >> 8) & 0xFF;
+
+ return dest_data;
+}
+
+static void bcm43xx_write_probe_resp_template(struct bcm43xx_private *bcm,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u8* probe_resp_data;
+ u16 size;
+
+ assert(bcm->cached_beacon);
+ size = bcm->cached_beacon->len;
+ probe_resp_data = bcm43xx_generate_probe_resp(bcm, &size, rate);
+ if (unlikely(!probe_resp_data))
+ return;
+
+ /* Looks like PLCP headers plus packet timings are stored for
+ * all possible basic rates
+ */
+ bcm43xx_write_probe_resp_plcp(bcm, 0x31A, size,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x32C, size,
+ BCM43xx_CCK_RATE_2MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x33E, size,
+ BCM43xx_CCK_RATE_5MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x350, size,
+ BCM43xx_CCK_RATE_11MB);
+
+ size = min((size_t)size,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
+ bcm43xx_write_template_common(bcm, probe_resp_data,
+ size, ram_offset,
+ shm_size_offset, rate);
+ kfree(probe_resp_data);
+}
+
+static int bcm43xx_refresh_cached_beacon(struct bcm43xx_private *bcm)
+{
+ struct ieee80211_tx_control control;
+
+ if (bcm->cached_beacon)
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
+ bcm->interface.if_id,
+ &control);
+ if (unlikely(!bcm->cached_beacon))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void bcm43xx_update_templates(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ assert(bcm->cached_beacon);
+
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_template(bcm, 0x268, 0x4A,
+ BCM43xx_CCK_RATE_11MB);
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
+ status |= 0x03;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
+}
+
+static void bcm43xx_refresh_templates(struct bcm43xx_private *bcm)
+{
+ int err;
+
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
+ return;
+ bcm43xx_update_templates(bcm);
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = NULL;
+}
+
+static void bcm43xx_set_ssid(struct bcm43xx_private *bcm,
+ const u8 *ssid, u8 ssid_len)
+{
+ u32 tmp;
+ u16 i, len;
+
+ len = min((u16)ssid_len, (u16)0x100);
+ for (i = 0; i < len; i += sizeof(u32)) {
+ tmp = (u32)(ssid[i + 0]);
+ if (i + 1 < len)
+ tmp |= (u32)(ssid[i + 1]) << 8;
+ if (i + 2 < len)
+ tmp |= (u32)(ssid[i + 2]) << 16;
+ if (i + 3 < len)
+ tmp |= (u32)(ssid[i + 3]) << 24;
+ bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+ 0x380 + i, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
+ 0x48, len);
+}
+
+static void bcm43xx_set_beacon_int(struct bcm43xx_private *bcm, u16 beacon_int)
+{
+ bcm43xx_time_lock(bcm);
+ if (bcm->current_core->rev >= 3) {
+ bcm43xx_write32(bcm, 0x188, (beacon_int << 16));
+ } else {
+ bcm43xx_write16(bcm, 0x606, (beacon_int >> 6));
+ bcm43xx_write16(bcm, 0x610, beacon_int);
+ }
+ bcm43xx_time_unlock(bcm);
}
static void handle_irq_beacon(struct bcm43xx_private *bcm)
{
u32 status;
+ int err;
bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
if (!bcm->cached_beacon) {
- struct ieee80211_tx_control control;
-
- /* No cached template available, yet.
- * Request the 80211 subsystem to generate a new beacon
- * frame and use it as template.
- */
- bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
- bcm->interface.if_id,
- &control);
- if (unlikely(!bcm->cached_beacon)) {
- dprintkl(KERN_WARNING PFX "Could not generate beacon template.\n");
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
goto ack;
- }
}
if ((status & 0x1) && (status & 0x2)) {
@@ -1571,18 +1807,20 @@
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
BCM43xx_IRQ_BEACON);
bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
- if (likely(bcm->cached_beacon))
+ if (bcm->cached_beacon)
kfree_skb(bcm->cached_beacon);
bcm->cached_beacon = NULL;
return;
}
if (!(status & 0x1)) {
- bcm43xx_write_beacon_template(bcm, 0x68, 0x18);
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x1;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
if (!(status & 0x2)) {
- bcm43xx_write_beacon_template(bcm, 0x468, 0x1A);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x2;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
@@ -4114,6 +4352,17 @@
radio->power_level = conf->power_level;
bcm43xx_phy_xmitpower(bcm);
}
+
+ if (conf->ssid_hidden) {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ | BCM43xx_SBF_NO_SSID_BCAST);
+ } else {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ & ~BCM43xx_SBF_NO_SSID_BCAST);
+ }
+
//FIXME: This does not seem to wake up:
#if 0
if (conf->power_level == 0) {
@@ -4128,6 +4377,11 @@
//TODO: phymode
//TODO: antennas
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ bcm43xx_set_beacon_int(bcm, conf->beacon_int);
+ bcm43xx_refresh_templates(bcm);
+ }
+
bcm43xx_unlock_irqonly(bcm, flags);
return 0;
@@ -4293,8 +4547,11 @@
bcm->interface.mac_addr = conf->mac_addr;
bcm->interface.type = conf->type;
}
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
bcm43xx_select_opmode(bcm);
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
+ bcm43xx_refresh_templates(bcm);
+ }
err = 0;
dprintk(KERN_INFO PFX "Virtual interface added "
@@ -4343,6 +4600,11 @@
if (conf->type != IEEE80211_IF_TYPE_MNTR) {
assert(bcm->interface.if_id == if_id);
bcm->interface.bssid = conf->bssid;
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ assert(conf->type == IEEE80211_IF_TYPE_AP);
+ bcm43xx_set_ssid(bcm, conf->ssid, conf->ssid_len);
+ bcm43xx_refresh_templates(bcm);
+ }
}
bcm43xx_unlock_irqsafe(bcm, flags);
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-13 21:06:01.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-18 18:43:12.000000000 +0200
@@ -112,14 +112,13 @@
return 0;
}
-static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
- const u16 octets, const u8 bitrate,
- const int ofdm_modulation)
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate)
{
__le32 *data = &(plcp->data);
__u8 *raw = plcp->raw;
- if (ofdm_modulation) {
+ if (bcm43xx_is_ofdm_rate(bitrate)) {
*data = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
assert(!(octets & 0xF000));
*data |= (octets << 5);
@@ -224,11 +223,9 @@
flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + FCS_LEN,
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
- flen, bitrate,
- !bcm43xx_is_cck_rate(bitrate));
+ flen, bitrate);
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
- flen, fallback_bitrate,
- !bcm43xx_is_cck_rate(fallback_bitrate));
+ flen, fallback_bitrate);
fctl = WLAN_FC_TYPE_CTRL << 2;
fctl |= WLAN_FC_STYPE_RTS << 4;
dur = le16_to_cpu(wlhdr->duration_id);
@@ -332,10 +329,9 @@
}
/* Generate the PLCP header and the fallback PLCP header. */
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),
- plcp_fragment_len,
- bitrate, ofdm_modulation);
+ plcp_fragment_len, bitrate);
bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,
- fallback_bitrate, fallback_ofdm_modulation);
+ fallback_bitrate);
/* Set the CONTROL field */
if (ofdm_modulation)
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-18 18:41:27.000000000 +0200
@@ -154,4 +154,7 @@
struct sk_buff *skb,
struct bcm43xx_rxhdr *rxhdr);
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate);
+
#endif /* BCM43xx_XMIT_H_ */
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-18 18:41:03.000000000 +0200
@@ -33,24 +33,6 @@
#include "bcm43xx.h"
-#ifdef CONFIG_BCM947XX
-#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
-
-static inline void e_aton(char *str, char *dest)
-{
- int i = 0;
- u16 *d = (u16 *) dest;
-
- for (;;) {
- dest[i++] = (char) simple_strtoul(str, NULL, 16);
- str += 2;
- if (!*str++ || i == 6)
- break;
- }
- for (i = 0; i < 3; i++)
- d[i] = cpu_to_be16(d[i]);
-}
-#endif
#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
@@ -143,6 +125,12 @@
rate == BCM43xx_CCK_RATE_11MB);
}
+static inline
+int bcm43xx_is_ofdm_rate(int rate)
+{
+ return !bcm43xx_is_cck_rate(rate);
+}
+
void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
--
Greetings Michael.
[-- Attachment #2: hostapd-dscape.patch --]
[-- Type: text/x-diff, Size: 1112 bytes --]
diff -urN hostapd-0.5-2006-06-10/driver_devicescape.c hostapd.new/driver_devicescape.c
--- hostapd-0.5-2006-06-10/driver_devicescape.c 2006-05-03 03:04:24.000000000 +0000
+++ hostapd.new/driver_devicescape.c 2006-06-12 21:17:10.000000000 +0000
@@ -1338,8 +1338,12 @@
return -1;
}
- memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
+ /* Enable management interface */
+ hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 1);
+ strcpy(drv->mgmt_iface, "wmgmt0");
+
+ memset(&ifr, 0, sizeof(ifr));
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
perror("ioctl(SIOCGIFINDEX)");
return -1;
@@ -1747,6 +1751,9 @@
/* Disable the radio. */
(void) hostap_ioctl_prism2param(drv, PRISM2_PARAM_RADIO_ENABLED, 0);
+ /* Disable management interface */
+ hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 0);
+
drv->hapd->driver = NULL;
(void) hostapd_set_iface_flags(drv, 0);
Files hostapd-0.5-2006-06-10/hostapd and hostapd.new/hostapd differ
[-- Attachment #3: d80211-ap-mode.patch --]
[-- Type: text/x-diff, Size: 438 bytes --]
diff -urN d80211.orig/ieee80211.c d80211/ieee80211.c
--- d80211.orig/ieee80211.c 2006-05-29 10:30:12.000000000 +0000
+++ d80211/ieee80211.c 2006-06-12 20:39:47.000000000 +0000
@@ -2534,7 +2534,7 @@
if (sdata->bss)
atomic_inc(&sdata->bss->num_sta_ps);
- sta->flags |= WLAN_STA_PS;
+ /* sta->flags |= WLAN_STA_PS; */
sta->pspoll = 0;
#ifdef IEEE80211_VERBOSE_DEBUG_PS
printk(KERN_DEBUG "%s: STA " MACSTR " aid %d enters power "
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-19 9:07 [PATCH, RFT] bcm43xx: AccessPoint mode Michael Buesch
@ 2006-06-22 15:30 ` Jiri Benc
2006-06-22 19:08 ` Alexander Tsvyashchenko
2006-06-23 18:19 ` hostapd patch for d80211 Jiri Benc
2006-06-28 19:27 ` [PATCH, RFT] bcm43xx: AccessPoint mode Francois Barre
2 siblings, 1 reply; 10+ messages in thread
From: Jiri Benc @ 2006-06-22 15:30 UTC (permalink / raw)
To: Michael Buesch
Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko, Francois Barre
On Mon, 19 Jun 2006 11:07:34 +0200, Michael Buesch wrote:
> Well, it does not work 100%, but at least it's very promising.
> We are able to create a bssid and correctly send beacon frames out.
Great work! I was even able to ping. (Tried only open system
authentication for now, it seems it works quite well.)
> Please give it a testrun.
> Final note about hostapd:
> "hostapd snapshot 0.5-2006-06-10" seems to "work" in the sense
> that it is able to bring up the device.
> "hostapd snapshot 0.5-2006-06-11" seems to fail.
0.5-2006-06-19 works with the patch.
> Important notes from Alexander Tsvyashchenko's initial mail follow:
> [...]
> Although my previous patch to hostapd to make it interoperable with
> bcm43xx & dscape has been merged already in their CVS version, due to
> the subsequent changes in dscape stack current hostapd is again
> incompartible :-( So, to test this patch, the patch to hostapd should be
> applied.
Or, if you don't want to patch hostapd (untested, but should work):
iwpriv wlan0 param 1046 1
ip link set wmgmt0 name wmaster0ap
hostapd /path/to/hostapd.conf
iwpriv wlan0 param 1046 0
> I used hostapd snapshot 0.5-2006-06-10, patch for it is attached.
> The patch is very hacky and requires tricky way to bring everything up,
> but as dscape stack is changed quite constantly, I just do not want to
> waste time fixing it in "proper" way only to find a week later that
> dscape handling of master interface was changed completely once more and
> everything is broken again ;-)
Hopefully we will convert the whole hostapd<->stack communication to
netlink in some near future ;-)
> 2) Insert modules (80211, rate_control and bcm43xx-d80211)
modprobe bcm43xx-d80211 is enough, other modules will load
automatically.
> 4) "ifconfig wlan0 up" (this should be done by hostapd actually, but
> its operation with current dscape stack seems to be broken)
hostapd tries to open (put to 'up' state) wmgmt0 earlier than wlan0,
which is not possible. It should open wlan0 first; even more, opening of
wmgmt0 is not necessary as it will be opened automatically when wlan0 is
opened.
> 6) "iwconfig wlan0 essid <your-SSID-name>" (this also should not be
> required, but current combination of hostapd + dscape doesn't seem to
> generate config_interface callback when setting beacon, so this is
> required just to force call of config_interface).
The stack currently has very limited support for cards with "beacon
templates". ieee80211_beacon_get function is not designed in a way it is
used in bcm43xx. Although this seems to be easy to fix now, we will run
into other problems later (with TIM elements mainly).
I need to look how PS mode works in bcm chipsets to find a correct
solution for this. Do you have any ideas?
Thanks,
Jiri
--
Jiri Benc
SUSE Labs
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-22 15:30 ` Jiri Benc
@ 2006-06-22 19:08 ` Alexander Tsvyashchenko
2006-06-23 11:26 ` Jiri Benc
0 siblings, 1 reply; 10+ messages in thread
From: Alexander Tsvyashchenko @ 2006-06-22 19:08 UTC (permalink / raw)
To: Jiri Benc, Michael Buesch
Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko, Francois Barre
Hello Jiri,
On 6/22/2006, "Jiri Benc" <jbenc@suse.cz> wrote:
>Great work! I was even able to ping. (Tried only open system
>authentication for now, it seems it works quite well.)
Well, I use first version of this patch from the end of April, and had no
problems so far, so,
while it's probably cannot be really called "stable" yet, it's at
least 'working somehow" ;-)
>Or, if you don't want to patch hostapd (untested, but should work):
>
>iwpriv wlan0 param 1046 1
>ip link set wmgmt0 name wmaster0ap
>hostapd /path/to/hostapd.conf
>iwpriv wlan0 param 1046 0
Thanks for the information! This is easier way indeed ;-)
>Hopefully we will convert the whole hostapd<->stack communication to
>netlink in some near future ;-)
Yes, it would be nice if things get a bit more settled & stable there ;-)
>> 2) Insert modules (80211, rate_control and bcm43xx-d80211)
>
>modprobe bcm43xx-d80211 is enough, other modules will load
>automatically.
I just had no modprobe on my test system, that's why I listed all of
them separately ;-)
But yes, for "normal" usage modprobe is easier.
>> 6) "iwconfig wlan0 essid <your-SSID-name>" (this also should not be
>> required, but current combination of hostapd + dscape doesn't seem to
>> generate config_interface callback when setting beacon, so this is
>> required just to force call of config_interface).
>
>The stack currently has very limited support for cards with "beacon
>templates". ieee80211_beacon_get function is not designed in a way it is
>used in bcm43xx. Although this seems to be easy to fix now, we will run
>into other problems later (with TIM elements mainly).
>I need to look how PS mode works in bcm chipsets to find a correct
>solution for this. Do you have any ideas?
Well, current use of ieee80211_beacon_get in bcm43xx is plain wrong
indeed,
it just happens that it seems to work anyway ;-)
As for the PS, the main problem currently seems to be the lack of hardware
specifications: quite some things that are needed to make it work are
unknown.
The information/speculations I have so far
(please note my understanding of 802.11 specs is very limited!!!):
1) TIM seems to be generated by software (I think it was confirmed by smb
from specs group).
2) DTIM counter in beacons sent is updated by hardware (confirmed by
specs group).
3) There is PS interrupt that in my experiments seemed to correlate with
the beacon interval
(one PS interrupt for one beacon sent?)
My original idea was that it could be used to update beacon template, but
specs group seemed
to be sceptical about this idea saying that in original driver the beacon
template was not updated
in PS interrupt handler.
Now I think that it's, probably, not necessary to update beacon template
exactly before/after current
beacon is sent, as the reason to update beacon is only change in TIM, and
we can just update
template as soon as TIM is changed (so, some sort of callback from dscape
to the driver is needed).
However, this PS interrupt could be used for sending broadcast packets
(which, as far as I understood
from 802.11 specs, should be sent after DTIM beacon). To use it for this
purpose, we need the following information:
a) Confirmation that PS interrupt is invoked exactly after current
beacon is sent.
b) The way to know whether current beacon was DTIM or not.
I do not have answers to these questions so far :-(
Yet another idea (which still should be checked) is that probably, PS
interrupt is invoked not for every beacon,
but for DTIM beacons only (I'm not sure that in my experiments I had
DTIM interval larger than beacon interval,
so it's possible every TIM was DTIM, that's why PS interrupt was called
for every beacon).
There's yet another interrupt that I currently don't fully understand -
beacon update interrupt, I did not see it called at all
so far, so I don't know where/how it could be used.
All other PS things seem to be relatively OK - there's also some support
in hardware for processing entering/exiting
PS mode for STAs, but these packets seem to be passed to dscape layer
also, and as they are already processed
in dscape, it looks like there's no need to bother with using hardware
for that.
Currently I just have not enough time to finish the experiments with PS,
and anyway I'm afraid some of these
things can be a bit hard to find out by experimenting only :-(
Good luck! Alexander
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-22 19:08 ` Alexander Tsvyashchenko
@ 2006-06-23 11:26 ` Jiri Benc
0 siblings, 0 replies; 10+ messages in thread
From: Jiri Benc @ 2006-06-23 11:26 UTC (permalink / raw)
To: Alexander Tsvyashchenko
Cc: Michael Buesch, bcm43xx-dev, netdev, Francois Barre
Hi Alexander,
thanks for valuable informations!
On Thu, 22 Jun 2006 23:08:10 +0400, Alexander Tsvyashchenko wrote:
> As for the PS, the main problem currently seems to be the lack of hardware
> specifications: quite some things that are needed to make it work are
> unknown.
I tried to look at bcm43xx specs but didn't find how TIM (or TIM bitmap)
is updated by the stack.
> The information/speculations I have so far
> (please note my understanding of 802.11 specs is very limited!!!):
>
> 1) TIM seems to be generated by software (I think it was confirmed by smb
> from specs group).
You mean Bitmap Control and Partial Virtual Bitmap fields of TIM, right?
> 2) DTIM counter in beacons sent is updated by hardware (confirmed by
> specs group).
>
> 3) There is PS interrupt that in my experiments seemed to correlate with
> the beacon interval
> (one PS interrupt for one beacon sent?)
This seems to be important. Is this generated after every beacon or
after DTIM only?
> My original idea was that it could be used to update beacon template, but
> specs group seemed
> to be sceptical about this idea saying that in original driver the beacon
> template was not updated
> in PS interrupt handler.
Especially if this is called after the beacon is set (or while is being
transmitted), there is no sense in updating beacon template in that
interrupt handler.
> Now I think that it's, probably, not necessary to update beacon template
> exactly before/after current
> beacon is sent, as the reason to update beacon is only change in TIM, and
> we can just update
> template as soon as TIM is changed (so, some sort of callback from dscape
> to the driver is needed).
You mean to update TIM each time a packet for PS-enabled STA arrives? It
doesn't look like a good idea to me. Maybe some caching can be performed
(e.g. update only for the first frame to each PS-enabled STA in a given
DTIM period) but it's probably still too bad performance - imagine a
situation with a lot of PS-enabled STAs.
> However, this PS interrupt could be used for sending broadcast packets
> (which, as far as I understood
> from 802.11 specs, should be sent after DTIM beacon). To use it for this
> purpose, we need the following information:
>
> a) Confirmation that PS interrupt is invoked exactly after current
> beacon is sent.
> b) The way to know whether current beacon was DTIM or not.
This is a problem only if that interrupt is generated after each beacon.
In such case, the stack is able to tell you this (though we need to be
sure it is in sync with the hardware) - look at the comment before
ieee80211_get_buffered_bc function in d80211.h. It's not useful for
bcm43xx in the current form but it can be easily extended (some
ieee80211_report_sent_beacon function).
> [...]
> All other PS things seem to be relatively OK - there's also some support
> in hardware for processing entering/exiting
> PS mode for STAs, but these packets seem to be passed to dscape layer
> also, and as they are already processed
> in dscape, it looks like there's no need to bother with using hardware
> for that.
Are you sure that hardware functionality is not used for generating TIM
bitmap?
Thanks,
Jiri
--
Jiri Benc
SUSE Labs
^ permalink raw reply [flat|nested] 10+ messages in thread
* hostapd patch for d80211
2006-06-19 9:07 [PATCH, RFT] bcm43xx: AccessPoint mode Michael Buesch
2006-06-22 15:30 ` Jiri Benc
@ 2006-06-23 18:19 ` Jiri Benc
2006-06-23 21:13 ` Michael Buesch
2006-06-24 2:17 ` Jouni Malinen
2006-06-28 19:27 ` [PATCH, RFT] bcm43xx: AccessPoint mode Francois Barre
2 siblings, 2 replies; 10+ messages in thread
From: Jiri Benc @ 2006-06-23 18:19 UTC (permalink / raw)
To: Michael Buesch
Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko, Francois Barre,
Jouni Malinen
On Mon, 19 Jun 2006 11:07:34 +0200, Michael Buesch wrote:
> Important notes from Alexander Tsvyashchenko's initial mail follow:
> [...]
> Although my previous patch to hostapd to make it interoperable with
> bcm43xx & dscape has been merged already in their CVS version, due to
> the subsequent changes in dscape stack current hostapd is again
> incompartible :-(
This patch allows devicescape driver in hostapd to work with recent d80211.
No manipulation with network interfaces is needed anymore - hostapd even
switches the interface to AP mode automatically now. Just modprobe
bcm43xx-d80211, run hostapd and enjoy :-)
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
driver_devicescape.c | 77 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 64 insertions(+), 13 deletions(-)
--- hostapd-0.5-2006-06-19.orig/driver_devicescape.c
+++ hostapd-0.5-2006-06-19/driver_devicescape.c
@@ -73,6 +73,7 @@ struct i802_driver_data {
char iface[IFNAMSIZ + 1];
char mgmt_iface[IFNAMSIZ + 1];
+ int mgmt_ifindex;
int sock; /* raw packet socket for driver access */
int ioctl_sock; /* socket for ioctl() use */
int wext_sock; /* socket for wireless events */
@@ -88,6 +89,21 @@ static const struct driver_ops devicesca
static int i802_sta_set_flags(void *priv, const u8 *addr,
int flags_or, int flags_and);
+static int i802_set_ap_mode(struct i802_driver_data *drv)
+{
+ struct iwreq iwr;
+
+ memset(&iwr, 0, sizeof(iwr));
+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+ iwr.u.mode = IW_MODE_MASTER;
+
+ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
+ perror("ioctl[SIOCSIWMODE]");
+ return -1;
+ }
+
+ return 0;
+}
static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
{
@@ -96,13 +112,16 @@ static int hostapd_set_iface_flags(struc
if (drv->ioctl_sock < 0)
return -1;
+ if (dev_up)
+ i802_set_ap_mode(drv);
+
memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->mgmt_iface);
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface);
if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
perror("ioctl[SIOCGIFFLAGS]");
wpa_printf(MSG_DEBUG, "Could not read interface flags (%s)",
- drv->mgmt_iface);
+ drv->iface);
return -1;
}
@@ -303,7 +322,35 @@ static int hostap_ioctl_prism2param(stru
return hostap_ioctl_prism2param_iface(drv->iface, drv, param, value);
}
-
+static int hostap_ioctl_get_prism2param_iface(const char *iface,
+ struct i802_driver_data *drv,
+ int param)
+{
+ struct iwreq iwr;
+ int *i;
+
+ memset(&iwr, 0, sizeof(iwr));
+ strncpy(iwr.ifr_name, iface, IFNAMSIZ);
+ i = (int *) iwr.u.name;
+ *i = param;
+
+ if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_GET_PRISM2_PARAM, &iwr) < 0) {
+ char buf[128];
+ snprintf(buf, sizeof(buf),
+ "%s: ioctl[PRISM2_IOCTL_GET_PRISM2_PARAM]", iface);
+ perror(buf);
+ return -1;
+ }
+
+ return *i;
+}
+
+static int hostap_ioctl_get_prism2param(struct i802_driver_data *drv,
+ int param)
+{
+ return hostap_ioctl_get_prism2param_iface(drv->iface, drv, param);
+}
+
static int i802_set_ssid(void *priv, const u8 *buf, int len)
{
struct i802_driver_data *drv = priv;
@@ -1338,12 +1385,20 @@ static int i802_init_sockets(struct i802
return -1;
}
+ /* Enable management interface */
+ if (hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 1) < 0)
+ return -1;
+ drv->mgmt_ifindex =
+ hostap_ioctl_get_prism2param(drv, PRISM2_PARAM_MGMT_IF);
+ if (drv->mgmt_ifindex < 0)
+ return -1;
memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
- if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
- perror("ioctl(SIOCGIFINDEX)");
+ ifr.ifr_ifindex = drv->mgmt_ifindex;
+ if (ioctl(drv->ioctl_sock, SIOCGIFNAME, &ifr) != 0) {
+ perror("ioctl(SIOCGIFNAME)");
return -1;
}
+ snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface), "%s", ifr.ifr_name);
if (hostapd_set_iface_flags(drv, 1))
return -1;
@@ -1716,13 +1771,6 @@ static int i802_init(struct hostapd_data
drv->ops = devicescape_driver_ops;
drv->hapd = hapd;
memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
- if (strncmp(hapd->conf->iface, "wlan", 4) == 0) {
- snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface),
- "wmaster%sap", hapd->conf->iface + 4);
- } else {
- snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface),
- "%sap", hapd->conf->iface);
- }
if (i802_init_sockets(drv))
goto failed;
@@ -1751,6 +1799,9 @@ static void i802_deinit(void *priv)
(void) hostapd_set_iface_flags(drv, 0);
+ /* Disable management interface */
+ hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 0);
+
if (drv->sock >= 0)
close(drv->sock);
if (drv->ioctl_sock >= 0)
--
Jiri Benc
SUSE Labs
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: hostapd patch for d80211
2006-06-23 18:19 ` hostapd patch for d80211 Jiri Benc
@ 2006-06-23 21:13 ` Michael Buesch
2006-06-24 2:17 ` Jouni Malinen
1 sibling, 0 replies; 10+ messages in thread
From: Michael Buesch @ 2006-06-23 21:13 UTC (permalink / raw)
To: Jiri Benc
Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko, Francois Barre,
Jouni Malinen
On Friday 23 June 2006 20:19, Jiri Benc wrote:
> On Mon, 19 Jun 2006 11:07:34 +0200, Michael Buesch wrote:
> > Important notes from Alexander Tsvyashchenko's initial mail follow:
> > [...]
> > Although my previous patch to hostapd to make it interoperable with
> > bcm43xx & dscape has been merged already in their CVS version, due to
> > the subsequent changes in dscape stack current hostapd is again
> > incompartible :-(
>
> This patch allows devicescape driver in hostapd to work with recent d80211.
> No manipulation with network interfaces is needed anymore - hostapd even
> switches the interface to AP mode automatically now. Just modprobe
> bcm43xx-d80211, run hostapd and enjoy :-)
>
> Signed-off-by: Jiri Benc <jbenc@suse.cz>
Well, if it works.... Jouni, please apply.
I did not test it. But I trust Jiri. If he says it works, then
it does work :)
> ---
>
> driver_devicescape.c | 77 ++++++++++++++++++++++++++++++++++++++++++---------
> 1 files changed, 64 insertions(+), 13 deletions(-)
>
> --- hostapd-0.5-2006-06-19.orig/driver_devicescape.c
> +++ hostapd-0.5-2006-06-19/driver_devicescape.c
> @@ -73,6 +73,7 @@ struct i802_driver_data {
>
> char iface[IFNAMSIZ + 1];
> char mgmt_iface[IFNAMSIZ + 1];
> + int mgmt_ifindex;
> int sock; /* raw packet socket for driver access */
> int ioctl_sock; /* socket for ioctl() use */
> int wext_sock; /* socket for wireless events */
> @@ -88,6 +89,21 @@ static const struct driver_ops devicesca
> static int i802_sta_set_flags(void *priv, const u8 *addr,
> int flags_or, int flags_and);
>
> +static int i802_set_ap_mode(struct i802_driver_data *drv)
> +{
> + struct iwreq iwr;
> +
> + memset(&iwr, 0, sizeof(iwr));
> + strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
> + iwr.u.mode = IW_MODE_MASTER;
> +
> + if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
> + perror("ioctl[SIOCSIWMODE]");
> + return -1;
> + }
> +
> + return 0;
> +}
>
> static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
> {
> @@ -96,13 +112,16 @@ static int hostapd_set_iface_flags(struc
> if (drv->ioctl_sock < 0)
> return -1;
>
> + if (dev_up)
> + i802_set_ap_mode(drv);
> +
> memset(&ifr, 0, sizeof(ifr));
> - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->mgmt_iface);
> + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface);
>
> if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
> perror("ioctl[SIOCGIFFLAGS]");
> wpa_printf(MSG_DEBUG, "Could not read interface flags (%s)",
> - drv->mgmt_iface);
> + drv->iface);
> return -1;
> }
>
> @@ -303,7 +322,35 @@ static int hostap_ioctl_prism2param(stru
> return hostap_ioctl_prism2param_iface(drv->iface, drv, param, value);
> }
>
> -
> +static int hostap_ioctl_get_prism2param_iface(const char *iface,
> + struct i802_driver_data *drv,
> + int param)
> +{
> + struct iwreq iwr;
> + int *i;
> +
> + memset(&iwr, 0, sizeof(iwr));
> + strncpy(iwr.ifr_name, iface, IFNAMSIZ);
> + i = (int *) iwr.u.name;
> + *i = param;
> +
> + if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_GET_PRISM2_PARAM, &iwr) < 0) {
> + char buf[128];
> + snprintf(buf, sizeof(buf),
> + "%s: ioctl[PRISM2_IOCTL_GET_PRISM2_PARAM]", iface);
> + perror(buf);
> + return -1;
> + }
> +
> + return *i;
> +}
> +
> +static int hostap_ioctl_get_prism2param(struct i802_driver_data *drv,
> + int param)
> +{
> + return hostap_ioctl_get_prism2param_iface(drv->iface, drv, param);
> +}
> +
> static int i802_set_ssid(void *priv, const u8 *buf, int len)
> {
> struct i802_driver_data *drv = priv;
> @@ -1338,12 +1385,20 @@ static int i802_init_sockets(struct i802
> return -1;
> }
>
> + /* Enable management interface */
> + if (hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 1) < 0)
> + return -1;
> + drv->mgmt_ifindex =
> + hostap_ioctl_get_prism2param(drv, PRISM2_PARAM_MGMT_IF);
> + if (drv->mgmt_ifindex < 0)
> + return -1;
> memset(&ifr, 0, sizeof(ifr));
> - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
> - if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
> - perror("ioctl(SIOCGIFINDEX)");
> + ifr.ifr_ifindex = drv->mgmt_ifindex;
> + if (ioctl(drv->ioctl_sock, SIOCGIFNAME, &ifr) != 0) {
> + perror("ioctl(SIOCGIFNAME)");
> return -1;
> }
> + snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface), "%s", ifr.ifr_name);
>
> if (hostapd_set_iface_flags(drv, 1))
> return -1;
> @@ -1716,13 +1771,6 @@ static int i802_init(struct hostapd_data
> drv->ops = devicescape_driver_ops;
> drv->hapd = hapd;
> memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
> - if (strncmp(hapd->conf->iface, "wlan", 4) == 0) {
> - snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface),
> - "wmaster%sap", hapd->conf->iface + 4);
> - } else {
> - snprintf(drv->mgmt_iface, sizeof(drv->mgmt_iface),
> - "%sap", hapd->conf->iface);
> - }
>
> if (i802_init_sockets(drv))
> goto failed;
> @@ -1751,6 +1799,9 @@ static void i802_deinit(void *priv)
>
> (void) hostapd_set_iface_flags(drv, 0);
>
> + /* Disable management interface */
> + hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 0);
> +
> if (drv->sock >= 0)
> close(drv->sock);
> if (drv->ioctl_sock >= 0)
>
>
--
Greetings Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: hostapd patch for d80211
2006-06-23 18:19 ` hostapd patch for d80211 Jiri Benc
2006-06-23 21:13 ` Michael Buesch
@ 2006-06-24 2:17 ` Jouni Malinen
1 sibling, 0 replies; 10+ messages in thread
From: Jouni Malinen @ 2006-06-24 2:17 UTC (permalink / raw)
To: Jiri Benc
Cc: Michael Buesch, bcm43xx-dev, netdev, Alexander Tsvyashchenko,
Francois Barre, Jouni Malinen
On Fri, Jun 23, 2006 at 08:19:33PM +0200, Jiri Benc wrote:
> This patch allows devicescape driver in hostapd to work with recent d80211.
> No manipulation with network interfaces is needed anymore - hostapd even
> switches the interface to AP mode automatically now. Just modprobe
> bcm43xx-d80211, run hostapd and enjoy :-)
Thanks! Unfortunately, I have been stuck with couple of other projects
lately and have been unable to keep up to date with all changes in
wireless-dev. Anyway, I'm hoping to do some more merging next week and
I'll add this to the list. I think that a similar change was already in
my pending merge queue from Devicescape, but anyway, either this patch
or something similar will end up into hostapd repository.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-19 9:07 [PATCH, RFT] bcm43xx: AccessPoint mode Michael Buesch
2006-06-22 15:30 ` Jiri Benc
2006-06-23 18:19 ` hostapd patch for d80211 Jiri Benc
@ 2006-06-28 19:27 ` Francois Barre
2006-06-28 19:39 ` Michael Buesch
2 siblings, 1 reply; 10+ messages in thread
From: Francois Barre @ 2006-06-28 19:27 UTC (permalink / raw)
To: Michael Buesch; +Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko
Hi all,
Sorry for answering years after the patch post, I didn't have time to
test this take2 patch before. I had a first look at it a couple of
days ago, but... you know, that was not my day.
> Well, it does not work 100%, but at least it's very promising.
> We are able to create a bssid and correctly send beacon frames out.
[...]
For my very own situation, that is :
- Apple Mini with a BCM 4306 (BigEndian)
- Linux/Win32 boxes with USB and PCMCIA wifi cards (mostly 802.11b usb
at the moment)
Current status is this one :
- master mode functionnal
- dhcp serving, good uptime
- no encryption, WEP or WPA of any kind tested yet
- a nice 1.2MB/s bandwidth (I'm testing with a 802.11b at client side,
and AFAIK, bcm43xx does not handle 802.11g yet, does it ?)
*BUT* a big issue : I got a per-connection hang-up at client side on
strong workloads, for both win32 and linux client side, with my usb
dongle (which is running ndiswrapper on *nux, sorry for that, I'm
ashamed of it, silly me, I know, but well... No choice, and the device
was given me free of charge so...).
Typical scenario is a ssh session on one hand and a ftp transfer on
the other. The ftp hangs, while the ssh session stays up and going.
I got no problem with the PCMCIA card (a rock-solid WG511T), on both
linux and win32.
Of course, the bcm43xx does not say anything about this (if it had
said so, I would have posted logs along with this complain), so my
conclusion would be :
Why on earth is this a per-connection issue ? where do I miss
something ? if I'm really missing packets on one connection, why is
the other one continuing to live ? I may have forgotten a subtle
detail of the TCP/IP behaviour here... Or may that be all about window
scaling and fragmentation ? I can not see anything else... I would at
least like to know what to test, as I'm a little bit confused here.
Yes, I'll try to dig around the ip window and timeout stuff by tonight...
Anyway, I would like to thank again and again Alexander and Michael
for the work done, that is really impressive. Great work !
Best regards,
F. B.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-28 19:27 ` [PATCH, RFT] bcm43xx: AccessPoint mode Francois Barre
@ 2006-06-28 19:39 ` Michael Buesch
2006-06-28 19:50 ` Francois Barre
0 siblings, 1 reply; 10+ messages in thread
From: Michael Buesch @ 2006-06-28 19:39 UTC (permalink / raw)
To: Francois Barre; +Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko
On Wednesday 28 June 2006 21:27, Francois Barre wrote:
> Hi all,
>
> Sorry for answering years after the patch post, I didn't have time to
> test this take2 patch before. I had a first look at it a couple of
> days ago, but... you know, that was not my day.
>
> > Well, it does not work 100%, but at least it's very promising.
> > We are able to create a bssid and correctly send beacon frames out.
> [...]
>
> For my very own situation, that is :
> - Apple Mini with a BCM 4306 (BigEndian)
> - Linux/Win32 boxes with USB and PCMCIA wifi cards (mostly 802.11b usb
> at the moment)
>
> Current status is this one :
> - master mode functionnal
> - dhcp serving, good uptime
> - no encryption, WEP or WPA of any kind tested yet
> - a nice 1.2MB/s bandwidth (I'm testing with a 802.11b at client side,
> and AFAIK, bcm43xx does not handle 802.11g yet, does it ?)
>
> *BUT* a big issue : I got a per-connection hang-up at client side on
> strong workloads, for both win32 and linux client side, with my usb
> dongle (which is running ndiswrapper on *nux, sorry for that, I'm
> ashamed of it, silly me, I know, but well... No choice, and the device
> was given me free of charge so...).
> Typical scenario is a ssh session on one hand and a ftp transfer on
> the other. The ftp hangs, while the ssh session stays up and going.
>
> I got no problem with the PCMCIA card (a rock-solid WG511T), on both
> linux and win32.
>
> Of course, the bcm43xx does not say anything about this (if it had
> said so, I would have posted logs along with this complain), so my
> conclusion would be :
>
> Why on earth is this a per-connection issue ? where do I miss
> something ? if I'm really missing packets on one connection, why is
> the other one continuing to live ? I may have forgotten a subtle
> detail of the TCP/IP behaviour here...
Well, I doubt it is a bcm43xx issue. But maybe. Not sure.
Do you run some QoS stuff? Some other quota stuff?
--
Greetings Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH, RFT] bcm43xx: AccessPoint mode
2006-06-28 19:39 ` Michael Buesch
@ 2006-06-28 19:50 ` Francois Barre
0 siblings, 0 replies; 10+ messages in thread
From: Francois Barre @ 2006-06-28 19:50 UTC (permalink / raw)
To: Michael Buesch; +Cc: bcm43xx-dev, netdev, Alexander Tsvyashchenko
>
> Well, I doubt it is a bcm43xx issue. But maybe. Not sure.
>
> Do you run some QoS stuff? Some other quota stuff?
>
Yes, a special QoS rule that cuts off connections from devices that do
not use a GPL driver.
Long life to the penguin !
Soon, my HiFi will cut off the whole drum section of the DRM songs
I'll ask it to play, and I'm thinking about how to teach my oven not
to bake GM Food :-p.
More seriously, no, I do not have any QoS nor quota service running.
Instead, I was more thinking about a beacon at high rates, but I do not have
enough 802.11 knowledge to know what is advertised during connection...
Maybe the netdev guys would have a clue, a tool, or a bright idea ?
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-06-28 19:51 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-19 9:07 [PATCH, RFT] bcm43xx: AccessPoint mode Michael Buesch
2006-06-22 15:30 ` Jiri Benc
2006-06-22 19:08 ` Alexander Tsvyashchenko
2006-06-23 11:26 ` Jiri Benc
2006-06-23 18:19 ` hostapd patch for d80211 Jiri Benc
2006-06-23 21:13 ` Michael Buesch
2006-06-24 2:17 ` Jouni Malinen
2006-06-28 19:27 ` [PATCH, RFT] bcm43xx: AccessPoint mode Francois Barre
2006-06-28 19:39 ` Michael Buesch
2006-06-28 19:50 ` Francois Barre
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).