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

// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************
 *
 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
 *
 * Contact Information:
 *  Intel Linux Wireless <[email protected]>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.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 <asm/unaligned.h>
#include <net/mac80211.h>

#include "common.h"
#include "3945.h"

/* Send led command */
static int
il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
{}

#define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)

/*
 * Parameter order:
 *   rate, prev rate, next rate, prev tgg rate, next tgg rate
 *
 * If there isn't a valid next or previous rate then INV is used which
 * maps to RATE_INVALID
 *
 */
const struct il3945_rate_info il3945_rates[RATE_COUNT_3945] =;

static inline u8
il3945_get_prev_ieee_rate(u8 rate_idx)
{}

/* 1 = enable the il3945_disable_events() function */
#define IL_EVT_DISABLE
#define IL_EVT_DISABLE_SIZE

/*
 * il3945_disable_events - Disable selected events in uCode event log
 *
 * Disable an event by writing "1"s into "disable"
 *   bitmap in SRAM.  Bit position corresponds to Event # (id/type).
 *   Default values of 0 enable uCode events to be logged.
 * Use for only special debugging.  This function is just a placeholder as-is,
 *   you'll need to provide the special bits! ...
 *   ... and set IL_EVT_DISABLE to 1. */
void
il3945_disable_events(struct il_priv *il)
{}

static int
il3945_hwrate_to_plcp_idx(u8 plcp)
{}

#ifdef CONFIG_IWLEGACY_DEBUG
#define TX_STATUS_ENTRY(x)

static const char *
il3945_get_tx_fail_reason(u32 status)
{}
#else
static inline const char *
il3945_get_tx_fail_reason(u32 status)
{
	return "";
}
#endif

/*
 * get ieee prev rate from rate scale table.
 * for A and B mode we need to overright prev
 * value
 */
int
il3945_rs_next_rate(struct il_priv *il, int rate)
{}

/*
 * il3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
 *
 * When FW advances 'R' idx, all entries between old and new 'R' idx
 * need to be reclaimed. As result, some free space forms. If there is
 * enough free space (> low mark), wake the stack that feeds us.
 */
static void
il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
{}

/*
 * il3945_hdl_tx - Handle Tx response
 */
static void
il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
{}

/*****************************************************************************
 *
 * Intel PRO/Wireless 3945ABG/BG Network Connection
 *
 *  RX handler implementations
 *
 *****************************************************************************/
#ifdef CONFIG_IWLEGACY_DEBUGFS
static void
il3945_accumulative_stats(struct il_priv *il, __le32 * stats)
{}
#endif

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

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

/******************************************************************************
 *
 * Misc. internal state and helper functions
 *
 ******************************************************************************/

/* This is necessary only for a number of stats, see the caller. */
static int
il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)
{}

#define SMALL_PACKET_SIZE

static void
il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
			       struct ieee80211_rx_status *stats)
{}

#define IL_DELAY_NEXT_SCAN_AFTER_ASSOC

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

int
il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq,
				dma_addr_t addr, u16 len, u8 reset, u8 pad)
{}

/*
 * il3945_hw_txq_free_tfd - Free one TFD, those at idx [txq->q.read_ptr]
 *
 * Does NOT advance any idxes
 */
void
il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
{}

/*
 * il3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
 *
*/
void
il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd,
			    struct ieee80211_tx_info *info,
			    struct ieee80211_hdr *hdr, int sta_id)
{}

static u8
il3945_sync_sta(struct il_priv *il, int sta_id, u16 tx_rate)
{}

static void
il3945_set_pwr_vmain(struct il_priv *il)
{}

static int
il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq)
{}

static int
il3945_tx_reset(struct il_priv *il)
{}

/*
 * il3945_txq_ctx_reset - Reset TX queue context
 *
 * Destroys all DMA structures and initialize them again
 */
static int
il3945_txq_ctx_reset(struct il_priv *il)
{}

/*
 * Start up 3945's basic functionality after it has been reset
 * (e.g. after platform boot, or shutdown via il_apm_stop())
 * NOTE:  This does not load uCode nor start the embedded processor
 */
static int
il3945_apm_init(struct il_priv *il)
{}

static void
il3945_nic_config(struct il_priv *il)
{}

int
il3945_hw_nic_init(struct il_priv *il)
{}

/*
 * il3945_hw_txq_ctx_free - Free TXQ Context
 *
 * Destroy all TX DMA queues and structures
 */
void
il3945_hw_txq_ctx_free(struct il_priv *il)
{}

void
il3945_hw_txq_ctx_stop(struct il_priv *il)
{}

/*
 * il3945_hw_reg_adjust_power_by_temp
 * return idx delta into power gain settings table
*/
static int
il3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
{}

/*
 * il3945_hw_reg_temp_out_of_range - Keep temperature in sane range
 */
static inline int
il3945_hw_reg_temp_out_of_range(int temperature)
{}

