From d6ede678c138061f5202b519f8f8d6372e2cb5bb Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 2 Dec 2009 15:25:57 +0100 Subject: libertas: remove mesh_autostart_enabled and sync_channel mesh_autostart_enabled was nowhere set. Rumor is that this is used in the OLPC tree, but they never did submit their code upstream. After removing this code, it turned out that the sync_channel stuff is now also unused, so get rid of that as well. Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/main.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index db38a5a719fa..b0799e347ba2 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -806,18 +806,6 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv) return 0; } -static void lbs_sync_channel_worker(struct work_struct *work) -{ - struct lbs_private *priv = container_of(work, struct lbs_private, - sync_channel); - - lbs_deb_enter(LBS_DEB_MAIN); - if (lbs_update_channel(priv)) - lbs_pr_info("Channel synchronization failed."); - lbs_deb_leave(LBS_DEB_MAIN); -} - - static int lbs_init_adapter(struct lbs_private *priv) { size_t bufsize; @@ -997,7 +985,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); - INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker); priv->mesh_open = 0; sprintf(priv->mesh_ssid, "mesh"); -- cgit v1.2.3 From cd74468b8c56c1a809d9b7f913f11d8181c3a0b2 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 2 Dec 2009 15:25:59 +0100 Subject: libertas: decouple mesh and rtap While it's might be technically true that only MESH-enabled firmwares are also RTAP-enabled, I like to have this decoupled. Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/main.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index b0799e347ba2..ad3434011897 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1062,6 +1062,17 @@ void lbs_remove_card(struct lbs_private *priv) EXPORT_SYMBOL_GPL(lbs_remove_card); +static int lbs_rtap_supported(struct lbs_private *priv) +{ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) + return 1; + + /* newer firmware use a capability mask */ + return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) && + (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)); +} + + int lbs_start_card(struct lbs_private *priv) { struct net_device *dev = priv->dev; @@ -1081,12 +1092,14 @@ int lbs_start_card(struct lbs_private *priv) lbs_update_channel(priv); + lbs_init_mesh(priv); + /* * While rtap isn't related to mesh, only mesh-enabled * firmware implements the rtap functionality via * CMD_802_11_MONITOR_MODE. */ - if (lbs_init_mesh(priv)) { + if (lbs_rtap_supported(priv)) { if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) lbs_pr_err("cannot register lbs_rtap attribute\n"); } @@ -1120,7 +1133,9 @@ void lbs_stop_card(struct lbs_private *priv) netif_carrier_off(dev); lbs_debugfs_remove_one(priv); - if (lbs_deinit_mesh(priv)) + lbs_deinit_mesh(priv); + + if (lbs_rtap_supported(priv)) device_remove_file(&dev->dev, &dev_attr_lbs_rtap); /* Delete the timeout of the currently processing command */ -- cgit v1.2.3 From e4da1a81a967c05dfde6f0498cff1f6fe6683f52 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 2 Dec 2009 15:26:00 +0100 Subject: libertas: move mesh SSID initialization into mesh.c Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/main.c | 4 ---- drivers/net/wireless/libertas/mesh.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index ad3434011897..127b7f60c320 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -986,10 +986,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); - priv->mesh_open = 0; - sprintf(priv->mesh_ssid, "mesh"); - priv->mesh_ssid_len = 4; - priv->wol_criteria = 0xffffffff; priv->wol_gpio = 0xff; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 1d94f7d4efc8..4f67c8b62edc 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -237,6 +237,9 @@ int lbs_init_mesh(struct lbs_private *priv) if (priv->mesh_tlv) { + sprintf(priv->mesh_ssid, "mesh"); + priv->mesh_ssid_len = 4; + lbs_add_mesh(priv); if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) -- cgit v1.2.3 From 602114ae595af6c89eab149cf9f939e3f7ef4a34 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 2 Dec 2009 15:26:01 +0100 Subject: libertas: add access functions for mesh open/connect status Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 2 +- drivers/net/wireless/libertas/main.c | 5 ++--- drivers/net/wireless/libertas/mesh.c | 3 ++- drivers/net/wireless/libertas/mesh.h | 6 ++++++ drivers/net/wireless/libertas/scan.c | 2 +- drivers/net/wireless/libertas/tx.c | 2 +- drivers/net/wireless/libertas/wext.c | 6 +++--- 7 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index dd69191f24eb..4a198113f9be 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1304,7 +1304,7 @@ int lbs_execute_next_command(struct lbs_private *priv) if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && ((priv->connect_status == LBS_CONNECTED) || - (priv->mesh_connect_status == LBS_CONNECTED))) { + lbs_mesh_connected(priv))) { if (priv->secinfo.WPAenabled || priv->secinfo.WPA2enabled) { /* check for valid WPA group keys */ diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 127b7f60c320..64b327d4548b 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -123,7 +123,7 @@ static ssize_t lbs_rtap_set(struct device *dev, if (priv->monitormode == monitor_mode) return strlen(buf); if (!priv->monitormode) { - if (priv->infra_open || priv->mesh_open) + if (priv->infra_open || lbs_mesh_open(priv)) return -EBUSY; if (priv->mode == IW_MODE_INFRA) lbs_cmd_80211_deauthenticate(priv, @@ -619,7 +619,7 @@ static int lbs_thread(void *data) if (priv->connect_status == LBS_CONNECTED) netif_wake_queue(priv->dev); if (priv->mesh_dev && - priv->mesh_connect_status == LBS_CONNECTED) + lbs_mesh_connected(priv)) netif_wake_queue(priv->mesh_dev); } } @@ -833,7 +833,6 @@ static int lbs_init_adapter(struct lbs_private *priv) memset(priv->current_addr, 0xff, ETH_ALEN); priv->connect_status = LBS_DISCONNECTED; - priv->mesh_connect_status = LBS_DISCONNECTED; priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; priv->mode = IW_MODE_INFRA; priv->channel = DEFAULT_AD_HOC_CHANNEL; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 4f67c8b62edc..954cd00f7452 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -196,6 +195,8 @@ int lbs_init_mesh(struct lbs_private *priv) lbs_deb_enter(LBS_DEB_MESH); + priv->mesh_connect_status = LBS_DISCONNECTED; + /* Determine mesh_fw_ver from fwrelease and fwcapinfo */ /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */ /* 5.110.22 have mesh command with 0xa3 command id */ diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h index b642d5d11699..388c39281b7d 100644 --- a/drivers/net/wireless/libertas/mesh.h +++ b/drivers/net/wireless/libertas/mesh.h @@ -84,4 +84,10 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *s); +/* Accessors */ + +#define lbs_mesh_open(priv) (priv->mesh_open) +#define lbs_mesh_connected(priv) (priv->mesh_connect_status == LBS_CONNECTED) + + #endif diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index c6a6c042b82f..4a0c3e3cd3b1 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -640,7 +640,7 @@ out: if (!priv->tx_pending_len) netif_wake_queue(priv->dev); } - if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { + if (priv->mesh_dev && lbs_mesh_connected(priv)) { netif_carrier_on(priv->mesh_dev); if (!priv->tx_pending_len) netif_wake_queue(priv->mesh_dev); diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index 315d1ce286ca..52d244ea3d97 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -198,7 +198,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) if (priv->connect_status == LBS_CONNECTED) netif_wake_queue(priv->dev); - if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) + if (priv->mesh_dev && lbs_mesh_connected(priv)) netif_wake_queue(priv->mesh_dev); } EXPORT_SYMBOL_GPL(lbs_send_tx_feedback); diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index a8eb9e1fcf36..c0c7bc40b109 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -192,7 +192,7 @@ static void copy_active_data_rates(struct lbs_private *priv, u8 *rates) lbs_deb_enter(LBS_DEB_WEXT); if ((priv->connect_status != LBS_CONNECTED) && - (priv->mesh_connect_status != LBS_CONNECTED)) + !lbs_mesh_connected(priv)) memcpy(rates, lbs_bg_rates, MAX_RATES); else memcpy(rates, priv->curbssparams.rates, MAX_RATES); @@ -307,7 +307,7 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, /* Use nickname to indicate that mesh is on */ - if (priv->mesh_connect_status == LBS_CONNECTED) { + if (lbs_mesh_connected(priv)) { strncpy(extra, "Mesh", 12); extra[12] = '\0'; dwrq->length = strlen(extra); @@ -863,7 +863,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) /* If we're not associated, all quality values are meaningless */ if ((priv->connect_status != LBS_CONNECTED) && - (priv->mesh_connect_status != LBS_CONNECTED)) + !lbs_mesh_connected(priv)) goto out; /* Quality by RSSI */ -- cgit v1.2.3 From 0e78ff8fcc6dabeda313719deb751afbd20bea41 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 2 Dec 2009 15:26:03 +0100 Subject: libertas: remove priv->capability This variable was once set to WLAN_CAPABILITY_SHORT_PREAMBLE and there's no code that could change the variable to something else. Therefore it seems this is not necessary :-) Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/assoc.c | 13 +++---------- drivers/net/wireless/libertas/cmd.c | 3 --- drivers/net/wireless/libertas/dev.h | 1 - drivers/net/wireless/libertas/main.c | 1 - 4 files changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 751067369ba8..5f58ae33405b 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -807,8 +807,7 @@ static int lbs_try_associate(struct lbs_private *priv, } /* Use short preamble only when both the BSS and firmware support it */ - if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && - (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) + if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) preamble = RADIO_PREAMBLE_SHORT; ret = lbs_set_radio(priv, preamble, 1); @@ -939,8 +938,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, } /* Use short preamble only when both the BSS and firmware support it */ - if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && - (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) { + if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { lbs_deb_join("AdhocJoin: Short preamble\n"); preamble = RADIO_PREAMBLE_SHORT; } @@ -1049,7 +1047,7 @@ static int lbs_adhoc_start(struct lbs_private *priv, struct assoc_request *assoc_req) { struct cmd_ds_802_11_ad_hoc_start cmd; - u8 preamble = RADIO_PREAMBLE_LONG; + u8 preamble = RADIO_PREAMBLE_SHORT; size_t ratesize = 0; u16 tmpcap = 0; int ret = 0; @@ -1057,11 +1055,6 @@ static int lbs_adhoc_start(struct lbs_private *priv, lbs_deb_enter(LBS_DEB_ASSOC); - if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { - lbs_deb_join("ADHOC_START: Will use short preamble\n"); - preamble = RADIO_PREAMBLE_SHORT; - } - ret = lbs_set_radio(priv, preamble, 1); if (ret) goto out; diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 4a0d8f4188ca..42051f7cad6d 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -842,9 +842,6 @@ int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on) if (priv->fwrelease < 0x09000000) { switch (preamble) { case RADIO_PREAMBLE_SHORT: - if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) - goto out; - /* Fall through */ case RADIO_PREAMBLE_AUTO: case RADIO_PREAMBLE_LONG: cmd.control = cpu_to_le16(preamble); diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 7330ab8521cc..cf47cf53458f 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -175,7 +175,6 @@ struct lbs_private { struct bss_descriptor *networks; struct assoc_request * pending_assoc_req; struct assoc_request * in_progress_assoc_req; - u16 capability; uint16_t enablehwauto; uint16_t ratebitmap; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 64b327d4548b..f9f195f7b17c 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -839,7 +839,6 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; priv->radio_on = 1; priv->enablehwauto = 1; - priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; priv->psmode = LBS802_11POWERMODECAM; priv->psstate = PS_STATE_FULL_POWER; priv->is_deep_sleep = 0; -- cgit v1.2.3 From 40e6fa829a2544c9f8fd5a94844fe502334d6afc Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Thu, 4 Feb 2010 14:37:45 +0100 Subject: libertas: don't retry commands Retrying commands seldomly works, most often the firmware is in a weird state anyway and needs the device to reset. So it's better to report the broken state back to user-space. Also rename command_timer_fn() into lbs_cmd_timeout_handler(), which better reflect it's usage. Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmdresp.c | 5 ----- drivers/net/wireless/libertas/dev.h | 1 - drivers/net/wireless/libertas/main.c | 31 +++++++------------------------ 3 files changed, 7 insertions(+), 30 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 0334a58820ee..e7470442f76b 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -240,11 +240,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) /* Now we got response from FW, cancel the command timer */ del_timer(&priv->command_timer); priv->cmd_timed_out = 0; - if (priv->nr_retries) { - lbs_pr_info("Received result %x to command %x after %d retries\n", - result, curcmd, priv->nr_retries); - priv->nr_retries = 0; - } /* Store the response code to cur_cmd_retcode. */ priv->cur_cmd_retcode = result; diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index d5a9dcae4059..efb2519d9d74 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -109,7 +109,6 @@ struct lbs_private { struct list_head cmdpendingq; /* pending command buffers */ wait_queue_head_t cmd_pending; struct timer_list command_timer; - int nr_retries; int cmd_timed_out; /* Command responses sent from the hardware to the driver */ diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index f9f195f7b17c..f5d641efd50a 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -533,31 +533,14 @@ static int lbs_thread(void *data) if (priv->cmd_timed_out && priv->cur_cmd) { struct cmd_ctrl_node *cmdnode = priv->cur_cmd; - if (++priv->nr_retries > 3) { - lbs_pr_info("Excessive timeouts submitting " - "command 0x%04x\n", - le16_to_cpu(cmdnode->cmdbuf->command)); - lbs_complete_command(priv, cmdnode, -ETIMEDOUT); - priv->nr_retries = 0; - if (priv->reset_card) - priv->reset_card(priv); - } else { - priv->cur_cmd = NULL; - priv->dnld_sent = DNLD_RES_RECEIVED; - lbs_pr_info("requeueing command 0x%04x due " - "to timeout (#%d)\n", - le16_to_cpu(cmdnode->cmdbuf->command), - priv->nr_retries); - - /* Stick it back at the _top_ of the pending queue - for immediate resubmission */ - list_add(&cmdnode->list, &priv->cmdpendingq); - } + lbs_pr_info("Timeout submitting command 0x%04x\n", + le16_to_cpu(cmdnode->cmdbuf->command)); + lbs_complete_command(priv, cmdnode, -ETIMEDOUT); + if (priv->reset_card) + priv->reset_card(priv); } priv->cmd_timed_out = 0; - - if (!priv->fw_ready) continue; @@ -729,7 +712,7 @@ done: * This function handles the timeout of command sending. * It will re-send the same command again. */ -static void command_timer_fn(unsigned long data) +static void lbs_cmd_timeout_handler(unsigned long data) { struct lbs_private *priv = (struct lbs_private *)data; unsigned long flags; @@ -848,7 +831,7 @@ static int lbs_init_adapter(struct lbs_private *priv) mutex_init(&priv->lock); - setup_timer(&priv->command_timer, command_timer_fn, + setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, (unsigned long)priv); setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, (unsigned long)priv); -- cgit v1.2.3 From 655ffee284dfcf9a24ac0343f3e5ee6db85b85c5 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sat, 27 Feb 2010 07:35:45 +0000 Subject: wireless: convert to use netdev_for_each_mc_addr also added missed locking in rndis_wlan.c Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/wireless/libertas/main.c | 8 ++++++-- drivers/net/wireless/orinoco/hw.c | 22 +++++++--------------- drivers/net/wireless/orinoco/hw.h | 2 +- drivers/net/wireless/orinoco/main.c | 3 +-- drivers/net/wireless/ray_cs.c | 8 ++++---- drivers/net/wireless/rndis_wlan.c | 15 ++++++++------- drivers/net/wireless/zd1201.c | 9 ++++----- 7 files changed, 31 insertions(+), 36 deletions(-) (limited to 'drivers/net/wireless/libertas/main.c') diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index cd8ed7fdafad..28a1c9d1627a 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -319,15 +319,18 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, { int i = nr_addrs; struct dev_mc_list *mc_list; + int cnt; if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST)) return nr_addrs; netif_addr_lock_bh(dev); - for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { + cnt = netdev_mc_count(dev); + netdev_for_each_mc_addr(mc_list, dev) { if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { lbs_deb_net("mcast address %s:%pM skipped\n", dev->name, mc_list->dmi_addr); + cnt--; continue; } @@ -337,9 +340,10 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name, mc_list->dmi_addr); i++; + cnt--; } netif_addr_unlock_bh(dev); - if (mc_list) + if (cnt) return -EOVERFLOW; return i; diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 404830f47ab2..e6369242e49c 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -1028,7 +1028,7 @@ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx) } int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, - struct dev_addr_list *mc_list, + struct net_device *dev, int mc_count, int promisc) { hermes_t *hw = &priv->hw; @@ -1049,24 +1049,16 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, * group address if either we want to multicast, or if we were * multicasting and want to stop */ if (!promisc && (mc_count || priv->mc_count)) { - struct dev_mc_list *p = mc_list; + struct dev_mc_list *p; struct hermes_multicast mclist; - int i; + int i = 0; - for (i = 0; i < mc_count; i++) { - /* paranoia: is list shorter than mc_count? */ - BUG_ON(!p); - /* paranoia: bad address size in list? */ - BUG_ON(p->dmi_addrlen != ETH_ALEN); - - memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN); - p = p->next; + netdev_for_each_mc_addr(p, dev) { + if (i == mc_count) + break; + memcpy(mclist.addr[i++], p->dmi_addr, ETH_ALEN); } - if (p) - printk(KERN_WARNING "%s: Multicast list is " - "longer than mc_count\n", priv->ndev->name); - err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES, HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h index e2f7fdc4d45a..9799a1d14a63 100644 --- a/drivers/net/wireless/orinoco/hw.h +++ b/drivers/net/wireless/orinoco/hw.h @@ -43,7 +43,7 @@ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, u8 *tsc, size_t tsc_len); int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx); int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, - struct dev_addr_list *mc_list, + struct net_device *dev, int mc_count, int promisc); int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]); diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index a9e9cea2d767..b42634c614b5 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1676,8 +1676,7 @@ __orinoco_set_multicast_list(struct net_device *dev) mc_count = netdev_mc_count(dev); } - err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count, - promisc); + err = __orinoco_hw_set_multicast_list(priv, dev, mc_count, promisc); return err; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 85905cab4f16..84c530aa52f9 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1871,10 +1871,8 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, /*===========================================================================*/ static void ray_update_multi_list(struct net_device *dev, int all) { - struct dev_mc_list *dmi, **dmip; int ccsindex; struct ccs __iomem *pccs; - int i = 0; ray_dev_t *local = netdev_priv(dev); struct pcmcia_device *link = local->finder; void __iomem *p = local->sram + HOST_TO_ECF_BASE; @@ -1895,9 +1893,11 @@ static void ray_update_multi_list(struct net_device *dev, int all) writeb(0xff, &pccs->var); local->num_multi = 0xff; } else { + struct dev_mc_list *dmi; + int i = 0; + /* Copy the kernel's list of MC addresses to card */ - for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; - dmip = &dmi->next) { + netdev_for_each_mc_addr(dmi, dev) { memcpy_toio(p, dmi->dmi_addr, ETH_ALEN); dev_dbg(&link->dev, "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n", diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 65cbd060cc30..9f6d6bf06b8e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1502,6 +1502,7 @@ static void set_multicast_list(struct usbnet *usbdev) filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; + netif_addr_lock_bh(usbdev->net); if (usbdev->net->flags & IFF_PROMISC) { filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | RNDIS_PACKET_TYPE_ALL_LOCAL; @@ -1515,16 +1516,15 @@ static void set_multicast_list(struct usbnet *usbdev) netdev_warn(usbdev->net, "couldn't alloc %d bytes of memory\n", size * ETH_ALEN); + netif_addr_unlock_bh(usbdev->net); return; } - mclist = usbdev->net->mc_list; - for (i = 0; i < size && mclist; mclist = mclist->next) { - if (mclist->dmi_addrlen != ETH_ALEN) - continue; - - memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); - i++; + i = 0; + netdev_for_each_mc_addr(mclist, usbdev->net) { + if (i == size) + break; + memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); } ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, @@ -1539,6 +1539,7 @@ static void set_multicast_list(struct usbnet *usbdev) kfree(buf); } + netif_addr_unlock_bh(usbdev->net); ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 5d2b52f4717f..6917286edcae 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -875,17 +875,16 @@ static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev) static void zd1201_set_multicast(struct net_device *dev) { struct zd1201 *zd = netdev_priv(dev); - struct dev_mc_list *mc = dev->mc_list; + struct dev_mc_list *mc; unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI]; int i; if (netdev_mc_count(dev) > ZD1201_MAXMULTI) return; - for (i=0; idmi_addr, ETH_ALEN); - mc = mc->next; - } + i = 0; + netdev_for_each_mc_addr(mc, dev) + memcpy(reqbuf + i++ * ETH_ALEN, mc->dmi_addr, ETH_ALEN); zd1201_setconfig(zd, ZD1201_RID_CNFGROUPADDRESS, reqbuf, netdev_mc_count(dev) * ETH_ALEN, 0); } -- cgit v1.2.3