// 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/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/units.h> #include <net/mac80211.h> #include <linux/etherdevice.h> #include <asm/unaligned.h> #include "common.h" #include "4965.h" /* * il_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 il4965_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len) { … } /* * il4965_verify_inst_full - verify runtime uCode image in card vs. host, * looking at all data. */ static int il4965_verify_inst_full(struct il_priv *il, __le32 * image, u32 len) { … } /* * il4965_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ int il4965_verify_ucode(struct il_priv *il) { … } /****************************************************************************** * * EEPROM related functions * ******************************************************************************/ /* * The device's EEPROM semaphore prevents conflicts between driver and uCode * when accessing the EEPROM; each access 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 the semaphore. */ int il4965_eeprom_acquire_semaphore(struct il_priv *il) { … } void il4965_eeprom_release_semaphore(struct il_priv *il) { … } int il4965_eeprom_check_version(struct il_priv *il) { … } void il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac) { … } /* Send led command */ static int il4965_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd) { … } /* Set led register off */ void il4965_led_enable(struct il_priv *il) { … } static int il4965_send_tx_power(struct il_priv *il); static int il4965_hw_get_temperature(struct il_priv *il); /* Highest firmware API version supported */ #define IL4965_UCODE_API_MAX … /* Lowest firmware API version supported */ #define IL4965_UCODE_API_MIN … #define IL4965_FW_PRE … #define _IL4965_MODULE_FIRMWARE(api) … #define IL4965_MODULE_FIRMWARE(api) … /* check contents of special bootstrap uCode SRAM */ static int il4965_verify_bsm(struct il_priv *il) { … } /* * il4965_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 il4965_load_bsm(struct il_priv *il) { … } /* * il4965_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 il4965_set_ucode_ptrs(struct il_priv *il) { … } /* * il4965_init_alive_start - Called after N_ALIVE notification received * * Called after N_ALIVE notification received from "initialize" uCode. * * The 4965 "initialize" ALIVE reply contains calibration data for: * Voltage, temperature, and MIMO tx gain correction, now stored in il * (3945 does not contain this data). * * Tell "initialize" uCode to go ahead and load the runtime uCode. */ static void il4965_init_alive_start(struct il_priv *il) { … } static bool iw4965_is_ht40_channel(__le32 rxon_flags) { … } void il4965_nic_config(struct il_priv *il) { … } /* Reset differential Rx gains in NIC to prepare for chain noise calibration. * Called after every association, but this runs only once! * ... once chain noise is calibrated the first time, it's good forever. */ static void il4965_chain_noise_reset(struct il_priv *il) { … } static s32 il4965_math_div_round(s32 num, s32 denom, s32 * res) { … } /* * il4965_get_voltage_compensation - Power supply voltage comp for txpower * * Determines power supply voltage compensation for txpower calculations. * Returns number of 1/2-dB steps to subtract from gain table idx, * to compensate for difference between power supply voltage during * factory measurements, vs. current power supply voltage. * * Voltage indication is higher for lower voltage. * Lower voltage requires more gain (lower gain table idx). */ static s32 il4965_get_voltage_compensation(s32 eeprom_voltage, s32 current_voltage) { … } static s32 il4965_get_tx_atten_grp(u16 channel) { … } static u32 il4965_get_sub_band(const struct il_priv *il, u32 channel) { … } static s32 il4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) { … } /* * il4965_interpolate_chan - Interpolate factory measurements for one channel * * Interpolates factory measurements from the two sample channels within a * sub-band, to apply to channel of interest. Interpolation is proportional to * differences in channel frequencies, which is proportional to differences * in channel number. */ static int il4965_interpolate_chan(struct il_priv *il, u32 channel, struct il_eeprom_calib_ch_info *chan_info) { … } /* bit-rate-dependent table to prevent Tx distortion, in half-dB units, * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ static s32 back_off_table[] = …; /* Thermal compensation values for txpower for various frequency ranges ... * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ static struct il4965_txpower_comp_entry { … } tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = …; static s32 get_min_power_idx(s32 rate_power_idx, u32 band) { … } struct gain_entry { … }; static const struct gain_entry gain_table[2][108] = …; static int il4965_fill_txpower_tbl(struct il_priv *il, u8 band, u16 channel, u8 is_ht40, u8 ctrl_chan_high, struct il4965_tx_power_db *tx_power_tbl) { … } /* * il4965_send_tx_power - Configure the TXPOWER level user limit * * Uses the active RXON for channel, band, and characteristics (ht40, high) * The power limit is taken from il->tx_power_user_lmt. */ static int il4965_send_tx_power(struct il_priv *il) { … } static int il4965_send_rxon_assoc(struct il_priv *il) { … } static int il4965_commit_rxon(struct il_priv *il) { … } static int il4965_hw_channel_switch(struct il_priv *il, struct ieee80211_channel_switch *ch_switch) { … } /* * il4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ static void il4965_txq_update_byte_cnt_tbl(struct il_priv *il, struct il_tx_queue *txq, u16 byte_cnt) { … } /* * il4965_hw_get_temperature - return the calibrated temperature (in Kelvin) * * A return of <0 indicates bogus data in the stats */ static int il4965_hw_get_temperature(struct il_priv *il) { … } /* Adjust Txpower only if temperature variance is greater than threshold. */ #define IL_TEMPERATURE_THRESHOLD … /* * il4965_is_temp_calib_needed - determines if new calibration is needed * * If the temperature changed has changed sufficiently, then a recalibration * is needed. * * Assumes caller will replace il->last_temperature once calibration * executed. */ static int il4965_is_temp_calib_needed(struct il_priv *il) { … } void il4965_temperature_calib(struct il_priv *il) { … } static u16 il4965_get_hcmd_size(u8 cmd_id, u16 len) { … } static u16 il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) { … } static void il4965_post_scan(struct il_priv *il) { … } static void il4965_post_associate(struct il_priv *il) { … } static void il4965_config_ap(struct il_priv *il) { … } const struct il_ops il4965_ops = …; struct il_cfg il4965_cfg = …; /* Module firmware */ MODULE_FIRMWARE(…);