linux/drivers/net/wireless/intel/iwlegacy/3945-mac.c

// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************
 *
 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
 *
 * Portions of this file are derived from the ipw3945 project, as well
 * as portions of the ieee80211 subsystem header files.
 *
 * Contact Information:
 *  Intel Linux Wireless <[email protected]>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>

#include <net/ieee80211_radiotap.h>
#include <net/mac80211.h>

#include <asm/div64.h>

#define DRV_NAME

#include "commands.h"
#include "common.h"
#include "3945.h"
#include "iwl-spectrum.h"

/*
 * module name, copyright, version, etc.
 */

#define DRV_DESCRIPTION

#ifdef CONFIG_IWLEGACY_DEBUG
#define VD
#else
#define VD
#endif

/*
 * add "s" to indicate spectrum measurement included.
 * we add it here to be consistent with previous releases in which
 * this was configurable.
 */
#define DRV_VERSION
#define DRV_COPYRIGHT
#define DRV_AUTHOR

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

 /* module parameters */
struct il_mod_params il3945_mod_params =;

/**
 * il3945_get_antenna_flags - Get antenna flags for RXON command
 * @il: eeprom and antenna fields are used to determine antenna flags
 *
 * il->eeprom39  is used to determine if antenna AUX/MAIN are reversed
 * il3945_mod_params.antenna specifies the antenna diversity mode:
 *
 * IL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
 * IL_ANTENNA_MAIN      - Force MAIN antenna
 * IL_ANTENNA_AUX       - Force AUX antenna
 */
__le32
il3945_get_antenna_flags(const struct il_priv *il)
{}

static int
il3945_set_ccmp_dynamic_key_info(struct il_priv *il,
				 struct ieee80211_key_conf *keyconf, u8 sta_id)
{}

static int
il3945_set_tkip_dynamic_key_info(struct il_priv *il,
				 struct ieee80211_key_conf *keyconf, u8 sta_id)
{}

static int
il3945_set_wep_dynamic_key_info(struct il_priv *il,
				struct ieee80211_key_conf *keyconf, u8 sta_id)
{}

static int
il3945_clear_sta_key_info(struct il_priv *il, u8 sta_id)
{}

static int
il3945_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
		       u8 sta_id)
{}

static int
il3945_remove_static_key(struct il_priv *il)
{}

static int
il3945_set_static_key(struct il_priv *il, struct ieee80211_key_conf *key)
{}

static void
il3945_clear_free_frames(struct il_priv *il)
{}

static struct il3945_frame *
il3945_get_free_frame(struct il_priv *il)
{}

static void
il3945_free_frame(struct il_priv *il, struct il3945_frame *frame)
{}

unsigned int
il3945_fill_beacon_frame(struct il_priv *il, struct ieee80211_hdr *hdr,
			 int left)
{}

static int
il3945_send_beacon_cmd(struct il_priv *il)
{}

static void
il3945_unset_hw_params(struct il_priv *il)
{}

static void
il3945_build_tx_cmd_hwcrypto(struct il_priv *il, struct ieee80211_tx_info *info,
			     struct il_device_cmd *cmd,
			     struct sk_buff *skb_frag, int sta_id)
{}

/*
 * handle build C_TX command notification.
 */
static void
il3945_build_tx_cmd_basic(struct il_priv *il, struct il_device_cmd *cmd,
			  struct ieee80211_tx_info *info,
			  struct ieee80211_hdr *hdr, u8 std_id)
{}

/*
 * start C_TX command process
 */
static int
il3945_tx_skb(struct il_priv *il,
	      struct ieee80211_sta *sta,
	      struct sk_buff *skb)
{}

static int
il3945_get_measurement(struct il_priv *il,
		       struct ieee80211_measurement_params *params, u8 type)
{}

static void
il3945_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb)
{}

static void
il3945_hdl_add_sta(struct il_priv *il, struct il_rx_buf *rxb)
{}

static void
il3945_hdl_beacon(struct il_priv *il, struct il_rx_buf *rxb)
{}

/* Handle notification from uCode that card's power state is changing
 * due to software, hardware, or critical temperature RFKILL */
static void
il3945_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
{}

/*
 * il3945_setup_handlers - Initialize Rx handler callbacks
 *
 * Setup the RX handlers for each of the reply types sent from the uCode
 * to the host.
 *
 * This function chains into the hardware specific files for them to setup
 * any hardware specific handlers as well.
 */
