linux/drivers/net/wireless/intel/ipw2x00/ipw2100.c

// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************

  Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.


  Contact Information:
  Intel Linux Wireless <[email protected]>
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

  Portions of this file are based on the sample_* files provided by Wireless
  Extensions 0.26 package and copyright (c) 1997-2003 Jean Tourrilhes
  <[email protected]>

  Portions of this file are based on the Host AP project,
  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
    <[email protected]>
  Copyright (c) 2002-2003, Jouni Malinen <[email protected]>

  Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and
  ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c
  available in the 2.4.25 kernel sources, and are copyright (c) Alan Cox

******************************************************************************/
/*

 Initial driver on which this is based was developed by Janusz Gorycki,
 Maciej Urbaniak, and Maciej Sosnowski.

 Promiscuous mode support added by Jacek Wysoczynski and Maciej Urbaniak.

Theory of Operation

Tx - Commands and Data

Firmware and host share a circular queue of Transmit Buffer Descriptors (TBDs)
Each TBD contains a pointer to the physical (dma_addr_t) address of data being
sent to the firmware as well as the length of the data.

The host writes to the TBD queue at the WRITE index.  The WRITE index points
to the _next_ packet to be written and is advanced when after the TBD has been
filled.

The firmware pulls from the TBD queue at the READ index.  The READ index points
to the currently being read entry, and is advanced once the firmware is
done with a packet.

When data is sent to the firmware, the first TBD is used to indicate to the
firmware if a Command or Data is being sent.  If it is Command, all of the
command information is contained within the physical address referred to by the
TBD.  If it is Data, the first TBD indicates the type of data packet, number
of fragments, etc.  The next TBD then refers to the actual packet location.

The Tx flow cycle is as follows:

1) ipw2100_tx() is called by kernel with SKB to transmit
2) Packet is move from the tx_free_list and appended to the transmit pending
   list (tx_pend_list)
3) work is scheduled to move pending packets into the shared circular queue.
4) when placing packet in the circular queue, the incoming SKB is DMA mapped
   to a physical address.  That address is entered into a TBD.  Two TBDs are
   filled out.  The first indicating a data packet, the second referring to the
   actual payload data.
5) the packet is removed from tx_pend_list and placed on the end of the
   firmware pending list (fw_pend_list)
6) firmware is notified that the WRITE index has
7) Once the firmware has processed the TBD, INTA is triggered.
8) For each Tx interrupt received from the firmware, the READ index is checked
   to see which TBDs are done being processed.
9) For each TBD that has been processed, the ISR pulls the oldest packet
   from the fw_pend_list.
10)The packet structure contained in the fw_pend_list is then used
   to unmap the DMA address and to free the SKB originally passed to the driver
   from the kernel.
11)The packet structure is placed onto the tx_free_list

The above steps are the same for commands, only the msg_free_list/msg_pend_list
are used instead of tx_free_list/tx_pend_list

...

Critical Sections / Locking :

There are two locks utilized.  The first is the low level lock (priv->low_lock)
that protects the following:

- Access to the Tx/Rx queue lists via priv->low_lock. The lists are as follows:

  tx_free_list : Holds pre-allocated Tx buffers.
    TAIL modified in __ipw2100_tx_process()
    HEAD modified in ipw2100_tx()

  tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
    TAIL modified ipw2100_tx()
    HEAD modified by ipw2100_tx_send_data()

  msg_free_list : Holds pre-allocated Msg (Command) buffers
    TAIL modified in __ipw2100_tx_process()
    HEAD modified in ipw2100_hw_send_command()

  msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
    TAIL modified in ipw2100_hw_send_command()
    HEAD modified in ipw2100_tx_send_commands()

  The flow of data on the TX side is as follows:

  MSG_FREE_LIST + COMMAND => MSG_PEND_LIST => TBD => MSG_FREE_LIST
  TX_FREE_LIST + DATA => TX_PEND_LIST => TBD => TX_FREE_LIST

  The methods that work on the TBD ring are protected via priv->low_lock.

- The internal data state of the device itself
- Access to the firmware read/write indexes for the BD queues
  and associated logic

All external entry functions are locked with the priv->action_lock to ensure
that only one external action is invoked at a time.


*/