int
il3945_hw_get_temperature(struct il_priv *il)
{}

/*
 * il3945_hw_reg_txpower_get_temperature
 * get the current temperature by reading from NIC
*/
static int
il3945_hw_reg_txpower_get_temperature(struct il_priv *il)
{}

/* Adjust Txpower only if temperature variance is greater than threshold.
 *
 * Both are lower than older versions' 9 degrees */
#define IL_TEMPERATURE_LIMIT_TIMER

/*
 * il3945_is_temp_calib_needed - determines if new calibration is needed
 *
 * records new temperature in tx_mgr->temperature.
 * replaces tx_mgr->last_temperature *only* if calib needed
 *    (assumes caller will actually do the calibration!). */
static int
il3945_is_temp_calib_needed(struct il_priv *il)
{}

#define IL_MAX_GAIN_ENTRIES
#define IL_CCK_FROM_OFDM_POWER_DIFF
#define IL_CCK_FROM_OFDM_IDX_DIFF

/* radio and DSP power table, each step is 1/2 dB.
 * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */
static struct il3945_tx_power power_gain_table[2][IL_MAX_GAIN_ENTRIES] =;

static inline u8
il3945_hw_reg_fix_power_idx(int idx)
{}

/* Kick off thermal recalibration check every 60 seconds */
#define REG_RECALIB_PERIOD

/*
 * il3945_hw_reg_set_scan_power - Set Tx power for scan probe requests
 *
 * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
 * or 6 Mbit (OFDM) rates.
 */
static void
il3945_hw_reg_set_scan_power(struct il_priv *il, u32 scan_tbl_idx, s32 rate_idx,
			     const s8 *clip_pwrs,
			     struct il_channel_info *ch_info, int band_idx)
{}

/*
 * il3945_send_tx_power - fill in Tx Power command with gain settings
 *
 * Configures power settings for all rates for the current channel,
 * using values from channel info struct, and send to NIC
 */
static int
il3945_send_tx_power(struct il_priv *il)
{}

/*
 * il3945_hw_reg_set_new_power - Configures power tables at new levels
 * @ch_info: Channel to update.  Uses power_info.requested_power.
 *
 * Replace requested_power and base_power_idx ch_info fields for
 * one channel.
 *
 * Called if user or spectrum management changes power preferences.
 * Takes into account h/w and modulation limitations (clip power).
 *
 * This does *not* send anything to NIC, just sets up ch_info for one channel.
 *
 * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to
 *	 properly fill out the scan powers, and actual h/w gain settings,
 *	 and send changes to NIC
 */
static int
il3945_hw_reg_set_new_power(struct il_priv *il, struct il_channel_info *ch_info)
{}

/*
 * il3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel
 *
 * NOTE: Returned power limit may be less (but not more) than requested,
 *	 based strictly on regulatory (eeprom and spectrum mgt) limitations
 *	 (no consideration for h/w clipping limitations).
 */
static int
il3945_hw_reg_get_ch_txpower_limit(struct il_channel_info *ch_info)
{}

/*
 * il3945_hw_reg_comp_txpower_temp - Compensate for temperature
 *
 * Compensate txpower settings of *all* channels for temperature.
 * This only accounts for the difference between current temperature
 *   and the factory calibration temperatures, and bases the new settings
 *   on the channel's base_power_idx.
 *
 * If RxOn is "associated", this sends the new Txpower to NIC!
 */
static int
il3945_hw_reg_comp_txpower_temp(struct il_priv *il)
{}

int
il3945_hw_reg_set_txpower(struct il_priv *il, s8 power)
{}

static int
il3945_send_rxon_assoc(struct il_priv *il)
{}

/*
 * il3945_commit_rxon - commit staging_rxon to hardware
 *
 * The RXON command in staging_rxon is committed to the hardware and
 * the active_rxon structure is updated with the new data.  This
 * function correctly transitions out of the RXON_ASSOC_MSK state if
 * a HW tune is required based on the RXON structure changes.
 */
int
il3945_commit_rxon(struct il_priv *il)
{}

/*
 * il3945_reg_txpower_periodic -  called when time to check our temperature.
 *
 * -- reset periodic timer
 * -- see if temp has changed enough to warrant re-calibration ... if so:
 *     -- correct coeffs for temp (can reset temp timer)
 *     -- save this temp as "last",
 *     -- send new set of gain settings to NIC
 * NOTE:  This should continue working, even when we're not associated,
 *   so we can keep our internal table of scan powers current. */
void
il3945_reg_txpower_periodic(struct il_priv *il)
{}

static void
il3945_bg_reg_txpower_periodic(struct work_struct *work)
{}