static void
il3945_setup_handlers(struct il_priv *il)
{}

/************************** RX-FUNCTIONS ****************************/
/*
 * Rx theory of operation
 *
 * The host allocates 32 DMA target addresses and passes the host address
 * to the firmware at register IL_RFDS_TBL_LOWER + N * RFD_SIZE where N is
 * 0 to 31
 *
 * Rx Queue Indexes
 * The host/firmware share two idx registers for managing the Rx buffers.
 *
 * The READ idx maps to the first position that the firmware may be writing
 * to -- the driver can read up to (but not including) this position and get
 * good data.
 * The READ idx is managed by the firmware once the card is enabled.
 *
 * The WRITE idx maps to the last position the driver has read from -- the
 * position preceding WRITE is the last slot the firmware can place a packet.
 *
 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
 * WRITE = READ.
 *
 * During initialization, the host sets up the READ queue position to the first
 * IDX position, and WRITE to the last (READ - 1 wrapped)
 *
 * When the firmware places a packet in a buffer, it will advance the READ idx
 * and fire the RX interrupt.  The driver can then query the READ idx and
 * process as many packets as possible, moving the WRITE idx forward as it
 * resets the Rx queue buffers with new memory.
 *
 * The management in the driver is as follows:
 * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
 *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
 *   to replenish the iwl->rxq->rx_free.
 * + In il3945_rx_replenish (scheduled) if 'processed' != 'read' then the
 *   iwl->rxq is replenished and the READ IDX is updated (updating the
 *   'processed' and 'read' driver idxes as well)
 * + A received packet is processed and handed to the kernel network stack,
 *   detached from the iwl->rxq.  The driver 'processed' idx is updated.
 * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
 *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
 *   IDX is not incremented and iwl->status(RX_STALLED) is set.  If there
 *   were enough free buffers and RX_STALLED is set it is cleared.
 *
 *
 * Driver sequence:
 *
 * il3945_rx_replenish()     Replenishes rx_free list from rx_used, and calls
 *                            il3945_rx_queue_restock
 * il3945_rx_queue_restock() Moves available buffers from rx_free into Rx
 *                            queue, updates firmware pointers, and updates
 *                            the WRITE idx.  If insufficient rx_free buffers
 *                            are available, schedules il3945_rx_replenish
 *
 * -- enable interrupts --
 * ISR - il3945_rx()         Detach il_rx_bufs from pool up to the
 *                            READ IDX, detaching the SKB from the pool.
 *                            Moves the packet buffer from queue to rx_used.
 *                            Calls il3945_rx_queue_restock to refill any empty
 *                            slots.
 * ...
 *
 */

/*
 * il3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
 */
static inline __le32
il3945_dma_addr2rbd_ptr(struct il_priv *il, dma_addr_t dma_addr)
{}

/*
 * il3945_rx_queue_restock - refill RX queue from pre-allocated pool
 *
 * If there are slots in the RX queue that need to be restocked,
 * and we have free pre-allocated buffers, fill the ranks as much
 * as we can, pulling from rx_free.
 *
 * This moves the 'write' idx forward to catch up with 'processed', and
 * also updates the memory address in the firmware to reference the new
 * target buffer.
 */
static void
il3945_rx_queue_restock(struct il_priv *il)
{}

/*
 * il3945_rx_replenish - Move all used packet from rx_used to rx_free
 *
 * When moving to rx_free an SKB is allocated for the slot.
 *
 * Also restock the Rx queue via il3945_rx_queue_restock.
 * This is called as a scheduled work item (except for during initialization)
 */
static void
il3945_rx_allocate(struct il_priv *il, gfp_t priority)
{}

void
il3945_rx_queue_reset(struct il_priv *il, struct il_rx_queue *rxq)
{}

void
il3945_rx_replenish(void *data)
{}

static void
il3945_rx_replenish_now(struct il_priv *il)
{}

/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
 * This free routine walks the list of POOL entries and if SKB is set to
 * non NULL it is unmapped and freed
 */
static void
il3945_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
{}

/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] =;

/* Calculates a relative dB value from a ratio of linear
 *   (i.e. not dB) signal levels.
 * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
int
il3945_calc_db_from_ratio(int sig_ratio)
{}

/*
 * il3945_rx_handle - Main entry function for receiving responses from uCode
 *
 * Uses the il->handlers callback function array to invoke
 * the appropriate handlers, including command responses,
 * frame-received notifications, and other notifications.
 */