#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/stringify.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/time.h>
#include <linux/firmware.h>
#include <linux/acpi.h>
#include <linux/ctype.h>
#include <linux/pm_qos.h>

#include <net/lib80211.h>

#include "ipw2100.h"
#include "ipw.h"

#define IPW2100_VERSION

#define DRV_NAME
#define DRV_VERSION
#define DRV_DESCRIPTION
#define DRV_COPYRIGHT

static struct pm_qos_request ipw2100_pm_qos_req;

/* Debugging stuff */
#ifdef CONFIG_IPW2100_DEBUG
#define IPW2100_RX_DEBUG
#endif

MODULE_DESCRIPTION();
MODULE_VERSION();
MODULE_AUTHOR();
MODULE_LICENSE();

static int debug =;
static int network_mode =;
static int channel =;
static int associate =;
static int disable =;
#ifdef CONFIG_PM
static struct ipw2100_fw ipw2100_firmware;
#endif

#include <linux/moduleparam.h>
module_param(debug, int, 0444);
module_param_named(mode, network_mode, int, 0444);
module_param(channel, int, 0444);
module_param(associate, int, 0444);
module_param(disable, int, 0444);

MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();

static u32 ipw2100_debug_level =;

#ifdef CONFIG_IPW2100_DEBUG
#define IPW_DEBUG(level, message...)
#else
#define IPW_DEBUG
#endif				/* CONFIG_IPW2100_DEBUG */

#ifdef CONFIG_IPW2100_DEBUG
static const char *command_types[] =;
#endif

static const long ipw2100_frequencies[] =;

#define FREQ_COUNT

static struct ieee80211_rate ipw2100_bg_rates[] =;

#define RATE_COUNT

/* Pre-decl until we get the code solid and then we can clean it up */
static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
static int ipw2100_adapter_setup(struct ipw2100_priv *priv);

static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
static void ipw2100_queues_free(struct ipw2100_priv *priv);
static int ipw2100_queues_allocate(struct ipw2100_priv *priv);

static int ipw2100_fw_download(struct ipw2100_priv *priv,
			       struct ipw2100_fw *fw);
static int ipw2100_get_firmware(struct ipw2100_priv *priv,
				struct ipw2100_fw *fw);
static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
				 size_t max);
static void ipw2100_release_firmware(struct ipw2100_priv *priv,
				     struct ipw2100_fw *fw);
static int ipw2100_ucode_download(struct ipw2100_priv *priv,
				  struct ipw2100_fw *fw);
static void ipw2100_wx_event_work(struct work_struct *work);
static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
static const struct iw_handler_def ipw2100_wx_handler_def;

static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
{}

static inline void write_register(struct net_device *dev, u32 reg, u32 val)
{}

static inline void read_register_word(struct net_device *dev, u32 reg,
				      u16 * val)
{}

static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
{}

static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
{}

static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
{}

static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
{}

static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
{}

static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
{}

static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
{}

static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
{}

static inline void write_nic_byte(struct net_device *dev, u32 addr, u8 val)
{}

static void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
				    const u8 * buf)
{}

static void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
				   u8 * buf)
{}

static bool ipw2100_hw_is_adapter_in_system(struct net_device *dev)
{}

static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
			       void *val, u32 * len)
{}

static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
			       u32 * len)
{}

static char *snprint_line(char *buf, size_t count,
			  const u8 * data, u32 len, u32 ofs)
{}

static void printk_buf(int level, const u8 * data, u32 len)
{}

#define MAX_RESET_BACKOFF

static void schedule_reset(struct ipw2100_priv *priv)
{}