/*
 * il3945_hw_reg_get_ch_grp_idx - find the channel-group idx (0-4) for channel.
 *
 * This function is used when initializing channel-info structs.
 *
 * NOTE: These channel groups do *NOT* match the bands above!
 *	 These channel groups are based on factory-tested channels;
 *	 on A-band, EEPROM's "group frequency" entries represent the top
 *	 channel in each group 1-4.  Group 5 All B/G channels are in group 0.
 */
static u16
il3945_hw_reg_get_ch_grp_idx(struct il_priv *il,
			     const struct il_channel_info *ch_info)
{}

/*
 * il3945_hw_reg_get_matched_power_idx - Interpolate to get nominal idx
 *
 * Interpolate to get nominal (i.e. at factory calibration temperature) idx
 *   into radio/DSP gain settings table for requested power.
 */
static int
il3945_hw_reg_get_matched_power_idx(struct il_priv *il, s8 requested_power,
				    s32 setting_idx, s32 *new_idx)
{}

static void
il3945_hw_reg_init_channel_groups(struct il_priv *il)
{}

/*
 * il3945_txpower_set_from_eeprom - Set channel power info based on EEPROM
 *
 * Second pass (during init) to set up il->channel_info
 *
 * Set up Tx-power settings in our channel info database for each VALID
 * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values
 * and current temperature.
 *
 * Since this is based on current temperature (at init time), these values may
 * not be valid for very long, but it gives us a starting/default point,
 * and allows us to active (i.e. using Tx) scan.
 *
 * This does *not* write values to NIC, just sets up our internal table.
 */
int
il3945_txpower_set_from_eeprom(struct il_priv *il)
{}

int
il3945_hw_rxq_stop(struct il_priv *il)
{}

int
il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq)
{}

/*
 * HCMD utils
 */
static u16
il3945_get_hcmd_size(u8 cmd_id, u16 len)
{}

static u16
il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
{}

static int
il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
{}

static int
il3945_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif,
			   bool add)
{}

/*
 * il3945_init_hw_rate_table - Initialize the hardware rate fallback table
 */
int
il3945_init_hw_rate_table(struct il_priv *il)
{}

/* Called when initializing driver */
int
il3945_hw_set_hw_params(struct il_priv *il)
{}

unsigned int
il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame,
			 u8 rate)
{}

void
il3945_hw_handler_setup(struct il_priv *il)
{}

void
il3945_hw_setup_deferred_work(struct il_priv *il)
{}

void
il3945_hw_cancel_deferred_work(struct il_priv *il)
{}

/* check contents of special bootstrap uCode SRAM */
static int
il3945_verify_bsm(struct il_priv *il)
{}

/******************************************************************************
 *
 * EEPROM related functions
 *
 ******************************************************************************/

/*
 * Clear the OWNER_MSK, to establish driver (instead of uCode running on
 * embedded controller) as EEPROM reader; each read is a series of pulses
 * to/from the EEPROM chip, not a single event, so even reads could conflict
 * if they weren't arbitrated by some ownership mechanism.  Here, the driver
 * simply claims ownership, which should be safe when this function is called
 * (i.e. before loading uCode!).
 */
static int
il3945_eeprom_acquire_semaphore(struct il_priv *il)
{}

static void
il3945_eeprom_release_semaphore(struct il_priv *il)
{}

 /*
  * il3945_load_bsm - Load bootstrap instructions
  *
  * BSM operation:
  *
  * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
  * in special SRAM that does not power down during RFKILL.  When powering back
  * up after power-saving sleeps (or during initial uCode load), the BSM loads
  * the bootstrap program into the on-board processor, and starts it.
  *
  * The bootstrap program loads (via DMA) instructions and data for a new
  * program from host DRAM locations indicated by the host driver in the
  * BSM_DRAM_* registers.  Once the new program is loaded, it starts
  * automatically.
  *
  * When initializing the NIC, the host driver points the BSM to the
  * "initialize" uCode image.  This uCode sets up some internal data, then
  * notifies host via "initialize alive" that it is complete.
  *
  * The host then replaces the BSM_DRAM_* pointer values to point to the
  * normal runtime uCode instructions and a backup uCode data cache buffer
  * (filled initially with starting data values for the on-board processor),
  * then triggers the "initialize" uCode to load and launch the runtime uCode,
  * which begins normal operation.
  *
  * When doing a power-save shutdown, runtime uCode saves data SRAM into
  * the backup data cache in DRAM before SRAM is powered down.
  *
  * When powering back up, the BSM loads the bootstrap program.  This reloads
  * the runtime uCode instructions and the backup data cache into SRAM,
  * and re-launches the runtime uCode from where it left off.
  */
static int
il3945_load_bsm(struct il_priv *il)
{}

const struct il_ops il3945_ops =;

static const struct il_cfg il3945_bg_cfg =;

static const struct il_cfg il3945_abg_cfg =;

const struct pci_device_id il3945_hw_card_ids[] =;

MODULE_DEVICE_TABLE(pci, il3945_hw_card_ids);