X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Flibertas%2Fmain.c;h=5c58c50b430d2ff49bb799f7c78780d24308251e;hb=6a8121572e2f2d188f04673bfa460ccfcedeb008;hp=dcbf102a057e79895fdf4e662fcc5bc412ab5a92;hpb=bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775;p=powerpc.git diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index dcbf102a05..5c58c50b43 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -4,6 +4,7 @@ * thread etc.. */ +#include #include #include #include @@ -11,6 +12,7 @@ #include #include +#include #include "host.h" #include "sbi.h" @@ -21,9 +23,19 @@ #include "debugfs.h" #include "assoc.h" -#ifdef ENABLE_PM -static struct pm_dev *wlan_pm_dev = NULL; +#define DRIVER_RELEASE_VERSION "320.p0" +const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION +#ifdef DEBUG + "-dbg" #endif + ""; + + +/* Module parameters */ +unsigned int libertas_debug = 0; +module_param(libertas_debug, int, 0644); + + #define WLAN_TX_PWR_DEFAULT 20 /*100mW */ #define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */ @@ -138,14 +150,6 @@ static struct region_cfp_table region_cfp_table[] = { /*Add new region here */ }; -/** - * the rates supported by the card - */ -u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] = - { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, - 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 -}; - /** * the rates supported */ @@ -165,16 +169,6 @@ u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] = */ u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 }; -/** - * the global variable of a pointer to wlan_private - * structure variable - */ -static wlan_private *wlanpriv = NULL; - -#define MAX_DEVS 5 -static struct net_device *libertas_devs[MAX_DEVS]; -static int libertas_found = 0; - /** * the table to keep region code */ @@ -210,7 +204,6 @@ static ssize_t libertas_mpp_set(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { struct cmd_ds_mesh_access mesh_access; - memset(&mesh_access, 0, sizeof(mesh_access)); sscanf(buf, "%d", &(mesh_access.data[0])); libertas_prepare_and_send_command((to_net_dev(dev))->priv, @@ -238,7 +231,8 @@ static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get, * function to work around the issue. * */ -static int pre_open_check(struct net_device *dev) { +static int pre_open_check(struct net_device *dev) +{ wlan_private *priv = (wlan_private *) dev->priv; wlan_adapter *adapter = priv->adapter; int i = 0; @@ -248,8 +242,7 @@ static int pre_open_check(struct net_device *dev) { msleep_interruptible(100); } if (!adapter->fw_ready) { - lbs_pr_info("FW not ready, pre_open_check() return failure\n"); - LEAVE(); + lbs_pr_err("firmware not ready\n"); return -1; } @@ -267,17 +260,19 @@ static int wlan_dev_open(struct net_device *dev) wlan_private *priv = (wlan_private *) dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); - + lbs_deb_enter(LBS_DEB_NET); priv->open = 1; if (adapter->connect_status == libertas_connected) { netif_carrier_on(priv->wlan_dev.netdev); - } else + netif_carrier_on(priv->mesh_dev); + } else { netif_carrier_off(priv->wlan_dev.netdev); + netif_carrier_off(priv->mesh_dev); + } - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); return 0; } /** @@ -290,10 +285,10 @@ static int mesh_open(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv ; - if(pre_open_check(dev) == -1) + if (pre_open_check(dev) == -1) return -1; priv->mesh_open = 1 ; - netif_start_queue(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); if (priv->infra_open == 0) return wlan_dev_open(priv->wlan_dev.netdev) ; return 0; @@ -322,12 +317,13 @@ static int wlan_dev_close(struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); netif_carrier_off(priv->wlan_dev.netdev); + netif_carrier_off(priv->mesh_dev); priv->open = 0; - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); return 0; } @@ -355,7 +351,8 @@ static int mesh_close(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int wlan_close(struct net_device *dev) { +static int wlan_close(struct net_device *dev) +{ wlan_private *priv = (wlan_private *) dev->priv; netif_stop_queue(priv->wlan_dev.netdev); @@ -367,123 +364,12 @@ static int wlan_close(struct net_device *dev) { } -#ifdef ENABLE_PM - -/** - * @brief This function is a callback function. it is called by - * kernel to enter or exit power saving mode. - * - * @param pmdev A pointer to pm_dev - * @param pmreq pm_request_t - * @param pmdata A pointer to pmdata - * @return 0 or -1 - */ -static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq, - void *pmdata) -{ - wlan_private *priv = wlanpriv; - wlan_adapter *adapter = priv->adapter; - struct net_device *dev = priv->wlan_dev.netdev; - - lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq); - - switch (pmreq) { - case PM_SUSPEND: - lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n"); - - /* in associated mode */ - if (adapter->connect_status == libertas_connected) { - if ((adapter->psstate != PS_STATE_SLEEP) - ) { - lbs_pr_debug(1, - "wlan_pm_callback: can't enter sleep mode\n"); - return -1; - } else { - - /* - * Detach the network interface - * if the network is running - */ - if (netif_running(dev)) { - netif_device_detach(dev); - lbs_pr_debug(1, - "netif_device_detach().\n"); - } - libertas_sbi_suspend(priv); - } - break; - } - - /* in non associated mode */ - - /* - * Detach the network interface - * if the network is running - */ - if (netif_running(dev)) - netif_device_detach(dev); - - /* - * Storing and restoring of the regs be taken care - * at the driver rest will be done at wlan driver - * this makes driver independent of the card - */ - - libertas_sbi_suspend(priv); - - break; - - case PM_RESUME: - /* in associated mode */ - if (adapter->connect_status == libertas_connected) { - { - /* - * Bring the inteface up first - * This case should not happen still ... - */ - libertas_sbi_resume(priv); - - /* - * Attach the network interface - * if the network is running - */ - if (netif_running(dev)) { - netif_device_attach(dev); - lbs_pr_debug(1, - "after netif_device_attach().\n"); - } - lbs_pr_debug(1, - "After netif attach, in associated mode.\n"); - } - break; - } - - /* in non associated mode */ - - /* - * Bring the inteface up first - * This case should not happen still ... - */ - - libertas_sbi_resume(priv); - - if (netif_running(dev)) - netif_device_attach(dev); - - lbs_pr_debug(1, "after netif attach, in NON associated mode.\n"); - break; - } - - return 0; -} -#endif /* ENABLE_PM */ - static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int ret = 0; wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); if (priv->wlan_dev.dnld_sent || priv->adapter->TxLockFlag) { priv->stats.tx_dropped++; @@ -491,11 +377,12 @@ static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } netif_stop_queue(priv->wlan_dev.netdev); + netif_stop_queue(priv->mesh_dev); if (libertas_process_tx(priv, skb) == 0) dev->trans_start = jiffies; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); return ret; } @@ -506,31 +393,41 @@ done: static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + int ret; + + lbs_deb_enter(LBS_DEB_MESH); + SET_MESH_FRAME(skb); - LEAVE(); - return wlan_hard_start_xmit(skb, priv->wlan_dev.netdev); + ret = wlan_hard_start_xmit(skb, priv->wlan_dev.netdev); + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); + return ret; } /** * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit * */ -static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { - ENTER(); +static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int ret; + + lbs_deb_enter(LBS_DEB_NET); + UNSET_MESH_FRAME(skb); - LEAVE(); - return wlan_hard_start_xmit(skb, dev); + + ret = wlan_hard_start_xmit(skb, dev); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + return ret; } static void wlan_tx_timeout(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_TX); - lbs_pr_err("tx watch dog timeout!\n"); + lbs_pr_err("tx watch dog timeout\n"); priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED; dev->trans_start = jiffies; @@ -543,10 +440,12 @@ static void wlan_tx_timeout(struct net_device *dev) libertas_send_tx_feedback(priv); } else wake_up_interruptible(&priv->mainthread.waitq); - } else if (priv->adapter->connect_status == libertas_connected) + } else if (priv->adapter->connect_status == libertas_connected) { netif_wake_queue(priv->wlan_dev.netdev); + netif_wake_queue(priv->mesh_dev); + } - LEAVE(); + lbs_deb_leave(LBS_DEB_TX); } /** @@ -569,7 +468,7 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) wlan_adapter *adapter = priv->adapter; struct sockaddr *phwaddr = addr; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); memset(adapter->current_addr, 0, ETH_ALEN); @@ -584,17 +483,18 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) cmd_option_waitforrsp, 0, NULL); if (ret) { - lbs_pr_debug(1, "set mac address failed.\n"); + lbs_deb_net("set MAC address failed\n"); ret = -1; goto done; } lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN); memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN); - memcpy(((wlan_private *) dev->priv)->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); + if (priv->mesh_dev) + memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); return ret; } @@ -619,12 +519,12 @@ static void wlan_set_multicast_list(struct net_device *dev) wlan_adapter *adapter = priv->adapter; int oldpacketfilter; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); oldpacketfilter = adapter->currentpacketfilter; if (dev->flags & IFF_PROMISC) { - lbs_pr_debug(1, "enable Promiscuous mode\n"); + lbs_deb_net("enable promiscuous mode\n"); adapter->currentpacketfilter |= cmd_act_mac_promiscuous_enable; adapter->currentpacketfilter &= @@ -637,7 +537,7 @@ static void wlan_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_ALLMULTI || dev->mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) { - lbs_pr_debug(1, "Enabling All Multicast!\n"); + lbs_deb_net( "enabling all multicast\n"); adapter->currentpacketfilter |= cmd_act_mac_all_multicast_enable; adapter->currentpacketfilter &= @@ -647,8 +547,8 @@ static void wlan_set_multicast_list(struct net_device *dev) ~cmd_act_mac_all_multicast_enable; if (!dev->mc_count) { - lbs_pr_debug(1, "No multicast addresses - " - "disabling multicast!\n"); + lbs_deb_net("no multicast addresses, " + "disabling multicast\n"); adapter->currentpacketfilter &= ~cmd_act_mac_multicast_enable; } else { @@ -660,12 +560,12 @@ static void wlan_set_multicast_list(struct net_device *dev) adapter->nr_of_multicastmacaddr = wlan_copy_multicast_address(adapter, dev); - lbs_pr_debug(1, "Multicast addresses: %d\n", + lbs_deb_net("multicast addresses: %d\n", dev->mc_count); for (i = 0; i < dev->mc_count; i++) { - lbs_pr_debug(1, "Multicast address %d:" - "%x %x %x %x %x %x\n", i, + lbs_deb_net("Multicast address %d:" + MAC_FMT "\n", i, adapter->multicastlist[i][0], adapter->multicastlist[i][1], adapter->multicastlist[i][2], @@ -673,7 +573,7 @@ static void wlan_set_multicast_list(struct net_device *dev) adapter->multicastlist[i][4], adapter->multicastlist[i][5]); } - /* set multicast addresses to firmware */ + /* send multicast addresses to firmware */ libertas_prepare_and_send_command(priv, cmd_mac_multicast_adr, cmd_act_set, 0, 0, @@ -686,13 +586,13 @@ static void wlan_set_multicast_list(struct net_device *dev) libertas_set_mac_packet_filter(priv); } - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); } /** - * @brief This function hanldes the major job in WLAN driver. - * it handles the event generated by firmware, rx data received - * from firmware and tx data sent from kernel. + * @brief This function handles the major jobs in the WLAN driver. + * It handles all events generated by firmware, RX data received + * from firmware and TX data sent from kernel. * * @param data A pointer to wlan_thread structure * @return 0 @@ -705,14 +605,14 @@ static int wlan_service_main_thread(void *data) wait_queue_t wait; u8 ireg = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); wlan_activate_thread(thread); init_waitqueue_entry(&wait, current); for (;;) { - lbs_pr_debug(1, "main-thread 111: intcounter=%d " + lbs_deb_thread( "main-thread 111: intcounter=%d " "currenttxskb=%p dnld_sent=%d\n", adapter->intcounter, adapter->currenttxskb, priv->wlan_dev.dnld_sent); @@ -724,7 +624,7 @@ static int wlan_service_main_thread(void *data) (!adapter->intcounter && (priv->wlan_dev.dnld_sent || adapter->cur_cmd || list_empty(&adapter->cmdpendingq)))) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n", adapter->connect_status, adapter->intcounter, adapter->psmode, adapter->psstate); @@ -734,7 +634,7 @@ static int wlan_service_main_thread(void *data) spin_unlock_irq(&adapter->driver_lock); - lbs_pr_debug(1, + lbs_deb_thread( "main-thread 222 (waking up): intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, adapter->currenttxskb, priv->wlan_dev.dnld_sent); @@ -743,14 +643,14 @@ static int wlan_service_main_thread(void *data) remove_wait_queue(&thread->waitq, &wait); try_to_freeze(); - lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p " + lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, adapter->currenttxskb, priv->wlan_dev.dnld_sent); if (kthread_should_stop() || adapter->surpriseremoved) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread: break from main thread: surpriseremoved=0x%x\n", adapter->surpriseremoved); break; @@ -764,7 +664,7 @@ static int wlan_service_main_thread(void *data) int_status = libertas_sbi_get_int_status(priv, &ireg); if (int_status) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread: reading HOST_INT_STATUS_REG failed\n"); spin_unlock_irq(&adapter->driver_lock); continue; @@ -772,14 +672,14 @@ static int wlan_service_main_thread(void *data) adapter->hisregcpy |= ireg; } - lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p " + lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, adapter->currenttxskb, priv->wlan_dev.dnld_sent); /* command response? */ if (adapter->hisregcpy & his_cmdupldrdy) { - lbs_pr_debug(1, "main-thread: cmd response ready.\n"); + lbs_deb_thread("main-thread: cmd response ready\n"); adapter->hisregcpy &= ~his_cmdupldrdy; spin_unlock_irq(&adapter->driver_lock); @@ -789,13 +689,13 @@ static int wlan_service_main_thread(void *data) /* Any Card Event */ if (adapter->hisregcpy & his_cardevent) { - lbs_pr_debug(1, "main-thread: Card Event Activity.\n"); + lbs_deb_thread("main-thread: Card Event Activity\n"); adapter->hisregcpy &= ~his_cardevent; if (libertas_sbi_read_event_cause(priv)) { lbs_pr_alert( - "main-thread: libertas_sbi_read_event_cause failed.\n"); + "main-thread: libertas_sbi_read_event_cause failed\n"); spin_unlock_irq(&adapter->driver_lock); continue; } @@ -809,7 +709,7 @@ static int wlan_service_main_thread(void *data) if (!priv->wlan_dev.dnld_sent && !adapter->cur_cmd) { if (adapter->connect_status == libertas_connected) { - lbs_pr_debug(1, + lbs_deb_thread( "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p " "dnld_sent=%d cur_cmd=%p, confirm now\n", adapter->intcounter, @@ -857,7 +757,7 @@ static int wlan_service_main_thread(void *data) wake_up_all(&adapter->cmd_pending); wlan_deactivate_thread(thread); - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); return 0; } @@ -871,46 +771,29 @@ static int wlan_service_main_thread(void *data) wlan_private *wlan_add_card(void *card) { struct net_device *dev = NULL; - struct net_device *mesh_dev = NULL; wlan_private *priv = NULL; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); /* Allocate an Ethernet device and register it */ if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { - lbs_pr_alert( "Init ethernet device failed!\n"); + lbs_pr_err("init ethX device failed\n"); return NULL; } - priv = dev->priv; /* allocate buffer for wlan_adapter */ - if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) { - lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n"); - goto err_kmalloc; - } - - /* Allocate a virtual mesh device */ - if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) { - lbs_pr_debug(1, "Init ethernet device failed!\n"); - return NULL; + if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) { + lbs_pr_err("allocate buffer for wlan_adapter failed\n"); + goto err_kzalloc; } - /* Both intervaces share the priv structure */ - mesh_dev->priv = priv; - - /* init wlan_adapter */ - memset(priv->adapter, 0, sizeof(wlan_adapter)); - priv->wlan_dev.netdev = dev; priv->wlan_dev.card = card; priv->mesh_open = 0; priv->infra_open = 0; - priv->mesh_dev = mesh_dev; - wlanpriv = priv; SET_MODULE_OWNER(dev); - SET_MODULE_OWNER(mesh_dev); /* Setup the OS Interface to our functions */ dev->open = wlan_open; @@ -918,25 +801,12 @@ wlan_private *wlan_add_card(void *card) dev->stop = wlan_close; dev->do_ioctl = libertas_do_ioctl; dev->set_mac_address = wlan_set_mac_address; - mesh_dev->open = mesh_open; - mesh_dev->hard_start_xmit = mesh_pre_start_xmit; - mesh_dev->stop = mesh_close; - mesh_dev->do_ioctl = libertas_do_ioctl; - memcpy(mesh_dev->dev_addr, wlanpriv->wlan_dev.netdev->dev_addr, - sizeof(wlanpriv->wlan_dev.netdev->dev_addr)); - -#define WLAN_WATCHDOG_TIMEOUT (5 * HZ) - dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; - dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT; + dev->watchdog_timeo = 5 * HZ; dev->ethtool_ops = &libertas_ethtool_ops; - mesh_dev->get_stats = wlan_get_stats; - mesh_dev->ethtool_ops = &libertas_ethtool_ops; - #ifdef WIRELESS_EXT dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; - mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; #endif #define NETIF_F_DYNALLOC 16 dev->features |= NETIF_F_DYNALLOC; @@ -949,15 +819,31 @@ wlan_private *wlan_add_card(void *card) spin_lock_init(&priv->adapter->driver_lock); init_waitqueue_head(&priv->adapter->cmd_pending); priv->adapter->nr_cmd_pending = 0; + goto done; + +err_kzalloc: + free_netdev(dev); + priv = NULL; +done: + lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv); + return priv; +} + +int libertas_activate_card(wlan_private *priv) +{ + struct net_device *dev = priv->wlan_dev.netdev; + int ret = -1; + + lbs_deb_enter(LBS_DEB_MAIN); - lbs_pr_debug(1, "Starting kthread...\n"); + lbs_deb_thread("Starting kthread...\n"); priv->mainthread.priv = priv; wlan_create_thread(wlan_service_main_thread, &priv->mainthread, "wlan_main_service"); priv->assoc_thread = create_singlethread_workqueue("libertas_assoc"); - INIT_DELAYED_WORK(&priv->assoc_work, wlan_association_worker); + INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); /* * Register the device. Fillup the private data structure with @@ -965,47 +851,28 @@ wlan_private *wlan_add_card(void *card) * IRQ. */ if (libertas_sbi_register_dev(priv) < 0) { - lbs_pr_info("failed to register wlan device!\n"); + lbs_pr_err("failed to register WLAN device\n"); goto err_registerdev; } /* init FW and HW */ if (libertas_init_fw(priv)) { - lbs_pr_debug(1, "Firmware Init failed\n"); + lbs_pr_err("firmware init failed\n"); goto err_registerdev; } if (register_netdev(dev)) { - lbs_pr_err("Cannot register network device!\n"); + lbs_pr_err("cannot register ethX device\n"); goto err_init_fw; } - /* Register virtual mesh interface */ - if (register_netdev(mesh_dev)) { - lbs_pr_info("Cannot register mesh virtual interface!\n"); - goto err_init_fw; - } - - lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev->name); + lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); libertas_debugfs_init_one(priv, dev); - if (libertas_found == MAX_DEVS) - goto err_init_fw; - libertas_devs[libertas_found] = dev; - libertas_found++; -#ifdef ENABLE_PM - if (!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback))) - lbs_pr_alert( "failed to register PM callback\n"); -#endif - if (device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp)) - goto err_create_file; - - LEAVE(); - return priv; + ret = 0; + goto done; -err_create_file: - device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); err_init_fw: libertas_sbi_unregister_dev(priv); err_registerdev: @@ -1014,13 +881,75 @@ err_registerdev: wake_up_interruptible(&priv->mainthread.waitq); wlan_terminate_thread(&priv->mainthread); kfree(priv->adapter); -err_kmalloc: free_netdev(dev); +done: + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + return ret; +} + +/** + * @brief This function adds mshX interface + * + * @param priv A pointer to the wlan_private structure + * @return 0 if successful, -X otherwise + */ +int wlan_add_mesh(wlan_private *priv) +{ + struct net_device *mesh_dev = NULL; + int ret = 0; + + lbs_deb_enter(LBS_DEB_MESH); + + /* Allocate a virtual mesh device */ + if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) { + lbs_deb_mesh("init mshX device failed\n"); + ret = -ENOMEM; + goto done; + } + mesh_dev->priv = priv; + priv->mesh_dev = mesh_dev; + + SET_MODULE_OWNER(mesh_dev); + + mesh_dev->open = mesh_open; + mesh_dev->hard_start_xmit = mesh_pre_start_xmit; + mesh_dev->stop = mesh_close; + mesh_dev->do_ioctl = libertas_do_ioctl; + mesh_dev->get_stats = wlan_get_stats; + mesh_dev->ethtool_ops = &libertas_ethtool_ops; + memcpy(mesh_dev->dev_addr, priv->wlan_dev.netdev->dev_addr, + sizeof(priv->wlan_dev.netdev->dev_addr)); + +#ifdef WIRELESS_EXT + mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; +#endif +#define NETIF_F_DYNALLOC 16 + + /* Register virtual mesh interface */ + ret = register_netdev(mesh_dev); + if (ret) { + lbs_pr_err("cannot register mshX virtual interface\n"); + goto err_free; + } + + ret = device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); + if (ret) + goto err_unregister; + + /* Everything successful */ + ret = 0; + goto done; + + +err_unregister: + unregister_netdev(mesh_dev); + +err_free: free_netdev(mesh_dev); - wlanpriv = NULL; - LEAVE(); - return NULL; +done: + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); + return ret; } static void wake_pending_cmdnodes(wlan_private *priv) @@ -1028,6 +957,8 @@ static void wake_pending_cmdnodes(wlan_private *priv) struct cmd_ctrl_node *cmdnode; unsigned long flags; + lbs_deb_enter(LBS_DEB_CMD); + spin_lock_irqsave(&priv->adapter->driver_lock, flags); list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) { cmdnode->cmdwaitqwoken = 1; @@ -1037,40 +968,29 @@ static void wake_pending_cmdnodes(wlan_private *priv) } -int wlan_remove_card(void *card) +int wlan_remove_card(wlan_private *priv) { - wlan_private *priv = libertas_sbi_get_priv(card); wlan_adapter *adapter; struct net_device *dev; - struct net_device *mesh_dev; union iwreq_data wrqu; - int i; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); - if (!priv) { - LEAVE(); - return 0; - } + if (!priv) + goto out; adapter = priv->adapter; - if (!adapter) { - LEAVE(); - return 0; - } + if (!adapter) + goto out; dev = priv->wlan_dev.netdev; - mesh_dev = priv->mesh_dev; - netif_stop_queue(mesh_dev); netif_stop_queue(priv->wlan_dev.netdev); netif_carrier_off(priv->wlan_dev.netdev); wake_pending_cmdnodes(priv); - device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); - unregister_netdev(mesh_dev); unregister_netdev(dev); cancel_delayed_work(&priv->assoc_work); @@ -1085,10 +1005,6 @@ int wlan_remove_card(void *card) wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); -#ifdef ENABLE_PM - pm_unregister(wlan_pm_dev); -#endif - adapter->surpriseremoved = 1; /* Stop the thread servicing the interrupts */ @@ -1096,29 +1012,43 @@ int wlan_remove_card(void *card) libertas_debugfs_remove_one(priv); - lbs_pr_debug(1, "Free adapter\n"); + lbs_deb_net("free adapter\n"); libertas_free_adapter(priv); - for (i = 0; iwlan_dev.netdev) { - libertas_devs[i] = libertas_devs[--libertas_found]; - libertas_devs[libertas_found] = NULL ; - break ; - } - } - - lbs_pr_debug(1, "Unregister finish\n"); + lbs_deb_net("unregister finish\n"); priv->wlan_dev.netdev = NULL; - priv->mesh_dev = NULL ; - free_netdev(mesh_dev); free_netdev(dev); - wlanpriv = NULL; - LEAVE(); +out: + lbs_deb_leave(LBS_DEB_NET); return 0; } +void wlan_remove_mesh(wlan_private *priv) +{ + struct net_device *mesh_dev; + + lbs_deb_enter(LBS_DEB_NET); + + if (!priv) + goto out; + + mesh_dev = priv->mesh_dev; + + netif_stop_queue(mesh_dev); + netif_carrier_off(priv->mesh_dev); + + device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); + unregister_netdev(mesh_dev); + + priv->mesh_dev = NULL ; + free_netdev(mesh_dev); + +out: + lbs_deb_leave(LBS_DEB_NET); +} + /** * @brief This function finds the CFP in * region_cfp_table based on region and band parameter. @@ -1132,33 +1062,34 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c { int i, end; - ENTER(); + lbs_deb_enter(LBS_DEB_MAIN); end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table); for (i = 0; i < end ; i++) { - lbs_pr_debug(1, "region_cfp_table[i].region=%d\n", + lbs_deb_main("region_cfp_table[i].region=%d\n", region_cfp_table[i].region); if (region_cfp_table[i].region == region) { *cfp_no = region_cfp_table[i].cfp_no_BG; - LEAVE(); + lbs_deb_leave(LBS_DEB_MAIN); return region_cfp_table[i].cfp_BG; } } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL"); return NULL; } int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) { wlan_adapter *adapter = priv->adapter; + int ret = 0; int i = 0; struct chan_freq_power *cfp; int cfp_no; - ENTER(); + lbs_deb_enter(LBS_DEB_MAIN); memset(adapter->region_channel, 0, sizeof(adapter->region_channel)); @@ -1168,17 +1099,19 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) adapter->region_channel[i].nrcfp = cfp_no; adapter->region_channel[i].CFP = cfp; } else { - lbs_pr_debug(1, "wrong region code %#x in band B-G\n", + lbs_deb_main("wrong region code %#x in band B/G\n", region); - return -1; + ret = -1; + goto out; } adapter->region_channel[i].valid = 1; adapter->region_channel[i].region = region; adapter->region_channel[i].band = band; i++; } - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); + return ret; } /** @@ -1193,9 +1126,9 @@ void libertas_interrupt(struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); - lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n", + lbs_deb_thread("libertas_interrupt: intcounter=%d\n", priv->adapter->intcounter); priv->adapter->intcounter++; @@ -1203,18 +1136,19 @@ void libertas_interrupt(struct net_device *dev) if (priv->adapter->psstate == PS_STATE_SLEEP) { priv->adapter->psstate = PS_STATE_AWAKE; netif_wake_queue(dev); + netif_wake_queue(priv->mesh_dev); } wake_up_interruptible(&priv->mainthread.waitq); - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); } static int wlan_init_module(void) { int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_MAIN); if (libertas_fw_name == NULL) { libertas_fw_name = default_fw_name; @@ -1225,29 +1159,20 @@ static int wlan_init_module(void) if (libertas_sbi_register()) { ret = -1; libertas_debugfs_remove(); - goto done; } -done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } static void wlan_cleanup_module(void) { - int i; - - ENTER(); - - for (i = 0; ipriv; - reset_device(priv); - } + lbs_deb_enter(LBS_DEB_MAIN); libertas_sbi_unregister(); libertas_debugfs_remove(); - LEAVE(); + lbs_deb_leave(LBS_DEB_MAIN); } module_init(wlan_init_module);