#define HOST_COMPLETE_TIMEOUT
static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
				   struct host_command *cmd)
{}

/*
 * Verify the values and data access of the hardware
 * No locks needed or used.  No functions called.
 */
static int ipw2100_verify(struct ipw2100_priv *priv)
{}

/*
 *
 * Loop until the CARD_DISABLED bit is the same value as the
 * supplied parameter
 *
 * TODO: See if it would be more efficient to do a wait/wake
 *       cycle and have the completion event trigger the wakeup
 *
 */
#define IPW_CARD_DISABLE_COMPLETE_WAIT
static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
{}

/*********************************************************************
    Procedure   :   sw_reset_and_clock
    Purpose     :   Asserts s/w reset, asserts clock initialization
                    and waits for clock stabilization
 ********************************************************************/
static int sw_reset_and_clock(struct ipw2100_priv *priv)
{}

/*********************************************************************
    Procedure   :   ipw2100_download_firmware
    Purpose     :   Initiaze adapter after power on.
                    The sequence is:
                    1. assert s/w reset first!
                    2. awake clocks & wait for clock stabilization
                    3. hold ARC (don't ask me why...)
                    4. load Dino ucode and reset/clock init again
                    5. zero-out shared mem
                    6. download f/w
 *******************************************************************/
static int ipw2100_download_firmware(struct ipw2100_priv *priv)
{}

static inline void ipw2100_enable_interrupts(struct ipw2100_priv *priv)
{}

static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
{}

static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
{}

static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
{}

static int rf_kill_active(struct ipw2100_priv *priv)
{}

static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
{}

/*
 * Start firmware execution after power on and initialization
 * The sequence is:
 *  1. Release ARC
 *  2. Wait for f/w initialization completes;
 */
static int ipw2100_start_adapter(struct ipw2100_priv *priv)
{}

static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
{}

/* NOTE: Our interrupt is disabled when this method is called */
static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
{}

/*
 * Send the CARD_DISABLE_PHY_OFF command to the card to disable it
 *
 * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent.
 *
 * STATUS_CARD_DISABLE_NOTIFICATION will be sent regardless of
 * if STATUS_ASSN_LOST is sent.
 */
static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
{}

static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
{}

static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
{}

static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
{}

static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
{}

static int ipw2100_start_scan(struct ipw2100_priv *priv)
{}

static const struct libipw_geo ipw_geos[] =;

static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
{}

static void ipw2100_down(struct ipw2100_priv *priv)
{}

static int ipw2100_wdev_init(struct net_device *dev)
{}

static void ipw2100_reset_adapter(struct work_struct *work)
{}

static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
{}

static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
			     int length, int batch_mode)
{}

static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
{}

static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
{}

static void ipw2100_scan_event(struct work_struct *work)
{}

static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
{}

#ifdef CONFIG_IPW2100_DEBUG
#define IPW2100_HANDLER(v, f)
struct ipw2100_status_indicator {};
#else
#define IPW2100_HANDLER
struct ipw2100_status_indicator {
	int status;
	void (*cb) (struct ipw2100_priv * priv, u32 status);
};
#endif				/* CONFIG_IPW2100_DEBUG */

static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
{}

static const struct ipw2100_status_indicator status_handlers[] =;

static void isr_status_change(struct ipw2100_priv *priv, int status)
{}

static void isr_rx_complete_command(struct ipw2100_priv *priv,
				    struct ipw2100_cmd_header *cmd)
{}

#ifdef CONFIG_IPW2100_DEBUG
static const char *frame_types[] =;
#endif

static int ipw2100_alloc_skb(struct ipw2100_priv *priv,
				    struct ipw2100_rx_packet *packet)
{}

#define SEARCH_ERROR
#define SEARCH_FAIL
#define SEARCH_SUCCESS
#define SEARCH_DISCARD
#define SEARCH_SNAPSHOT

#define SNAPSHOT_ADDR(ofs)
static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
{}