static void
il3945_rx_handle(struct il_priv *il)
{}

/* call this function to flush any scheduled tasklet */
static inline void
il3945_synchronize_irq(struct il_priv *il)
{}

static const char *
il3945_desc_lookup(int i)
{}

#define ERROR_START_OFFSET
#define ERROR_ELEM_SIZE

void
il3945_dump_nic_error_log(struct il_priv *il)
{}

static void
il3945_irq_tasklet(struct tasklet_struct *t)
{}

static int
il3945_get_channels_for_scan(struct il_priv *il, enum nl80211_band band,
			     u8 is_active, u8 n_probes,
			     struct il3945_scan_channel *scan_ch,
			     struct ieee80211_vif *vif)
{}

static void
il3945_init_hw_rates(struct il_priv *il, struct ieee80211_rate *rates)
{}

/******************************************************************************
 *
 * uCode download functions
 *
 ******************************************************************************/

static void
il3945_dealloc_ucode_pci(struct il_priv *il)
{}

/*
 * il3945_verify_inst_full - verify runtime uCode image in card vs. host,
 *     looking at all data.
 */
static int
il3945_verify_inst_full(struct il_priv *il, __le32 * image, u32 len)
{}

/*
 * il3945_verify_inst_sparse - verify runtime uCode image in card vs. host,
 *   using sample data 100 bytes apart.  If these sample points are good,
 *   it's a pretty good bet that everything between them is good, too.
 */
static int
il3945_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len)
{}

/*
 * il3945_verify_ucode - determine which instruction image is in SRAM,
 *    and verify its contents
 */
static int
il3945_verify_ucode(struct il_priv *il)
{}

static void
il3945_nic_start(struct il_priv *il)
{}

#define IL3945_UCODE_GET(item)

static u32
il3945_ucode_get_header_size(u32 api_ver)
{}

static u8 *
il3945_ucode_get_data(const struct il_ucode_header *ucode)
{}

IL3945_UCODE_GET(inst_size);
IL3945_UCODE_GET(data_size);
IL3945_UCODE_GET(init_size);
IL3945_UCODE_GET(init_data_size);
IL3945_UCODE_GET(boot_size);

/*
 * il3945_read_ucode - Read uCode images from disk file.
 *
 * Copy into buffers for card to fetch via bus-mastering
 */
static int
il3945_read_ucode(struct il_priv *il)
{}

/*
 * il3945_set_ucode_ptrs - Set uCode address location
 *
 * Tell initialization uCode where to find runtime uCode.
 *
 * BSM registers initially contain pointers to initialization uCode.
 * We need to replace them to load runtime uCode inst and data,
 * and to save runtime data when powering down.
 */
static int
il3945_set_ucode_ptrs(struct il_priv *il)
{}

/*
 * il3945_init_alive_start - Called after N_ALIVE notification received
 *
 * Called after N_ALIVE notification received from "initialize" uCode.
 *
 * Tell "initialize" uCode to go ahead and load the runtime uCode.
 */
static void
il3945_init_alive_start(struct il_priv *il)
{}

/*
 * il3945_alive_start - called after N_ALIVE notification received
 *                   from protocol/runtime uCode (initialization uCode's
 *                   Alive gets handled by il3945_init_alive_start()).
 */
static void
il3945_alive_start(struct il_priv *il)
{}

static void il3945_cancel_deferred_work(struct il_priv *il);

static void
__il3945_down(struct il_priv *il)
{}

static void
il3945_down(struct il_priv *il)
{}

#define MAX_HW_RESTARTS

static int
il3945_alloc_bcast_station(struct il_priv *il)
{}

static int
__il3945_up(struct il_priv *il)
{}

/*****************************************************************************
 *
 * Workqueue callbacks
 *
 *****************************************************************************/

static void
il3945_bg_init_alive_start(struct work_struct *data)
{}

static void
il3945_bg_alive_start(struct work_struct *data)
{}

/*
 * 3945 cannot interrupt driver when hardware rf kill switch toggles;
 * driver must poll CSR_GP_CNTRL_REG register for change.  This register
 * *is* readable even when device has been SW_RESET into low power mode
 * (e.g. during RF KILL).
 */
static void
il3945_rfkill_poll(struct work_struct *data)
{}

