For convenience, here are the patches for each driver. johannes
--- wireless-dev.orig/drivers/net/wireless/adm8211.c 2007-08-16 16:51:20.493468950 +0200 +++ wireless-dev/drivers/net/wireless/adm8211.c 2007-08-16 16:56:13.153468950 +0200 @@ -349,25 +349,47 @@ static int adm8211_get_stats(struct ieee return 0; } -static void adm8211_set_rx_mode(struct ieee80211_hw *dev, - unsigned short flags, int mc_count) +static void adm8211_set_bssid(struct ieee80211_hw *dev, u8 *bssid) +{ + struct adm8211_priv *priv = dev->priv; + u32 reg; + + reg = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24); + ADM8211_CSR_WRITE(BSSID0, reg); + reg = ADM8211_CSR_READ(ABDA1); + reg &= 0x0000ffff; + reg |= (bssid[4] << 16) | (bssid[5] << 24); + ADM8211_CSR_WRITE(ABDA1, reg); +} + +static void adm8211_configure_filter(struct ieee80211_hw *dev, + int multi_count, + unsigned int changed, + unsigned int *flags) { struct adm8211_priv *priv = dev->priv; unsigned int bit_nr; __le32 mc_filter[2]; struct dev_mc_list *mclist; void *tmp; + int change = 0; + u8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - mc_filter[1] = mc_filter[0] = 0; - if (flags & IFF_PROMISC) { + /* TODO: honour more flags */ + + mc_filter[1] = mc_filter[0] = 0; + + if (*flags & FIF_PROMISC_IN_BSS) { priv->nar |= ADM8211_NAR_PR; priv->nar &= ~ADM8211_NAR_MM; mc_filter[1] = mc_filter[0] = cpu_to_le32(~0); - } else if ((flags & IFF_ALLMULTI) || (mc_count > -1)) { + change = 1; + } else if (*flags & FIF_ALLMULTI) { priv->nar &= ~ADM8211_NAR_PR; priv->nar |= ADM8211_NAR_MM; mc_filter[1] = mc_filter[0] = cpu_to_le32(~0); - } else { + change = 1; + } else if (multi_count >= 0) { priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR); mc_filter[1] = mc_filter[0] = 0; mclist = NULL; @@ -377,15 +399,27 @@ static void adm8211_set_rx_mode(struct i bit_nr &= 0x3F; mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); } + change = 1; } - ADM8211_IDLE_RX(); + *flags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; - ADM8211_CSR_WRITE(MAR0, mc_filter[0]); - ADM8211_CSR_WRITE(MAR1, mc_filter[1]); - ADM8211_CSR_READ(NAR); + if (change & FIF_BCN_PRBRESP_PROMISC) { + if (*flags & FIF_BCN_PRBRESP_PROMISC) + adm8211_set_bssid(dev, bcast_addr); + else + adm8211_set_bssid(dev, priv->bssid); + } - ADM8211_RESTORE(); + if (change) { + ADM8211_IDLE_RX(); + + ADM8211_CSR_WRITE(MAR0, mc_filter[0]); + ADM8211_CSR_WRITE(MAR1, mc_filter[1]); + ADM8211_CSR_READ(NAR); + + ADM8211_RESTORE(); + } } static int adm8211_get_tx_stats(struct ieee80211_hw *dev, @@ -1414,19 +1448,6 @@ static void adm8211_set_interval(struct ADM8211_CSR_WRITE(BPLI, reg); } -static void adm8211_set_bssid(struct ieee80211_hw *dev, u8 *bssid) -{ - struct adm8211_priv *priv = dev->priv; - u32 reg; - - reg = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24); - ADM8211_CSR_WRITE(BSSID0, reg); - reg = ADM8211_CSR_READ(ABDA1); - reg &= 0x0000ffff; - reg |= (bssid[4] << 16) | (bssid[5] << 24); - ADM8211_CSR_WRITE(ABDA1, reg); -} - static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len) { struct adm8211_priv *priv = dev->priv; @@ -1502,6 +1523,8 @@ static void adm8211_remove_interface(str { struct adm8211_priv *priv = dev->priv; priv->mode = IEEE80211_IF_TYPE_MGMT; + + /* TODO: clear MAC address */ } static int adm8211_init_rings(struct ieee80211_hw *dev) @@ -1585,7 +1608,7 @@ static void adm8211_free_rings(struct ie } } -static int adm8211_open(struct ieee80211_hw *dev) +static int adm8211_start(struct ieee80211_hw *dev) { struct adm8211_priv *priv = dev->priv; int retval; @@ -1628,7 +1651,7 @@ fail: return retval; } -static int adm8211_stop(struct ieee80211_hw *dev) +static void adm8211_stop(struct ieee80211_hw *dev) { struct adm8211_priv *priv = dev->priv; @@ -1640,7 +1663,6 @@ static int adm8211_stop(struct ieee80211 free_irq(priv->pdev->irq, dev); adm8211_free_rings(dev); - return 0; } static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int len, @@ -1841,13 +1863,13 @@ static int adm8211_alloc_rings(struct ie static const struct ieee80211_ops adm8211_ops = { .tx = adm8211_tx, - .open = adm8211_open, + .start = adm8211_start, .stop = adm8211_stop, .add_interface = adm8211_add_interface, .remove_interface = adm8211_remove_interface, .config = adm8211_config, .config_interface = adm8211_config_interface, - .set_multicast_list = adm8211_set_rx_mode, + .configure_filter = adm8211_configure_filter, .get_stats = adm8211_get_stats, .get_tx_stats = adm8211_get_tx_stats, .get_tsf = adm8211_get_tsft @@ -1953,7 +1975,8 @@ static int __devinit adm8211_probe(struc SET_IEEE80211_PERM_ADDR(dev, perm_addr); dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); - dev->flags = IEEE80211_HW_WEP_INCLUDE_IV | IEEE80211_HW_NO_TKIP_WMM_HWACCEL; + dev->flags = IEEE80211_HW_WEP_INCLUDE_IV | IEEE80211_HW_NO_TKIP_WMM_HWACCEL | + IEEE80211_HW_MULTICAST_FILTER; // however, IEEE80211_HW_RX_INCLUDES_FCS in promisc mode dev->channel_change_time = 1000; @@ -2082,7 +2105,7 @@ static int adm8211_resume(struct pci_dev pci_restore_state(pdev); if (priv->mode != IEEE80211_IF_TYPE_MGMT) { - adm8211_open(dev); + adm8211_start(dev); ieee80211_start_queues(dev); }
--- wireless-dev.orig/drivers/net/wireless/b43/b43.h 2007-08-16 16:51:20.373468950 +0200 +++ wireless-dev/drivers/net/wireless/b43/b43.h 2007-08-16 16:56:13.123468950 +0200 @@ -572,9 +572,8 @@ struct b43_wl { * at a time. General information about this interface follows. */ - /* Opaque ID of the operating interface (!= monitor - * interface) from the ieee80211 subsystem. - * Do not modify. + /* Opaque ID of the operating interface from the ieee80211 + * subsystem. Do not modify. */ int if_id; /* MAC address (can be NULL). */ @@ -583,14 +582,10 @@ struct b43_wl { const u8 *bssid; /* Interface type. (IEEE80211_IF_TYPE_XXX) */ int if_type; - /* Counter of active monitor interfaces. */ - int monitor; /* Is the card operating in AP, STA or IBSS mode? */ bool operating; - /* Promisc mode active? - * Note that (monitor != 0) implies promisc. - */ - bool promisc; + /* filter flags */ + unsigned int filter_flags; /* Stats about the wireless interface */ struct ieee80211_low_level_stats ieee_stats; @@ -747,8 +742,6 @@ static inline struct b43_wldev *dev_to_b /* Is the device operating in a specified mode (IEEE80211_IF_TYPE_XXX). */ static inline int b43_is_mode(struct b43_wl *wl, int type) { - if (type == IEEE80211_IF_TYPE_MNTR) - return !!(wl->monitor); return (wl->operating && wl->if_type == type); } --- wireless-dev.orig/drivers/net/wireless/b43/main.c 2007-08-16 16:51:20.403468950 +0200 +++ wireless-dev/drivers/net/wireless/b43/main.c 2007-08-16 16:57:17.573468950 +0200 @@ -91,14 +91,6 @@ static char modparam_fwpostfix[16]; module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444); MODULE_PARM_DESC(fwpostfix, "Postfix for the .fw files to load."); -static int modparam_mon_keep_bad; -module_param_named(mon_keep_bad, modparam_mon_keep_bad, int, 0444); -MODULE_PARM_DESC(mon_keep_bad, "Keep bad frames in monitor mode"); - -static int modparam_mon_keep_badplcp; -module_param_named(mon_keep_badplcp, modparam_mon_keep_bad, int, 0444); -MODULE_PARM_DESC(mon_keep_badplcp, "Keep frames with bad PLCP in monitor mode"); - static int modparam_hwpctl; module_param_named(hwpctl, modparam_hwpctl, int, 0444); MODULE_PARM_DESC(hwpctl, "Enable hardware-side power control (default off)"); @@ -561,12 +553,10 @@ static void b43_write_mac_bssid_template } } -static void b43_upload_card_macaddress(struct b43_wldev *dev, - const u8 * mac_addr) +static void b43_upload_card_macaddress(struct b43_wldev *dev) { - dev->wl->mac_addr = mac_addr; b43_write_mac_bssid_templates(dev); - b43_macfilter_set(dev, B43_MACFILTER_SELF, mac_addr); + b43_macfilter_set(dev, B43_MACFILTER_SELF, dev->wl->mac_addr); } static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) @@ -1957,33 +1947,25 @@ static void b43_adjust_opmode(struct b43 ctl &= ~B43_MACCTL_KEEP_BADPLCP; ctl &= ~B43_MACCTL_KEEP_BAD; ctl &= ~B43_MACCTL_PROMISC; + ctl &= ~B43_MACCTL_BEACPROMISC; ctl |= B43_MACCTL_INFRA; - if (wl->operating) { - switch (wl->if_type) { - case IEEE80211_IF_TYPE_AP: - ctl |= B43_MACCTL_AP; - break; - case IEEE80211_IF_TYPE_IBSS: - ctl &= ~B43_MACCTL_INFRA; - break; - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_MNTR: - case IEEE80211_IF_TYPE_WDS: - break; - default: - B43_WARN_ON(1); - } - } - if (wl->monitor) { + if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) + ctl |= B43_MACCTL_AP; + else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) + ctl &= ~B43_MACCTL_INFRA; + + if (wl->filter_flags & FIF_CONTROL) ctl |= B43_MACCTL_KEEP_CTL; - if (modparam_mon_keep_bad) - ctl |= B43_MACCTL_KEEP_BAD; - if (modparam_mon_keep_badplcp) - ctl |= B43_MACCTL_KEEP_BADPLCP; - } - if (wl->promisc) + if (wl->filter_flags & FIF_FCSFAIL) + ctl |= B43_MACCTL_KEEP_BAD; + if (wl->filter_flags & FIF_PLCPFAIL) + ctl |= B43_MACCTL_KEEP_BADPLCP; + if (wl->filter_flags & FIF_PROMISC_IN_BSS) ctl |= B43_MACCTL_PROMISC; + if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC) + ctl |= B43_MACCTL_BEACPROMISC; + /* Workaround: On old hardware the HW-MAC-address-filter * doesn't work properly, so always run promisc in filter * it in software. */ @@ -2147,9 +2129,6 @@ static int b43_chip_init(struct b43_wlde & ~B43_MACCTL_INFRA); b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) | B43_MACCTL_INFRA); - /* Let beacons come through */ - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_BEACPROMISC); if (b43_using_pio(dev)) { b43_write32(dev, 0x0210, 0x00000100); @@ -2893,21 +2872,41 @@ out: return err; } -static void b43_set_multicast_list(struct ieee80211_hw *hw, - unsigned short netflags, int mc_count) +static void b43_configure_filter(struct ieee80211_hw *hw, + int multi_count, + unsigned int changed, + unsigned int *fflags) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; unsigned long flags; - if (!dev) + if (!dev) { + *fflags = 0; return; - spin_lock_irqsave(&wl->irq_lock, flags); - if (wl->promisc != !!(netflags & IFF_PROMISC)) { - wl->promisc = !!(netflags & IFF_PROMISC); - if (b43_status(dev) >= B43_STAT_INITIALIZED) - b43_adjust_opmode(dev); } + + spin_lock_irqsave(&wl->irq_lock, flags); + *fflags &= FIF_PROMISC_IN_BSS | + FIF_ALLMULTI | + FIF_FCSFAIL | + FIF_PLCPFAIL | + FIF_CONTROL | + FIF_OTHER_BSS | + FIF_BCN_PRBRESP_PROMISC; + + changed &= FIF_PROMISC_IN_BSS | + FIF_ALLMULTI | + FIF_FCSFAIL | + FIF_PLCPFAIL | + FIF_CONTROL | + FIF_OTHER_BSS | + FIF_BCN_PRBRESP_PROMISC; + + wl->filter_flags = *fflags; + + if (changed && b43_status(dev) >= B43_STAT_INITIALIZED) + b43_adjust_opmode(dev); spin_unlock_irqrestore(&wl->irq_lock, flags); } @@ -2922,18 +2921,16 @@ static int b43_config_interface(struct i return -ENODEV; mutex_lock(&wl->mutex); spin_lock_irqsave(&wl->irq_lock, flags); - if (conf->type != IEEE80211_IF_TYPE_MNTR) { - B43_WARN_ON(wl->if_id != if_id); - wl->bssid = conf->bssid; - if (b43_status(dev) >= B43_STAT_INITIALIZED) { - if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) { - B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); - b43_set_ssid(dev, conf->ssid, conf->ssid_len); - if (conf->beacon) - b43_refresh_templates(dev, conf->beacon); - } - b43_write_mac_bssid_templates(dev); + B43_WARN_ON(wl->if_id != if_id); + wl->bssid = conf->bssid; + if (b43_status(dev) >= B43_STAT_INITIALIZED) { + if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) { + B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); + b43_set_ssid(dev, conf->ssid, conf->ssid_len); + if (conf->beacon) + b43_refresh_templates(dev, conf->beacon); } + b43_write_mac_bssid_templates(dev); } spin_unlock_irqrestore(&wl->irq_lock, flags); mutex_unlock(&wl->mutex); @@ -3353,7 +3350,8 @@ static int b43_wireless_core_init(struct ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ wl->bssid = NULL; - b43_upload_card_macaddress(dev, NULL); + wl->mac_addr = NULL; + b43_upload_card_macaddress(dev); b43_security_init(dev); b43_rng_init(wl); @@ -3383,21 +3381,80 @@ static int b43_add_interface(struct ieee struct b43_wldev *dev; unsigned long flags; int err = -EOPNOTSUPP; - int did_init = 0; + + /* TODO: allow WDS/AP devices to coexist */ + + if (conf->type != IEEE80211_IF_TYPE_AP && + conf->type != IEEE80211_IF_TYPE_STA && + conf->type != IEEE80211_IF_TYPE_WDS && + conf->type != IEEE80211_IF_TYPE_IBSS) + return -EOPNOTSUPP; mutex_lock(&wl->mutex); - if ((conf->type != IEEE80211_IF_TYPE_MNTR) && wl->operating) + if (wl->operating) goto out_mutex_unlock; bcmdbg(wl, "Adding Interface type %d\n", conf->type); dev = wl->current_dev; + wl->operating = 1; + wl->if_id = conf->if_id; + wl->if_type = conf->type; + wl->mac_addr = conf->mac_addr; + + spin_lock_irqsave(&wl->irq_lock, flags); + b43_adjust_opmode(dev); + b43_upload_card_macaddress(dev); + spin_unlock_irqrestore(&wl->irq_lock, flags); + + err = 0; + out_mutex_unlock: + mutex_unlock(&wl->mutex); + + return err; +} + +static void b43_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev = wl->current_dev; + unsigned long flags; + + bcmdbg(wl, "Removing Interface type %d\n", conf->type); + + mutex_lock(&wl->mutex); + + B43_WARN_ON(!wl->operating); + B43_WARN_ON(wl->if_id != conf->if_id); + + wl->operating = 0; + + spin_lock_irqsave(&wl->irq_lock, flags); + b43_adjust_opmode(dev); + wl->mac_addr = NULL; + b43_upload_card_macaddress(dev); + spin_unlock_irqrestore(&wl->irq_lock, flags); + + mutex_unlock(&wl->mutex); +} + +static int b43_start(struct ieee80211_hw *hw) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev = wl->current_dev; + int did_init = 0; + int err; + + mutex_lock(&wl->mutex); + if (b43_status(dev) < B43_STAT_INITIALIZED) { err = b43_wireless_core_init(dev); if (err) goto out_mutex_unlock; did_init = 1; } + if (b43_status(dev) < B43_STAT_STARTED) { err = b43_wireless_core_start(dev); if (err) { @@ -3407,59 +3464,21 @@ static int b43_add_interface(struct ieee } } - spin_lock_irqsave(&wl->irq_lock, flags); - switch (conf->type) { - case IEEE80211_IF_TYPE_MNTR: - wl->monitor++; - break; - default: - wl->operating = 1; - wl->if_id = conf->if_id; - wl->if_type = conf->type; - b43_upload_card_macaddress(dev, conf->mac_addr); - } - b43_adjust_opmode(dev); - spin_unlock_irqrestore(&wl->irq_lock, flags); - - err = 0; - out_mutex_unlock: + out_mutex_unlock: mutex_unlock(&wl->mutex); return err; } -static void b43_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +void b43_stop(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); - struct b43_wldev *dev; - unsigned long flags; - - bcmdbg(wl, "Removing Interface type %d\n", conf->type); + struct b43_wldev *dev = wl->current_dev; mutex_lock(&wl->mutex); - if (conf->type == IEEE80211_IF_TYPE_MNTR) { - wl->monitor--; - B43_WARN_ON(wl->monitor < 0); - } else { - B43_WARN_ON(!wl->operating); - wl->operating = 0; - } - - dev = wl->current_dev; - if (!wl->operating && wl->monitor == 0) { - /* No interface left. */ - if (b43_status(dev) >= B43_STAT_STARTED) - b43_wireless_core_stop(dev); - b43_wireless_core_exit(dev); - } else { - /* Just monitor interfaces left. */ - spin_lock_irqsave(&wl->irq_lock, flags); - b43_adjust_opmode(dev); - if (!wl->operating) - b43_upload_card_macaddress(dev, NULL); - spin_unlock_irqrestore(&wl->irq_lock, flags); - } + if (b43_status(dev) >= B43_STAT_STARTED) + b43_wireless_core_stop(dev); + b43_wireless_core_exit(dev); mutex_unlock(&wl->mutex); } @@ -3470,10 +3489,12 @@ static const struct ieee80211_ops b43_hw .remove_interface = b43_remove_interface, .config = b43_dev_config, .config_interface = b43_config_interface, - .set_multicast_list = b43_set_multicast_list, + .configure_filter = b43_configure_filter, .set_key = b43_dev_set_key, .get_stats = b43_get_stats, .get_tx_stats = b43_get_tx_stats, + .start = b43_start, + .stop = b43_stop, }; /* Hard-reset the chip. Do not call this directly. @@ -3811,7 +3832,6 @@ static int b43_wireless_init(struct ssb_ /* fill hw info */ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | - IEEE80211_HW_MONITOR_DURING_OPER | IEEE80211_HW_DEVICE_HIDES_WEP | IEEE80211_HW_WEP_INCLUDE_IV; hw->max_signal = 100; hw->max_rssi = -110;
--- wireless-dev.orig/drivers/net/wireless/iwl-base.c 2007-08-16 16:51:20.433468950 +0200 +++ wireless-dev/drivers/net/wireless/iwl-base.c 2007-08-16 16:57:17.653468950 +0200 @@ -2591,6 +2591,8 @@ static void iwl_set_flags_for_phymode(st /* * initilize rxon structure with default values fromm eeprom + * + * XXX: This function should use the filter flags instead! */ static void iwl_connection_init_rx_config(struct iwl_priv *priv) { @@ -7502,7 +7504,7 @@ static void iwl_bg_scan_completed(struct * *****************************************************************************/ -static int iwl_mac_open(struct ieee80211_hw *hw) +static int iwl_mac_start(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -7521,7 +7523,7 @@ static int iwl_mac_open(struct ieee80211 return 0; } -static int iwl_mac_stop(struct ieee80211_hw *hw) +static void iwl_mac_stop(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -7530,8 +7532,18 @@ static int iwl_mac_stop(struct ieee80211 /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); IWL_DEBUG_MAC80211("leave\n"); +} - return 0; +static void iwl_configure_filter(struct ieee80211_hw *hw, + int multi_count, + unsigned int changed_flags, + unsigned int *total_flags) +{ + /* + * XXX: dummy + * see also iwl_connection_init_rx_config + */ + *total_flags = 0; } static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, @@ -7700,6 +7712,8 @@ static int iwl_mac_config_interface(stru if (conf == NULL) return -EIO; + /* TODO: use conf->mac_addr */ + if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && (!conf->beacon || !conf->ssid_len)) { IWL_DEBUG_MAC80211 @@ -7714,8 +7728,14 @@ static int iwl_mac_config_interface(stru IWL_DEBUG_MAC80211("bssid: " MAC_FMT "\n", MAC_ARG(conf->bssid)); + /* + * XXX: there was a test for IEEE80211_HW_NO_PROBE_FILTERING here + * which must have been wrong since it was always true. + * the test was: if (unlikely(priv->status & STATUS_SCANNING) && !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { + */ + if (unlikely(priv->status & STATUS_SCANNING)) { IWL_DEBUG_MAC80211("leave - scanning\n"); mutex_unlock(&priv->mutex); return 0; @@ -7808,6 +7828,8 @@ static void iwl_mac_remove_interface(str } mutex_unlock(&priv->mutex); + /* TODO: clear MAC address in hardware */ + IWL_DEBUG_MAC80211("leave\n"); } @@ -9056,10 +9078,11 @@ static struct attribute_group iwl_attrib static struct ieee80211_ops iwl_hw_ops = { .tx = iwl_mac_tx, - .open = iwl_mac_open, + .start = iwl_mac_start, .stop = iwl_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, + .configure_filter = iwl_configure_filter, .config = iwl_mac_config, .config_interface = iwl_mac_config_interface, .set_key = iwl_mac_set_key,
--- wireless-dev.orig/drivers/net/wireless/rtl8187_dev.c 2007-08-16 16:51:20.463468950 +0200 +++ wireless-dev/drivers/net/wireless/rtl8187_dev.c 2007-08-16 16:56:13.153468950 +0200 @@ -365,7 +365,7 @@ static void rtl8187_set_channel(struct i rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); } -static int rtl8187_open(struct ieee80211_hw *dev) +static int rtl8187_start(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; u32 reg; @@ -419,7 +419,7 @@ static int rtl8187_open(struct ieee80211 return 0; } -static int rtl8187_stop(struct ieee80211_hw *dev) +static void rtl8187_stop(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; struct rtl8187_rx_info *info; @@ -445,7 +445,6 @@ static int rtl8187_stop(struct ieee80211 usb_kill_urb(info->urb); kfree_skb(skb); } - return 0; } static int rtl8187_add_interface(struct ieee80211_hw *dev, @@ -476,6 +475,8 @@ static void rtl8187_remove_interface(str { struct rtl8187_priv *priv = dev->priv; priv->mode = IEEE80211_IF_TYPE_MGMT; + + /* TODO: reset MAC address to zeroes */ } static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) @@ -523,14 +524,28 @@ static int rtl8187_config_interface(stru return 0; } +static void rtl8187_configure_filter(struct ieee80211_hw *dev, + int multi_count, + unsigned int changed, + unsigned int *flags) +{ + /* + * XXX: dummy + * + * TODO: change filter flags + */ + *flags = 0; +} + static const struct ieee80211_ops rtl8187_ops = { .tx = rtl8187_tx, - .open = rtl8187_open, + .start = rtl8187_start, .stop = rtl8187_stop, .add_interface = rtl8187_add_interface, .remove_interface = rtl8187_remove_interface, .config = rtl8187_config, .config_interface = rtl8187_config_interface, + .configure_filter = rtl8187_configure_filter, }; static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
--- wireless-dev.orig/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c 2007-08-16 16:51:20.533468950 +0200 +++ wireless-dev/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c 2007-08-16 16:56:13.153468950 +0200 @@ -170,29 +170,18 @@ void zd_mac_clear(struct zd_mac *mac) ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); } -/** - * has_monitor_interfaces - have monitor interfaces been enabled? - * @mac: the struct zd_mac pointer - * - * The function returns, whether the device has monitor interfaces attached. - */ -static int has_monitor_interfaces(struct zd_mac *mac) -{ - return mac->type == IEEE80211_IF_TYPE_MNTR; -} - static int set_rx_filter(struct zd_mac *mac) { - u32 filter = has_monitor_interfaces(mac) ? ~0 : STA_RX_FILTER; + /* XXX: need to work off the filter flags! */ + u32 filter = STA_RX_FILTER; return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); } static int set_sniffer(struct zd_mac *mac) { - return zd_iowrite32(&mac->chip, CR_SNIFFER_ON, - has_monitor_interfaces(mac) ? 1 : 0); - return 0; + /* XXX: need to work off the filter flags! */ + return zd_iowrite32(&mac->chip, CR_SNIFFER_ON, 0); } static int set_mc_hash(struct zd_mac *mac) @@ -200,13 +189,13 @@ static int set_mc_hash(struct zd_mac *ma struct zd_mc_hash hash; zd_mc_clear(&hash); - if (has_monitor_interfaces(mac)) + if (0) /* XXX: need to work off the filter flags! */ zd_mc_add_all(&hash); return zd_chip_set_multicast_hash(&mac->chip, &hash); } -static int zd_op_open(struct ieee80211_hw *hw) +static int zd_op_start(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; @@ -290,7 +279,7 @@ static void kfree_tx_skb(struct sk_buff dev_kfree_skb_any(skb); } -static int zd_op_stop(struct ieee80211_hw *hw) +static void zd_op_stop(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; @@ -313,8 +302,6 @@ static int zd_op_stop(struct ieee80211_h while ((skb = skb_dequeue(ack_wait_queue))) kfree_tx_skb(skb); - - return 0; } /** @@ -693,7 +680,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, c buffer += ZD_PLCP_HEADER_SIZE; if (filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) && - !has_monitor_interfaces(mac)) + 0 /* XXX: need to work off the filter flags! */) return 0; skb = dev_alloc_skb(length); @@ -715,7 +702,6 @@ static int zd_op_add_interface(struct ie return -1; switch (conf->type) { - case IEEE80211_IF_TYPE_MNTR: case IEEE80211_IF_TYPE_STA: mac->type = conf->type; break; @@ -765,18 +751,19 @@ static void set_multicast_hash_handler(s zd_chip_set_multicast_hash(&mac->chip, &hash); } -static void zd_op_set_multicast_list(struct ieee80211_hw *hw, - unsigned short dev_flags, int mc_count) +static void zd_op_configure_filter(struct ieee80211_hw *hw, + int multi_count, + unsigned int change, + unsigned int *filterflags) { struct zd_mc_hash hash; struct zd_mac *mac = zd_hw_mac(hw); unsigned long flags; - if ((dev_flags & (IFF_PROMISC|IFF_ALLMULTI)) || - has_monitor_interfaces(mac)) - { + if (*filterflags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) { + /* XXX: can we do better, with finer granularity? */ zd_mc_add_all(&hash); - } else { + } else if (multi_count >= 0) { struct dev_mc_list *mc = NULL; void *tmp = NULL; zd_mc_clear(&hash); @@ -787,10 +774,18 @@ static void zd_op_set_multicast_list(str } } - spin_lock_irqsave(&mac->lock, flags); - mac->multicast_hash = hash; - spin_unlock_irqrestore(&mac->lock, flags); - queue_work(zd_workqueue, &mac->set_multicast_hash_work); + /* + * XXX: probably not right, we probably see many other + * frames as well... + */ + *filterflags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI; + + if (multi_count >= 0) { + spin_lock_irqsave(&mac->lock, flags); + mac->multicast_hash = hash; + spin_unlock_irqrestore(&mac->lock, flags); + queue_work(zd_workqueue, &mac->set_multicast_hash_work); + } } static void set_rts_cts_work(struct work_struct *work) @@ -834,13 +829,13 @@ static void zd_op_erp_ie_changed(struct static const struct ieee80211_ops zd_ops = { .tx = zd_op_tx, - .open = zd_op_open, + .start = zd_op_start, .stop = zd_op_stop, .add_interface = zd_op_add_interface, .remove_interface = zd_op_remove_interface, .config = zd_op_config, .config_interface = zd_op_config_interface, - .set_multicast_list = zd_op_set_multicast_list, + .configure_filter = zd_op_configure_filter, .erp_ie_changed = zd_op_erp_ie_changed, }; @@ -880,7 +875,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(str hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_WEP_INCLUDE_IV | - IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; + IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED | + IEEE80211_HW_MULTICAST_FILTER; hw->max_rssi = 100; hw->max_signal = 100;
Attachment:
signature.asc
Description: This is a digitally signed message part