#ifdef IPW2100_DEBUG_C3
static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
{
	int i;
	if (priv->snapshot[0])
		return 1;
	for (i = 0; i < 0x30; i++) {
		priv->snapshot[i] = kmalloc(0x1000, GFP_ATOMIC);
		if (!priv->snapshot[i]) {
			IPW_DEBUG_INFO("%s: Error allocating snapshot "
				       "buffer %d\n", priv->net_dev->name, i);
			while (i > 0)
				kfree(priv->snapshot[--i]);
			priv->snapshot[0] = NULL;
			return 0;
		}
	}

	return 1;
}

static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
				    size_t len, int mode)
{
	u32 i, j;
	u32 tmp;
	u8 *s, *d;
	u32 ret;

	s = in_buf;
	if (mode == SEARCH_SNAPSHOT) {
		if (!ipw2100_snapshot_alloc(priv))
			mode = SEARCH_DISCARD;
	}

	for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
		read_nic_dword(priv->net_dev, i, &tmp);
		if (mode == SEARCH_SNAPSHOT)
			*(u32 *) SNAPSHOT_ADDR(i) = tmp;
		if (ret == SEARCH_FAIL) {
			d = (u8 *) & tmp;
			for (j = 0; j < 4; j++) {
				if (*s != *d) {
					s = in_buf;
					continue;
				}

				s++;
				d++;

				if ((s - in_buf) == len)
					ret = (i + j) - len + 1;
			}
		} else if (mode == SEARCH_DISCARD)
			return ret;
	}

	return ret;
}
#endif

/*
 *
 * 0) Disconnect the SKB from the firmware (just unmap)
 * 1) Pack the ETH header into the SKB
 * 2) Pass the SKB to the network stack
 *
 * When packet is provided by the firmware, it contains the following:
 *
 * .  libipw_hdr
 * .  libipw_snap_hdr
 *
 * The size of the constructed ethernet
 *
 */
#ifdef IPW2100_RX_DEBUG
static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
#endif

static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
{}

static void isr_rx(struct ipw2100_priv *priv, int i,
			  struct libipw_rx_stats *stats)
{}

#ifdef CONFIG_IPW2100_MONITOR

static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
		   struct libipw_rx_stats *stats)
{}

#endif

static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
{}

/*
 * ipw2100 interrupts are disabled at this point, and the ISR
 * is the only code that calls this method.  So, we do not need
 * to play with any locks.
 *
 * RX Queue works as follows:
 *
 * Read index - firmware places packet in entry identified by the
 *              Read index and advances Read index.  In this manner,
 *              Read index will always point to the next packet to
 *              be filled--but not yet valid.
 *
 * Write index - driver fills this entry with an unused RBD entry.
 *               This entry has not filled by the firmware yet.
 *
 * In between the W and R indexes are the RBDs that have been received
 * but not yet processed.
 *
 * The process of handling packets will start at WRITE + 1 and advance
 * until it reaches the READ index.
 *
 * The WRITE index is cached in the variable 'priv->rx_queue.next'.
 *
 */
static void __ipw2100_rx_process(struct ipw2100_priv *priv)
{}

/*
 * __ipw2100_tx_process
 *
 * This routine will determine whether the next packet on
 * the fw_pend_list has been processed by the firmware yet.
 *
 * If not, then it does nothing and returns.
 *
 * If so, then it removes the item from the fw_pend_list, frees
 * any associated storage, and places the item back on the
 * free list of its source (either msg_free_list or tx_free_list)
 *
 * TX Queue works as follows:
 *
 * Read index - points to the next TBD that the firmware will
 *              process.  The firmware will read the data, and once
 *              done processing, it will advance the Read index.
 *
 * Write index - driver fills this entry with an constructed TBD
 *               entry.  The Write index is not advanced until the
 *               packet has been configured.
 *
 * In between the W and R indexes are the TBDs that have NOT been
 * processed.  Lagging behind the R index are packets that have
 * been processed but have not been freed by the driver.
 *
 * In order to free old storage, an internal index will be maintained
 * that points to the next packet to be freed.  When all used
 * packets have been freed, the oldest index will be the same as the
 * firmware's read index.
 *
 * The OLDEST index is cached in the variable 'priv->tx_queue.oldest'
 *
 * Because the TBD structure can not contain arbitrary data, the
 * driver must keep an internal queue of cached allocations such that
 * it can put that data back into the tx_free_list and msg_free_list
 * for use by future command and data packets.
 *
 */