int
il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
{}

void
il3945_post_scan(struct il_priv *il)
{}

static void
il3945_bg_restart(struct work_struct *data)
{}

static void
il3945_bg_rx_replenish(struct work_struct *data)
{}

void
il3945_post_associate(struct il_priv *il)
{}

/*****************************************************************************
 *
 * mac80211 entry point functions
 *
 *****************************************************************************/

#define UCODE_READY_TIMEOUT

static int
il3945_mac_start(struct ieee80211_hw *hw)
{}

static void
il3945_mac_stop(struct ieee80211_hw *hw, bool suspend)
{}

static void
il3945_mac_tx(struct ieee80211_hw *hw,
	       struct ieee80211_tx_control *control,
	       struct sk_buff *skb)
{}

void
il3945_config_ap(struct il_priv *il)
{}

static int
il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
		   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
		   struct ieee80211_key_conf *key)
{}

static int
il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		   struct ieee80211_sta *sta)
{}

static void
il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
			unsigned int *total_flags, u64 multicast)
{}

/*****************************************************************************
 *
 * sysfs attributes
 *
 *****************************************************************************/

#ifdef CONFIG_IWLEGACY_DEBUG

/*
 * The following adds a new attribute to the sysfs representation
 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/)
 * used for controlling the debug level.
 *
 * See the level definitions in iwl for details.
 *
 * The debug_level being managed using sysfs below is a per device debug
 * level that is used instead of the global debug level if it (the per
 * device debug level) is set.
 */
static ssize_t
il3945_show_debug_level(struct device *d, struct device_attribute *attr,
			char *buf)
{}

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

static DEVICE_ATTR(debug_level, 0644, il3945_show_debug_level,
		   il3945_store_debug_level);

#endif /* CONFIG_IWLEGACY_DEBUG */

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

static DEVICE_ATTR(temperature, 0444, il3945_show_temperature, NULL);

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

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

static DEVICE_ATTR(tx_power, 0644, il3945_show_tx_power, il3945_store_tx_power);

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

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

static DEVICE_ATTR(flags, 0644, il3945_show_flags, il3945_store_flags);

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

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

static DEVICE_ATTR(filter_flags, 0644, il3945_show_filter_flags,
		   il3945_store_filter_flags);

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

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

static DEVICE_ATTR(measurement, 0600, il3945_show_measurement,
		   il3945_store_measurement);

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

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

static DEVICE_ATTR(retry_rate, 0600, il3945_show_retry_rate,
		   il3945_store_retry_rate);

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

static DEVICE_ATTR(channels, 0400, il3945_show_channels, NULL);

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

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

static DEVICE_ATTR(antenna, 0644, il3945_show_antenna, il3945_store_antenna);

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

static DEVICE_ATTR(status, 0444, il3945_show_status, NULL);

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

static DEVICE_ATTR(dump_errors, 0200, NULL, il3945_dump_error_log);

/*****************************************************************************
 *
 * driver setup and tear down
 *
 *****************************************************************************/

static int
il3945_setup_deferred_work(struct il_priv *il)
{}

static void
il3945_cancel_deferred_work(struct il_priv *il)
{}

static struct attribute *il3945_sysfs_entries[] =;

static const struct attribute_group il3945_attribute_group =;

static struct ieee80211_ops il3945_mac_ops __ro_after_init =;

static int
il3945_init_drv(struct il_priv *il)
{}

#define IL3945_MAX_PROBE_REQUEST

static int
il3945_setup_mac(struct il_priv *il)
{}

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

static void
il3945_pci_remove(struct pci_dev *pdev)
{}

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/

static struct pci_driver il3945_driver =;

static int __init
il3945_init(void)
{}

static void __exit
il3945_exit(void)
{}

MODULE_FIRMWARE();

module_param_named(antenna, il3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC();
module_param_named(swcrypto, il3945_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC();
module_param_named(disable_hw_scan, il3945_mod_params.disable_hw_scan, int,
		   0444);
MODULE_PARM_DESC();
#ifdef CONFIG_IWLEGACY_DEBUG
module_param_named(debug, il_debug_level, uint, 0644);
MODULE_PARM_DESC();
#endif
module_param_named(fw_restart, il3945_mod_params.restart_fw, int, 0444);
MODULE_PARM_DESC();

module_exit(il3945_exit);
module_init();