static int __ipw2100_tx_process(struct ipw2100_priv *priv)
{}

static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
{}

static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
{}

/*
 * ipw2100_tx_send_data
 *
 */
static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
{}

static void ipw2100_irq_tasklet(struct tasklet_struct *t)
{}

static irqreturn_t ipw2100_interrupt(int irq, void *data)
{}

static netdev_tx_t ipw2100_tx(struct libipw_txb *txb,
			      struct net_device *dev, int pri)
{}

static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
{}

static int ipw2100_msg_initialize(struct ipw2100_priv *priv)
{}

static void ipw2100_msg_free(struct ipw2100_priv *priv)
{}

static ssize_t pci_show(struct device *d, struct device_attribute *attr,
			char *buf)
{}

static DEVICE_ATTR_RO(pci);

static ssize_t cfg_show(struct device *d, struct device_attribute *attr,
			char *buf)
{}

static DEVICE_ATTR_RO(cfg);

static ssize_t status_show(struct device *d, struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(status);

static ssize_t capability_show(struct device *d, struct device_attribute *attr,
			       char *buf)
{}

static DEVICE_ATTR_RO(capability);

#define IPW2100_REG(x)
static const struct {} hw_data[] =;
#define IPW2100_NIC(x, s)
static const struct {} nic_data[] =;
#define IPW2100_ORD(x, d)
static const struct {} ord_data[] =;

static ssize_t registers_show(struct device *d, struct device_attribute *attr,
			      char *buf)
{}

static DEVICE_ATTR_RO(registers);

static ssize_t hardware_show(struct device *d, struct device_attribute *attr,
			     char *buf)
{}

static DEVICE_ATTR_RO(hardware);

static ssize_t memory_show(struct device *d, struct device_attribute *attr,
			   char *buf)
{}

static ssize_t memory_store(struct device *d, struct device_attribute *attr,
			    const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(memory);

static ssize_t ordinals_show(struct device *d, struct device_attribute *attr,
			     char *buf)
{}

static DEVICE_ATTR_RO(ordinals);

static ssize_t stats_show(struct device *d, struct device_attribute *attr,
			  char *buf)
{}

static DEVICE_ATTR_RO(stats);

static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
{}

static ssize_t internals_show(struct device *d, struct device_attribute *attr,
			      char *buf)
{}

static DEVICE_ATTR_RO(internals);

static ssize_t bssinfo_show(struct device *d, struct device_attribute *attr,
			    char *buf)
{}

static DEVICE_ATTR_RO(bssinfo);

#ifdef CONFIG_IPW2100_DEBUG
static ssize_t debug_level_show(struct device_driver *d, char *buf)
{}

static ssize_t debug_level_store(struct device_driver *d,
				 const char *buf, size_t count)
{}
static DRIVER_ATTR_RW(debug_level);
#endif				/* CONFIG_IPW2100_DEBUG */

static ssize_t fatal_error_show(struct device *d,
				struct device_attribute *attr, char *buf)
{}

static ssize_t fatal_error_store(struct device *d,
				 struct device_attribute *attr, const char *buf,
				 size_t count)
{}

static DEVICE_ATTR_RW(fatal_error);

static ssize_t scan_age_show(struct device *d, struct device_attribute *attr,
			     char *buf)
{}

static ssize_t scan_age_store(struct device *d, struct device_attribute *attr,
			      const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(scan_age);

static ssize_t rf_kill_show(struct device *d, struct device_attribute *attr,
			    char *buf)
{}

static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
{}

static ssize_t rf_kill_store(struct device *d, struct device_attribute *attr,
			     const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(rf_kill);

static struct attribute *ipw2100_sysfs_entries[] =;

static const struct attribute_group ipw2100_attribute_group =;

static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
{}

static void status_queue_free(struct ipw2100_priv *priv)
{}

static int bd_queue_allocate(struct ipw2100_priv *priv,
			     struct ipw2100_bd_queue *q, int entries)
{}

static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
{}

static void bd_queue_initialize(struct ipw2100_priv *priv,
				struct ipw2100_bd_queue *q, u32 base, u32 size,
				u32 r, u32 w)
{}

static void ipw2100_kill_works(struct ipw2100_priv *priv)
{}

static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
{}

static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
{}

static void ipw2100_tx_free(struct ipw2100_priv *priv)
{}

static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
{}

static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
{}

static void ipw2100_rx_free(struct ipw2100_priv *priv)
{}

static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
{}

/********************************************************************
 *
 * Firmware Commands
 *
 ********************************************************************/

static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
{}

static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
				 int batch_mode)
{}

static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
			       int batch_mode)
{}

static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
{}

static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
				int batch_mode)
{}

static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
{}

static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
{}

#if 0
int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
					u32 threshold, int batch_mode)
{
	struct host_command cmd = {
		.host_command = FRAG_THRESHOLD,
		.host_command_sequence = 0,
		.host_command_length = 4,
		.host_command_parameters[0] = 0,
	};
	int err;

	if (!batch_mode) {
		err = ipw2100_disable_adapter(priv);
		if (err)
			return err;
	}

	if (threshold == 0)
		threshold = DEFAULT_FRAG_THRESHOLD;
	else {
		threshold = max(threshold, MIN_FRAG_THRESHOLD);
		threshold = min(threshold, MAX_FRAG_THRESHOLD);
	}

	cmd.host_command_parameters[0] = threshold;

	IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);

	err = ipw2100_hw_send_command(priv, &cmd);

	if (!batch_mode)
		ipw2100_enable_adapter(priv);

	if (!err)
		priv->frag_threshold = threshold;

	return err;
}
#endif

static int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
{}

static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
{}

static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
				       int batch_mode)
{}

static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
{}

static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
			      struct ipw2100_wpa_assoc_frame *, int)
    __attribute__ ((unused));

static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
			      struct ipw2100_wpa_assoc_frame *wpa_frame,
			      int batch_mode)
{}

struct security_info_params {} __packed;

static int ipw2100_set_security_information(struct ipw2100_priv *priv,
					    int auth_mode,
					    int security_level,
					    int unicast_using_group,
					    int batch_mode)
{}

static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
{}

static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
					    u32 interval, int batch_mode)
{}

static void ipw2100_queues_initialize(struct ipw2100_priv *priv)
{}

static void ipw2100_queues_free(struct ipw2100_priv *priv)
{}

static int ipw2100_queues_allocate(struct ipw2100_priv *priv)
{}

#define IPW_PRIVACY_CAPABLE

static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
				 int batch_mode)
{}

struct ipw2100_wep_key {};

/* Macros to ease up priting WEP keys */
#define WEP_FMT_64
#define WEP_FMT_128
#define WEP_STR_64(x)
#define WEP_STR_128(x)

/**
 * ipw2100_set_key() - Set a the wep key
 *
 * @priv: struct to work on
 * @idx: index of the key we want to set
 * @key: ptr to the key data to set
 * @len: length of the buffer at @key
 * @batch_mode: FIXME perform the operation in batch mode, not
 *              disabling the device.
 *
 * @returns 0 if OK, < 0 errno code on error.
 *
 * Fill out a command structure with the new wep key, length an
 * index and send it down the wire.
 */
static int ipw2100_set_key(struct ipw2100_priv *priv,
			   int idx, char *key, int len, int batch_mode)
{}

static int ipw2100_set_key_index(struct ipw2100_priv *priv,
				 int idx, int batch_mode)
{}

static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
{}

static void ipw2100_security_work(struct work_struct *work)
{}

static void shim__set_security(struct net_device *dev,
			       struct libipw_security *sec)
{}

static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
{}

/*************************************************************************
 *
 * EXTERNALLY CALLED METHODS
 *
 *************************************************************************/

/* This method is called by the network layer -- not to be confused with
 * ipw2100_set_mac_address() declared above called by this driver (and this
 * method as well) to talk to the firmware */
static int ipw2100_set_address(struct net_device *dev, void *p)
{}

static int ipw2100_open(struct net_device *dev)
{}

static int ipw2100_close(struct net_device *dev)
{}

/*
 * TODO:  Fix this function... its just wrong
 */
static void ipw2100_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}

static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
{}

static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
{}

static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
				    char *wpa_ie, int wpa_ie_len)
{}

static void ipw_ethtool_get_drvinfo(struct net_device *dev,
				    struct ethtool_drvinfo *info)
{}

static u32 ipw2100_ethtool_get_link(struct net_device *dev)
{}

static const struct ethtool_ops ipw2100_ethtool_ops =;

static void ipw2100_hang_check(struct work_struct *work)
{}

static void ipw2100_rf_kill(struct work_struct *work)
{}

static void ipw2100_irq_tasklet(struct tasklet_struct *t);

static const struct net_device_ops ipw2100_netdev_ops =;

/* Look into using netdev destructor to shutdown libipw? */

static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
					       void __iomem * ioaddr)
{}

static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
				const struct pci_device_id *ent)
{}

static void ipw2100_pci_remove_one(struct pci_dev *pci_dev)
{}

static int __maybe_unused ipw2100_suspend(struct device *dev_d)
{}

static int __maybe_unused ipw2100_resume(struct device *dev_d)
{}

static void ipw2100_shutdown(struct pci_dev *pci_dev)
{}

#define IPW2100_DEV_ID(x)

static const struct pci_device_id ipw2100_pci_id_table[] =;

MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);

static SIMPLE_DEV_PM_OPS(ipw2100_pm_ops, ipw2100_suspend, ipw2100_resume);

static struct pci_driver ipw2100_pci_driver =;

/*
 * Initialize the ipw2100 driver/module
 *
 * @returns 0 if ok, < 0 errno node con error.
 *
 * Note: we cannot init the /proc stuff until the PCI driver is there,
 * or we risk an unlikely race condition on someone accessing
 * uninitialized data in the PCI dev struct through /proc.
 */
static int __init ipw2100_init(void)
{}

/*
 * Cleanup ipw2100 driver registration
 */
static void __exit ipw2100_exit(void)
{}

module_init();
module_exit(ipw2100_exit);

static int ipw2100_wx_get_name(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_freq(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_freq(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_mode(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_mode(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

#define POWER_MODES

/* Values are in microsecond */
static const s32 timeout_duration[POWER_MODES] =;

static const s32 period_duration[POWER_MODES] =;

static int ipw2100_wx_get_range(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_wap(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_wap(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_essid(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_essid(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_nick(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_nick(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_rate(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_rate(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_rts(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_rts(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_txpow(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_txpow(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_frag(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_frag(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_retry(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_retry(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_scan(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_scan(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

/*
 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
 */
static int ipw2100_wx_set_encode(struct net_device *dev,
				 struct iw_request_info *info,
				 union iwreq_data *wrqu, char *key)
{}

static int ipw2100_wx_get_encode(struct net_device *dev,
				 struct iw_request_info *info,
				 union iwreq_data *wrqu, char *key)
{}

static int ipw2100_wx_set_power(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_power(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

/*
 * WE-18 WPA support
 */

/* SIOCSIWGENIE */
static int ipw2100_wx_set_genie(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

/* SIOCGIWGENIE */
static int ipw2100_wx_get_genie(struct net_device *dev,
				struct iw_request_info *info,
				union iwreq_data *wrqu, char *extra)
{}

/* SIOCSIWAUTH */
static int ipw2100_wx_set_auth(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

/* SIOCGIWAUTH */
static int ipw2100_wx_get_auth(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

/* SIOCSIWENCODEEXT */
static int ipw2100_wx_set_encodeext(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}

/* SIOCGIWENCODEEXT */
static int ipw2100_wx_get_encodeext(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}

/* SIOCSIWMLME */
static int ipw2100_wx_set_mlme(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{}

/*
 *
 * IWPRIV handlers
 *
 */
#ifdef CONFIG_IPW2100_MONITOR
static int ipw2100_wx_set_promisc(struct net_device *dev,
				  struct iw_request_info *info,
				  union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_reset(struct net_device *dev,
			    struct iw_request_info *info,
			    union iwreq_data *wrqu, char *extra)
{}

#endif

static int ipw2100_wx_set_powermode(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}

#define MAX_POWER_STRING
static int ipw2100_wx_get_powermode(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_set_preamble(struct net_device *dev,
				   struct iw_request_info *info,
				   union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_preamble(struct net_device *dev,
				   struct iw_request_info *info,
				   union iwreq_data *wrqu, char *extra)
{}

#ifdef CONFIG_IPW2100_MONITOR
static int ipw2100_wx_set_crc_check(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}

static int ipw2100_wx_get_crc_check(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{}
#endif				/* CONFIG_IPW2100_MONITOR */

static iw_handler ipw2100_wx_handlers[] =;

#define IPW2100_PRIV_SET_MONITOR
#define IPW2100_PRIV_RESET
#define IPW2100_PRIV_SET_POWER
#define IPW2100_PRIV_GET_POWER
#define IPW2100_PRIV_SET_LONGPREAMBLE
#define IPW2100_PRIV_GET_LONGPREAMBLE
#define IPW2100_PRIV_SET_CRC_CHECK
#define IPW2100_PRIV_GET_CRC_CHECK

static const struct iw_priv_args ipw2100_private_args[] =;

static iw_handler ipw2100_private_handler[] =;

/*
 * Get wireless statistics.
 * Called by /proc/net/wireless
 * Also called by SIOCGIWSTATS
 */
static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
{}

static const struct iw_handler_def ipw2100_wx_handler_def =;

static void ipw2100_wx_event_work(struct work_struct *work)
{}

#define IPW2100_FW_MAJOR_VERSION
#define IPW2100_FW_MINOR_VERSION

#define IPW2100_FW_MINOR(x)
#define IPW2100_FW_MAJOR(x)

#define IPW2100_FW_VERSION

#define IPW2100_FW_PREFIX

#define IPW2100_FW_NAME(x)

/*

BINARY FIRMWARE HEADER FORMAT

offset      length   desc
0           2        version
2           2        mode == 0:BSS,1:IBSS,2:MONITOR
4           4        fw_len
8           4        uc_len
C           fw_len   firmware data
12 + fw_len uc_len   microcode data

*/

struct ipw2100_fw_header {} __packed;

static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
{}

static int ipw2100_get_firmware(struct ipw2100_priv *priv,
				struct ipw2100_fw *fw)
{}

MODULE_FIRMWARE();
#ifdef CONFIG_IPW2100_MONITOR
MODULE_FIRMWARE();
#endif
MODULE_FIRMWARE();

static void ipw2100_release_firmware(struct ipw2100_priv *priv,
				     struct ipw2100_fw *fw)
{}

static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
				 size_t max)
{}

/*
 * On exit, the firmware will have been freed from the fw list
 */
static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
{}

struct symbol_alive_response {};

static int ipw2100_ucode_download(struct ipw2100_priv *priv,
				  struct ipw2100_fw *fw)
{}