brintos

brintos / linux-shallow public Read only

0
0
Text · 75.1 KiB · 14d2331 Raw
2726 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.5 *6 * Contact Information:7 *  Intel Linux Wireless <ilw@linux.intel.com>8 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64979 *10 *****************************************************************************/11 12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/slab.h>15#include <linux/pci.h>16#include <linux/dma-mapping.h>17#include <linux/delay.h>18#include <linux/sched.h>19#include <linux/skbuff.h>20#include <linux/netdevice.h>21#include <linux/firmware.h>22#include <linux/etherdevice.h>23#include <linux/unaligned.h>24#include <net/mac80211.h>25 26#include "common.h"27#include "3945.h"28 29/* Send led command */30static int31il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)32{33	struct il_host_cmd cmd = {34		.id = C_LEDS,35		.len = sizeof(struct il_led_cmd),36		.data = led_cmd,37		.flags = CMD_ASYNC,38		.callback = NULL,39	};40 41	return il_send_cmd(il, &cmd);42}43 44#define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \45	[RATE_##r##M_IDX] = { RATE_##r##M_PLCP,   \46				    RATE_##r##M_IEEE,   \47				    RATE_##ip##M_IDX, \48				    RATE_##in##M_IDX, \49				    RATE_##rp##M_IDX, \50				    RATE_##rn##M_IDX, \51				    RATE_##pp##M_IDX, \52				    RATE_##np##M_IDX, \53				    RATE_##r##M_IDX_TBL, \54				    RATE_##ip##M_IDX_TBL }55 56/*57 * Parameter order:58 *   rate, prev rate, next rate, prev tgg rate, next tgg rate59 *60 * If there isn't a valid next or previous rate then INV is used which61 * maps to RATE_INVALID62 *63 */64const struct il3945_rate_info il3945_rates[RATE_COUNT_3945] = {65	IL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),	/*  1mbps */66	IL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),	/*  2mbps */67	IL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),	/*5.5mbps */68	IL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18),	/* 11mbps */69	IL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11),	/*  6mbps */70	IL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11),	/*  9mbps */71	IL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18),	/* 12mbps */72	IL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24),	/* 18mbps */73	IL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36),	/* 24mbps */74	IL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48),	/* 36mbps */75	IL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54),	/* 48mbps */76	IL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),	/* 54mbps */77};78 79static inline u880il3945_get_prev_ieee_rate(u8 rate_idx)81{82	u8 rate = il3945_rates[rate_idx].prev_ieee;83 84	if (rate == RATE_INVALID)85		rate = rate_idx;86	return rate;87}88 89/* 1 = enable the il3945_disable_events() function */90#define IL_EVT_DISABLE (0)91#define IL_EVT_DISABLE_SIZE (1532/32)92 93/*94 * il3945_disable_events - Disable selected events in uCode event log95 *96 * Disable an event by writing "1"s into "disable"97 *   bitmap in SRAM.  Bit position corresponds to Event # (id/type).98 *   Default values of 0 enable uCode events to be logged.99 * Use for only special debugging.  This function is just a placeholder as-is,100 *   you'll need to provide the special bits! ...101 *   ... and set IL_EVT_DISABLE to 1. */102void103il3945_disable_events(struct il_priv *il)104{105	int i;106	u32 base;		/* SRAM address of event log header */107	u32 disable_ptr;	/* SRAM address of event-disable bitmap array */108	u32 array_size;		/* # of u32 entries in array */109	static const u32 evt_disable[IL_EVT_DISABLE_SIZE] = {110		0x00000000,	/*   31 -    0  Event id numbers */111		0x00000000,	/*   63 -   32 */112		0x00000000,	/*   95 -   64 */113		0x00000000,	/*  127 -   96 */114		0x00000000,	/*  159 -  128 */115		0x00000000,	/*  191 -  160 */116		0x00000000,	/*  223 -  192 */117		0x00000000,	/*  255 -  224 */118		0x00000000,	/*  287 -  256 */119		0x00000000,	/*  319 -  288 */120		0x00000000,	/*  351 -  320 */121		0x00000000,	/*  383 -  352 */122		0x00000000,	/*  415 -  384 */123		0x00000000,	/*  447 -  416 */124		0x00000000,	/*  479 -  448 */125		0x00000000,	/*  511 -  480 */126		0x00000000,	/*  543 -  512 */127		0x00000000,	/*  575 -  544 */128		0x00000000,	/*  607 -  576 */129		0x00000000,	/*  639 -  608 */130		0x00000000,	/*  671 -  640 */131		0x00000000,	/*  703 -  672 */132		0x00000000,	/*  735 -  704 */133		0x00000000,	/*  767 -  736 */134		0x00000000,	/*  799 -  768 */135		0x00000000,	/*  831 -  800 */136		0x00000000,	/*  863 -  832 */137		0x00000000,	/*  895 -  864 */138		0x00000000,	/*  927 -  896 */139		0x00000000,	/*  959 -  928 */140		0x00000000,	/*  991 -  960 */141		0x00000000,	/* 1023 -  992 */142		0x00000000,	/* 1055 - 1024 */143		0x00000000,	/* 1087 - 1056 */144		0x00000000,	/* 1119 - 1088 */145		0x00000000,	/* 1151 - 1120 */146		0x00000000,	/* 1183 - 1152 */147		0x00000000,	/* 1215 - 1184 */148		0x00000000,	/* 1247 - 1216 */149		0x00000000,	/* 1279 - 1248 */150		0x00000000,	/* 1311 - 1280 */151		0x00000000,	/* 1343 - 1312 */152		0x00000000,	/* 1375 - 1344 */153		0x00000000,	/* 1407 - 1376 */154		0x00000000,	/* 1439 - 1408 */155		0x00000000,	/* 1471 - 1440 */156		0x00000000,	/* 1503 - 1472 */157	};158 159	base = le32_to_cpu(il->card_alive.log_event_table_ptr);160	if (!il3945_hw_valid_rtc_data_addr(base)) {161		IL_ERR("Invalid event log pointer 0x%08X\n", base);162		return;163	}164 165	disable_ptr = il_read_targ_mem(il, base + (4 * sizeof(u32)));166	array_size = il_read_targ_mem(il, base + (5 * sizeof(u32)));167 168	if (IL_EVT_DISABLE && array_size == IL_EVT_DISABLE_SIZE) {169		D_INFO("Disabling selected uCode log events at 0x%x\n",170		       disable_ptr);171		for (i = 0; i < IL_EVT_DISABLE_SIZE; i++)172			il_write_targ_mem(il, disable_ptr + (i * sizeof(u32)),173					  evt_disable[i]);174 175	} else {176		D_INFO("Selected uCode log events may be disabled\n");177		D_INFO("  by writing \"1\"s into disable bitmap\n");178		D_INFO("  in SRAM at 0x%x, size %d u32s\n", disable_ptr,179		       array_size);180	}181 182}183 184static int185il3945_hwrate_to_plcp_idx(u8 plcp)186{187	int idx;188 189	for (idx = 0; idx < RATE_COUNT_3945; idx++)190		if (il3945_rates[idx].plcp == plcp)191			return idx;192	return -1;193}194 195#ifdef CONFIG_IWLEGACY_DEBUG196#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x197 198static const char *199il3945_get_tx_fail_reason(u32 status)200{201	switch (status & TX_STATUS_MSK) {202	case TX_3945_STATUS_SUCCESS:203		return "SUCCESS";204		TX_STATUS_ENTRY(SHORT_LIMIT);205		TX_STATUS_ENTRY(LONG_LIMIT);206		TX_STATUS_ENTRY(FIFO_UNDERRUN);207		TX_STATUS_ENTRY(MGMNT_ABORT);208		TX_STATUS_ENTRY(NEXT_FRAG);209		TX_STATUS_ENTRY(LIFE_EXPIRE);210		TX_STATUS_ENTRY(DEST_PS);211		TX_STATUS_ENTRY(ABORTED);212		TX_STATUS_ENTRY(BT_RETRY);213		TX_STATUS_ENTRY(STA_INVALID);214		TX_STATUS_ENTRY(FRAG_DROPPED);215		TX_STATUS_ENTRY(TID_DISABLE);216		TX_STATUS_ENTRY(FRAME_FLUSHED);217		TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);218		TX_STATUS_ENTRY(TX_LOCKED);219		TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);220	}221 222	return "UNKNOWN";223}224#else225static inline const char *226il3945_get_tx_fail_reason(u32 status)227{228	return "";229}230#endif231 232/*233 * get ieee prev rate from rate scale table.234 * for A and B mode we need to overright prev235 * value236 */237int238il3945_rs_next_rate(struct il_priv *il, int rate)239{240	int next_rate = il3945_get_prev_ieee_rate(rate);241 242	switch (il->band) {243	case NL80211_BAND_5GHZ:244		if (rate == RATE_12M_IDX)245			next_rate = RATE_9M_IDX;246		else if (rate == RATE_6M_IDX)247			next_rate = RATE_6M_IDX;248		break;249	case NL80211_BAND_2GHZ:250		if (!(il->_3945.sta_supp_rates & IL_OFDM_RATES_MASK) &&251		    il_is_associated(il)) {252			if (rate == RATE_11M_IDX)253				next_rate = RATE_5M_IDX;254		}255		break;256 257	default:258		break;259	}260 261	return next_rate;262}263 264/*265 * il3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd266 *267 * When FW advances 'R' idx, all entries between old and new 'R' idx268 * need to be reclaimed. As result, some free space forms. If there is269 * enough free space (> low mark), wake the stack that feeds us.270 */271static void272il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)273{274	struct il_tx_queue *txq = &il->txq[txq_id];275	struct il_queue *q = &txq->q;276	struct sk_buff *skb;277 278	BUG_ON(txq_id == IL39_CMD_QUEUE_NUM);279 280	for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;281	     q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {282 283		skb = txq->skbs[txq->q.read_ptr];284		ieee80211_tx_status_irqsafe(il->hw, skb);285		txq->skbs[txq->q.read_ptr] = NULL;286		il->ops->txq_free_tfd(il, txq);287	}288 289	if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&290	    txq_id != IL39_CMD_QUEUE_NUM && il->mac80211_registered)291		il_wake_queue(il, txq);292}293 294/*295 * il3945_hdl_tx - Handle Tx response296 */297static void298il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)299{300	struct il_rx_pkt *pkt = rxb_addr(rxb);301	u16 sequence = le16_to_cpu(pkt->hdr.sequence);302	int txq_id = SEQ_TO_QUEUE(sequence);303	int idx = SEQ_TO_IDX(sequence);304	struct il_tx_queue *txq = &il->txq[txq_id];305	struct ieee80211_tx_info *info;306	struct il3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];307	u32 status = le32_to_cpu(tx_resp->status);308	int rate_idx;309	int fail;310 311	if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {312		IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "313		       "is out of range [0-%d] %d %d\n", txq_id, idx,314		       txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);315		return;316	}317 318	/*319	 * Firmware will not transmit frame on passive channel, if it not yet320	 * received some valid frame on that channel. When this error happen321	 * we have to wait until firmware will unblock itself i.e. when we322	 * note received beacon or other frame. We unblock queues in323	 * il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed.324	 */325	if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&326	    il->iw_mode == NL80211_IFTYPE_STATION) {327		il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);328		D_INFO("Stopped queues - RX waiting on passive channel\n");329	}330 331	txq->time_stamp = jiffies;332	info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);333	ieee80211_tx_info_clear_status(info);334 335	/* Fill the MRR chain with some info about on-chip retransmissions */336	rate_idx = il3945_hwrate_to_plcp_idx(tx_resp->rate);337	if (info->band == NL80211_BAND_5GHZ)338		rate_idx -= IL_FIRST_OFDM_RATE;339 340	fail = tx_resp->failure_frame;341 342	info->status.rates[0].idx = rate_idx;343	info->status.rates[0].count = fail + 1;	/* add final attempt */344 345	/* tx_status->rts_retry_count = tx_resp->failure_rts; */346	info->flags |=347	    ((status & TX_STATUS_MSK) ==348	     TX_STATUS_SUCCESS) ? IEEE80211_TX_STAT_ACK : 0;349 350	D_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", txq_id,351	     il3945_get_tx_fail_reason(status), status, tx_resp->rate,352	     tx_resp->failure_frame);353 354	D_TX_REPLY("Tx queue reclaim %d\n", idx);355	il3945_tx_queue_reclaim(il, txq_id, idx);356 357	if (status & TX_ABORT_REQUIRED_MSK)358		IL_ERR("TODO:  Implement Tx ABORT REQUIRED!!!\n");359}360 361/*****************************************************************************362 *363 * Intel PRO/Wireless 3945ABG/BG Network Connection364 *365 *  RX handler implementations366 *367 *****************************************************************************/368#ifdef CONFIG_IWLEGACY_DEBUGFS369static void370il3945_accumulative_stats(struct il_priv *il, __le32 * stats)371{372	int i;373	__le32 *prev_stats;374	u32 *accum_stats;375	u32 *delta, *max_delta;376 377	prev_stats = (__le32 *) &il->_3945.stats;378	accum_stats = (u32 *) &il->_3945.accum_stats;379	delta = (u32 *) &il->_3945.delta_stats;380	max_delta = (u32 *) &il->_3945.max_delta;381 382	for (i = sizeof(__le32); i < sizeof(struct il3945_notif_stats);383	     i +=384	     sizeof(__le32), stats++, prev_stats++, delta++, max_delta++,385	     accum_stats++) {386		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {387			*delta =388			    (le32_to_cpu(*stats) - le32_to_cpu(*prev_stats));389			*accum_stats += *delta;390			if (*delta > *max_delta)391				*max_delta = *delta;392		}393	}394 395	/* reset accumulative stats for "no-counter" type stats */396	il->_3945.accum_stats.general.temperature =397	    il->_3945.stats.general.temperature;398	il->_3945.accum_stats.general.ttl_timestamp =399	    il->_3945.stats.general.ttl_timestamp;400}401#endif402 403void404il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)405{406	struct il_rx_pkt *pkt = rxb_addr(rxb);407 408	D_RX("Statistics notification received (%d vs %d).\n",409	     (int)sizeof(struct il3945_notif_stats),410	     le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK);411#ifdef CONFIG_IWLEGACY_DEBUGFS412	il3945_accumulative_stats(il, (__le32 *) &pkt->u.raw);413#endif414 415	memcpy(&il->_3945.stats, pkt->u.raw, sizeof(il->_3945.stats));416}417 418void419il3945_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)420{421	struct il_rx_pkt *pkt = rxb_addr(rxb);422	__le32 *flag = (__le32 *) &pkt->u.raw;423 424	if (le32_to_cpu(*flag) & UCODE_STATS_CLEAR_MSK) {425#ifdef CONFIG_IWLEGACY_DEBUGFS426		memset(&il->_3945.accum_stats, 0,427		       sizeof(struct il3945_notif_stats));428		memset(&il->_3945.delta_stats, 0,429		       sizeof(struct il3945_notif_stats));430		memset(&il->_3945.max_delta, 0,431		       sizeof(struct il3945_notif_stats));432#endif433		D_RX("Statistics have been cleared\n");434	}435	il3945_hdl_stats(il, rxb);436}437 438/******************************************************************************439 *440 * Misc. internal state and helper functions441 *442 ******************************************************************************/443 444/* This is necessary only for a number of stats, see the caller. */445static int446il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)447{448	/* Filter incoming packets to determine if they are targeted toward449	 * this network, discarding packets coming from ourselves */450	switch (il->iw_mode) {451	case NL80211_IFTYPE_ADHOC:	/* Header: Dest. | Source    | BSSID */452		/* packets to our IBSS update information */453		return ether_addr_equal_64bits(header->addr3, il->bssid);454	case NL80211_IFTYPE_STATION:	/* Header: Dest. | AP{BSSID} | Source */455		/* packets to our IBSS update information */456		return ether_addr_equal_64bits(header->addr2, il->bssid);457	default:458		return 1;459	}460}461 462#define SMALL_PACKET_SIZE 256463 464static void465il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,466			       struct ieee80211_rx_status *stats)467{468	struct il_rx_pkt *pkt = rxb_addr(rxb);469	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt);470	struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);471	struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);472	u32 len = le16_to_cpu(rx_hdr->len);473	struct sk_buff *skb;474	__le16 fc = hdr->frame_control;475	u32 fraglen = PAGE_SIZE << il->hw_params.rx_page_order;476 477	/* We received data from the HW, so stop the watchdog */478	if (unlikely(len + IL39_RX_FRAME_SIZE > fraglen)) {479		D_DROP("Corruption detected!\n");480		return;481	}482 483	/* We only process data packets if the interface is open */484	if (unlikely(!il->is_open)) {485		D_DROP("Dropping packet while interface is not open.\n");486		return;487	}488 489	if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {490		il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);491		D_INFO("Woke queues - frame received on passive channel\n");492	}493 494	skb = dev_alloc_skb(SMALL_PACKET_SIZE);495	if (!skb) {496		IL_ERR("dev_alloc_skb failed\n");497		return;498	}499 500	if (!il3945_mod_params.sw_crypto)501		il_set_decrypted_flag(il, (struct ieee80211_hdr *)pkt,502				      le32_to_cpu(rx_end->status), stats);503 504	/* If frame is small enough to fit into skb->head, copy it505	 * and do not consume a full page506	 */507	if (len <= SMALL_PACKET_SIZE) {508		skb_put_data(skb, rx_hdr->payload, len);509	} else {510		skb_add_rx_frag(skb, 0, rxb->page,511				(void *)rx_hdr->payload - (void *)pkt, len,512				fraglen);513		il->alloc_rxb_page--;514		rxb->page = NULL;515	}516	il_update_stats(il, false, fc, len);517	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));518 519	ieee80211_rx(il->hw, skb);520}521 522#define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)523 524static void525il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)526{527	struct ieee80211_hdr *header;528	struct ieee80211_rx_status rx_status = {};529	struct il_rx_pkt *pkt = rxb_addr(rxb);530	struct il3945_rx_frame_stats_hdr *rx_stats = IL_RX_STATS(pkt);531	struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);532	struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);533	u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg);534	u16 rx_stats_noise_diff __maybe_unused =535	    le16_to_cpu(rx_stats->noise_diff);536	u8 network_packet;537 538	rx_status.flag = 0;539	rx_status.mactime = le64_to_cpu(rx_end->timestamp);540	rx_status.band =541	    (rx_hdr->542	     phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? NL80211_BAND_2GHZ :543	    NL80211_BAND_5GHZ;544	rx_status.freq =545	    ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel),546					   rx_status.band);547 548	rx_status.rate_idx = il3945_hwrate_to_plcp_idx(rx_hdr->rate);549	if (rx_status.band == NL80211_BAND_5GHZ)550		rx_status.rate_idx -= IL_FIRST_OFDM_RATE;551 552	rx_status.antenna =553	    (le16_to_cpu(rx_hdr->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) >>554	    4;555 556	/* set the preamble flag if appropriate */557	if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)558		rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;559 560	if ((unlikely(rx_stats->phy_count > 20))) {561		D_DROP("dsp size out of range [0,20]: %d\n",562		       rx_stats->phy_count);563		return;564	}565 566	if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR) ||567	    !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {568		D_RX("Bad CRC or FIFO: 0x%08X.\n", rx_end->status);569		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;570	}571 572	/* Convert 3945's rssi indicator to dBm */573	rx_status.signal = rx_stats->rssi - IL39_RSSI_OFFSET;574 575	D_STATS("Rssi %d sig_avg %d noise_diff %d\n", rx_status.signal,576		rx_stats_sig_avg, rx_stats_noise_diff);577 578	header = (struct ieee80211_hdr *)IL_RX_DATA(pkt);579 580	network_packet = il3945_is_network_packet(il, header);581 582	D_STATS("[%c] %d RSSI:%d Signal:%u, Rate:%u\n",583		network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel),584		rx_status.signal, rx_status.signal, rx_status.rate_idx);585 586	if (network_packet) {587		il->_3945.last_beacon_time =588		    le32_to_cpu(rx_end->beacon_timestamp);589		il->_3945.last_tsf = le64_to_cpu(rx_end->timestamp);590		il->_3945.last_rx_rssi = rx_status.signal;591	}592 593	il3945_pass_packet_to_mac80211(il, rxb, &rx_status);594}595 596int597il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq,598				dma_addr_t addr, u16 len, u8 reset, u8 pad)599{600	int count;601	struct il_queue *q;602	struct il3945_tfd *tfd, *tfd_tmp;603 604	q = &txq->q;605	tfd_tmp = (struct il3945_tfd *)txq->tfds;606	tfd = &tfd_tmp[q->write_ptr];607 608	if (reset)609		memset(tfd, 0, sizeof(*tfd));610 611	count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));612 613	if (count >= NUM_TFD_CHUNKS || count < 0) {614		IL_ERR("Error can not send more than %d chunks\n",615		       NUM_TFD_CHUNKS);616		return -EINVAL;617	}618 619	tfd->tbs[count].addr = cpu_to_le32(addr);620	tfd->tbs[count].len = cpu_to_le32(len);621 622	count++;623 624	tfd->control_flags =625	    cpu_to_le32(TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad));626 627	return 0;628}629 630/*631 * il3945_hw_txq_free_tfd - Free one TFD, those at idx [txq->q.read_ptr]632 *633 * Does NOT advance any idxes634 */635void636il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)637{638	struct il3945_tfd *tfd_tmp = (struct il3945_tfd *)txq->tfds;639	int idx = txq->q.read_ptr;640	struct il3945_tfd *tfd = &tfd_tmp[idx];641	struct pci_dev *dev = il->pci_dev;642	int i;643	int counter;644 645	/* sanity check */646	counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));647	if (counter > NUM_TFD_CHUNKS) {648		IL_ERR("Too many chunks: %i\n", counter);649		/* @todo issue fatal error, it is quite serious situation */650		return;651	}652 653	/* Unmap tx_cmd */654	if (counter)655		dma_unmap_single(&dev->dev,656				 dma_unmap_addr(&txq->meta[idx], mapping),657				 dma_unmap_len(&txq->meta[idx], len),658				 DMA_TO_DEVICE);659 660	/* unmap chunks if any */661 662	for (i = 1; i < counter; i++)663		dma_unmap_single(&dev->dev, le32_to_cpu(tfd->tbs[i].addr),664				 le32_to_cpu(tfd->tbs[i].len), DMA_TO_DEVICE);665 666	/* free SKB */667	if (txq->skbs) {668		struct sk_buff *skb = txq->skbs[txq->q.read_ptr];669 670		/* can be called from irqs-disabled context */671		if (skb) {672			dev_kfree_skb_any(skb);673			txq->skbs[txq->q.read_ptr] = NULL;674		}675	}676}677 678/*679 * il3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:680 *681*/682void683il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd,684			    struct ieee80211_tx_info *info,685			    struct ieee80211_hdr *hdr, int sta_id)686{687	u16 hw_value = ieee80211_get_tx_rate(il->hw, info)->hw_value;688	u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945 - 1);689	u16 rate_mask;690	int rate;691	const u8 rts_retry_limit = 7;692	u8 data_retry_limit;693	__le32 tx_flags;694	__le16 fc = hdr->frame_control;695	struct il3945_tx_cmd *tx_cmd = (struct il3945_tx_cmd *)cmd->cmd.payload;696 697	rate = il3945_rates[rate_idx].plcp;698	tx_flags = tx_cmd->tx_flags;699 700	/* We need to figure out how to get the sta->supp_rates while701	 * in this running context */702	rate_mask = RATES_MASK_3945;703 704	/* Set retry limit on DATA packets and Probe Responses */705	if (ieee80211_is_probe_resp(fc))706		data_retry_limit = 3;707	else708		data_retry_limit = IL_DEFAULT_TX_RETRY;709	tx_cmd->data_retry_limit = data_retry_limit;710	/* Set retry limit on RTS packets */711	tx_cmd->rts_retry_limit = min(data_retry_limit, rts_retry_limit);712 713	tx_cmd->rate = rate;714	tx_cmd->tx_flags = tx_flags;715 716	/* OFDM */717	tx_cmd->supp_rates[0] =718	    ((rate_mask & IL_OFDM_RATES_MASK) >> IL_FIRST_OFDM_RATE) & 0xFF;719 720	/* CCK */721	tx_cmd->supp_rates[1] = (rate_mask & 0xF);722 723	D_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "724	       "cck/ofdm mask: 0x%x/0x%x\n", sta_id, tx_cmd->rate,725	       le32_to_cpu(tx_cmd->tx_flags), tx_cmd->supp_rates[1],726	       tx_cmd->supp_rates[0]);727}728 729static u8730il3945_sync_sta(struct il_priv *il, int sta_id, u16 tx_rate)731{732	unsigned long flags_spin;733	struct il_station_entry *station;734 735	if (sta_id == IL_INVALID_STATION)736		return IL_INVALID_STATION;737 738	spin_lock_irqsave(&il->sta_lock, flags_spin);739	station = &il->stations[sta_id];740 741	station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;742	station->sta.rate_n_flags = cpu_to_le16(tx_rate);743	station->sta.mode = STA_CONTROL_MODIFY_MSK;744	il_send_add_sta(il, &station->sta, CMD_ASYNC);745	spin_unlock_irqrestore(&il->sta_lock, flags_spin);746 747	D_RATE("SCALE sync station %d to rate %d\n", sta_id, tx_rate);748	return sta_id;749}750 751static void752il3945_set_pwr_vmain(struct il_priv *il)753{754/*755 * (for documentation purposes)756 * to set power to V_AUX, do757 758		if (pci_pme_capable(il->pci_dev, PCI_D3cold)) {759			il_set_bits_mask_prph(il, APMG_PS_CTRL_REG,760					APMG_PS_CTRL_VAL_PWR_SRC_VAUX,761					~APMG_PS_CTRL_MSK_PWR_SRC);762 763			_il_poll_bit(il, CSR_GPIO_IN,764				     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,765				     CSR_GPIO_IN_BIT_AUX_POWER, 5000);766		}767 */768 769	il_set_bits_mask_prph(il, APMG_PS_CTRL_REG,770			      APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,771			      ~APMG_PS_CTRL_MSK_PWR_SRC);772 773	_il_poll_bit(il, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,774		     CSR_GPIO_IN_BIT_AUX_POWER, 5000);775}776 777static int778il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq)779{780	il_wr(il, FH39_RCSR_RBD_BASE(0), rxq->bd_dma);781	il_wr(il, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);782	il_wr(il, FH39_RCSR_WPTR(0), 0);783	il_wr(il, FH39_RCSR_CONFIG(0),784	      FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |785	      FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |786	      FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |787	      FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | (RX_QUEUE_SIZE_LOG788							       <<789							       FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE)790	      | FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | (1 <<791								 FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH)792	      | FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);793 794	/* fake read to flush all prev I/O */795	il_rd(il, FH39_RSSR_CTRL);796 797	return 0;798}799 800static int801il3945_tx_reset(struct il_priv *il)802{803	/* bypass mode */804	il_wr_prph(il, ALM_SCD_MODE_REG, 0x2);805 806	/* RA 0 is active */807	il_wr_prph(il, ALM_SCD_ARASTAT_REG, 0x01);808 809	/* all 6 fifo are active */810	il_wr_prph(il, ALM_SCD_TXFACT_REG, 0x3f);811 812	il_wr_prph(il, ALM_SCD_SBYP_MODE_1_REG, 0x010000);813	il_wr_prph(il, ALM_SCD_SBYP_MODE_2_REG, 0x030002);814	il_wr_prph(il, ALM_SCD_TXF4MF_REG, 0x000004);815	il_wr_prph(il, ALM_SCD_TXF5MF_REG, 0x000005);816 817	il_wr(il, FH39_TSSR_CBB_BASE, il->_3945.shared_phys);818 819	il_wr(il, FH39_TSSR_MSG_CONFIG,820	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |821	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |822	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |823	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |824	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |825	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |826	      FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);827 828	return 0;829}830 831/*832 * il3945_txq_ctx_reset - Reset TX queue context833 *834 * Destroys all DMA structures and initialize them again835 */836static int837il3945_txq_ctx_reset(struct il_priv *il)838{839	int rc, txq_id;840 841	il3945_hw_txq_ctx_free(il);842 843	/* allocate tx queue structure */844	rc = il_alloc_txq_mem(il);845	if (rc)846		return rc;847 848	/* Tx CMD queue */849	rc = il3945_tx_reset(il);850	if (rc)851		goto error;852 853	/* Tx queue(s) */854	for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {855		rc = il_tx_queue_init(il, txq_id);856		if (rc) {857			IL_ERR("Tx %d queue init failed\n", txq_id);858			goto error;859		}860	}861 862	return rc;863 864error:865	il3945_hw_txq_ctx_free(il);866	return rc;867}868 869/*870 * Start up 3945's basic functionality after it has been reset871 * (e.g. after platform boot, or shutdown via il_apm_stop())872 * NOTE:  This does not load uCode nor start the embedded processor873 */874static int875il3945_apm_init(struct il_priv *il)876{877	int ret = il_apm_init(il);878 879	/* Clear APMG (NIC's internal power management) interrupts */880	il_wr_prph(il, APMG_RTC_INT_MSK_REG, 0x0);881	il_wr_prph(il, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);882 883	/* Reset radio chip */884	il_set_bits_prph(il, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);885	udelay(5);886	il_clear_bits_prph(il, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);887 888	return ret;889}890 891static void892il3945_nic_config(struct il_priv *il)893{894	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;895	unsigned long flags;896	u8 rev_id = il->pci_dev->revision;897 898	spin_lock_irqsave(&il->lock, flags);899 900	/* Determine HW type */901	D_INFO("HW Revision ID = 0x%X\n", rev_id);902 903	if (rev_id & PCI_CFG_REV_ID_BIT_RTP)904		D_INFO("RTP type\n");905	else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {906		D_INFO("3945 RADIO-MB type\n");907		il_set_bit(il, CSR_HW_IF_CONFIG_REG,908			   CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);909	} else {910		D_INFO("3945 RADIO-MM type\n");911		il_set_bit(il, CSR_HW_IF_CONFIG_REG,912			   CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);913	}914 915	if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {916		D_INFO("SKU OP mode is mrc\n");917		il_set_bit(il, CSR_HW_IF_CONFIG_REG,918			   CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);919	} else920		D_INFO("SKU OP mode is basic\n");921 922	if ((eeprom->board_revision & 0xF0) == 0xD0) {923		D_INFO("3945ABG revision is 0x%X\n", eeprom->board_revision);924		il_set_bit(il, CSR_HW_IF_CONFIG_REG,925			   CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);926	} else {927		D_INFO("3945ABG revision is 0x%X\n", eeprom->board_revision);928		il_clear_bit(il, CSR_HW_IF_CONFIG_REG,929			     CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);930	}931 932	if (eeprom->almgor_m_version <= 1) {933		il_set_bit(il, CSR_HW_IF_CONFIG_REG,934			   CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);935		D_INFO("Card M type A version is 0x%X\n",936		       eeprom->almgor_m_version);937	} else {938		D_INFO("Card M type B version is 0x%X\n",939		       eeprom->almgor_m_version);940		il_set_bit(il, CSR_HW_IF_CONFIG_REG,941			   CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);942	}943	spin_unlock_irqrestore(&il->lock, flags);944 945	if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)946		D_RF_KILL("SW RF KILL supported in EEPROM.\n");947 948	if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)949		D_RF_KILL("HW RF KILL supported in EEPROM.\n");950}951 952int953il3945_hw_nic_init(struct il_priv *il)954{955	int rc;956	unsigned long flags;957	struct il_rx_queue *rxq = &il->rxq;958 959	spin_lock_irqsave(&il->lock, flags);960	il3945_apm_init(il);961	spin_unlock_irqrestore(&il->lock, flags);962 963	il3945_set_pwr_vmain(il);964	il3945_nic_config(il);965 966	/* Allocate the RX queue, or reset if it is already allocated */967	if (!rxq->bd) {968		rc = il_rx_queue_alloc(il);969		if (rc) {970			IL_ERR("Unable to initialize Rx queue\n");971			return -ENOMEM;972		}973	} else974		il3945_rx_queue_reset(il, rxq);975 976	il3945_rx_replenish(il);977 978	il3945_rx_init(il, rxq);979 980	/* Look at using this instead:981	   rxq->need_update = 1;982	   il_rx_queue_update_write_ptr(il, rxq);983	 */984 985	il_wr(il, FH39_RCSR_WPTR(0), rxq->write & ~7);986 987	rc = il3945_txq_ctx_reset(il);988	if (rc)989		return rc;990 991	set_bit(S_INIT, &il->status);992 993	return 0;994}995 996/*997 * il3945_hw_txq_ctx_free - Free TXQ Context998 *999 * Destroy all TX DMA queues and structures1000 */1001void1002il3945_hw_txq_ctx_free(struct il_priv *il)1003{1004	int txq_id;1005 1006	/* Tx queues */1007	if (il->txq) {1008		for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)1009			if (txq_id == IL39_CMD_QUEUE_NUM)1010				il_cmd_queue_free(il);1011			else1012				il_tx_queue_free(il, txq_id);1013	}1014 1015	/* free tx queue structure */1016	il_free_txq_mem(il);1017}1018 1019void1020il3945_hw_txq_ctx_stop(struct il_priv *il)1021{1022	int txq_id;1023 1024	/* stop SCD */1025	_il_wr_prph(il, ALM_SCD_MODE_REG, 0);1026	_il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);1027 1028	/* reset TFD queues */1029	for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {1030		_il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);1031		_il_poll_bit(il, FH39_TSSR_TX_STATUS,1032			     FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),1033			     FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),1034			     1000);1035	}1036}1037 1038/*1039 * il3945_hw_reg_adjust_power_by_temp1040 * return idx delta into power gain settings table1041*/1042static int1043il3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)1044{1045	return (new_reading - old_reading) * (-11) / 100;1046}1047 1048/*1049 * il3945_hw_reg_temp_out_of_range - Keep temperature in sane range1050 */1051static inline int1052il3945_hw_reg_temp_out_of_range(int temperature)1053{1054	return (temperature < -260 || temperature > 25) ? 1 : 0;1055}1056 1057int1058il3945_hw_get_temperature(struct il_priv *il)1059{1060	return _il_rd(il, CSR_UCODE_DRV_GP2);1061}1062 1063/*1064 * il3945_hw_reg_txpower_get_temperature1065 * get the current temperature by reading from NIC1066*/1067static int1068il3945_hw_reg_txpower_get_temperature(struct il_priv *il)1069{1070	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;1071	int temperature;1072 1073	temperature = il3945_hw_get_temperature(il);1074 1075	/* driver's okay range is -260 to +25.1076	 *   human readable okay range is 0 to +285 */1077	D_INFO("Temperature: %d\n", temperature + IL_TEMP_CONVERT);1078 1079	/* handle insane temp reading */1080	if (il3945_hw_reg_temp_out_of_range(temperature)) {1081		IL_ERR("Error bad temperature value  %d\n", temperature);1082 1083		/* if really really hot(?),1084		 *   substitute the 3rd band/group's temp measured at factory */1085		if (il->last_temperature > 100)1086			temperature = eeprom->groups[2].temperature;1087		else		/* else use most recent "sane" value from driver */1088			temperature = il->last_temperature;1089	}1090 1091	return temperature;	/* raw, not "human readable" */1092}1093 1094/* Adjust Txpower only if temperature variance is greater than threshold.1095 *1096 * Both are lower than older versions' 9 degrees */1097#define IL_TEMPERATURE_LIMIT_TIMER   61098 1099/*1100 * il3945_is_temp_calib_needed - determines if new calibration is needed1101 *1102 * records new temperature in tx_mgr->temperature.1103 * replaces tx_mgr->last_temperature *only* if calib needed1104 *    (assumes caller will actually do the calibration!). */1105static int1106il3945_is_temp_calib_needed(struct il_priv *il)1107{1108	int temp_diff;1109 1110	il->temperature = il3945_hw_reg_txpower_get_temperature(il);1111	temp_diff = il->temperature - il->last_temperature;1112 1113	/* get absolute value */1114	if (temp_diff < 0) {1115		D_POWER("Getting cooler, delta %d,\n", temp_diff);1116		temp_diff = -temp_diff;1117	} else if (temp_diff == 0)1118		D_POWER("Same temp,\n");1119	else1120		D_POWER("Getting warmer, delta %d,\n", temp_diff);1121 1122	/* if we don't need calibration, *don't* update last_temperature */1123	if (temp_diff < IL_TEMPERATURE_LIMIT_TIMER) {1124		D_POWER("Timed thermal calib not needed\n");1125		return 0;1126	}1127 1128	D_POWER("Timed thermal calib needed\n");1129 1130	/* assume that caller will actually do calib ...1131	 *   update the "last temperature" value */1132	il->last_temperature = il->temperature;1133	return 1;1134}1135 1136#define IL_MAX_GAIN_ENTRIES 781137#define IL_CCK_FROM_OFDM_POWER_DIFF  -51138#define IL_CCK_FROM_OFDM_IDX_DIFF (10)1139 1140/* radio and DSP power table, each step is 1/2 dB.1141 * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */1142static struct il3945_tx_power power_gain_table[2][IL_MAX_GAIN_ENTRIES] = {1143	{1144	 {251, 127},		/* 2.4 GHz, highest power */1145	 {251, 127},1146	 {251, 127},1147	 {251, 127},1148	 {251, 125},1149	 {251, 110},1150	 {251, 105},1151	 {251, 98},1152	 {187, 125},1153	 {187, 115},1154	 {187, 108},1155	 {187, 99},1156	 {243, 119},1157	 {243, 111},1158	 {243, 105},1159	 {243, 97},1160	 {243, 92},1161	 {211, 106},1162	 {211, 100},1163	 {179, 120},1164	 {179, 113},1165	 {179, 107},1166	 {147, 125},1167	 {147, 119},1168	 {147, 112},1169	 {147, 106},1170	 {147, 101},1171	 {147, 97},1172	 {147, 91},1173	 {115, 107},1174	 {235, 121},1175	 {235, 115},1176	 {235, 109},1177	 {203, 127},1178	 {203, 121},1179	 {203, 115},1180	 {203, 108},1181	 {203, 102},1182	 {203, 96},1183	 {203, 92},1184	 {171, 110},1185	 {171, 104},1186	 {171, 98},1187	 {139, 116},1188	 {227, 125},1189	 {227, 119},1190	 {227, 113},1191	 {227, 107},1192	 {227, 101},1193	 {227, 96},1194	 {195, 113},1195	 {195, 106},1196	 {195, 102},1197	 {195, 95},1198	 {163, 113},1199	 {163, 106},1200	 {163, 102},1201	 {163, 95},1202	 {131, 113},1203	 {131, 106},1204	 {131, 102},1205	 {131, 95},1206	 {99, 113},1207	 {99, 106},1208	 {99, 102},1209	 {99, 95},1210	 {67, 113},1211	 {67, 106},1212	 {67, 102},1213	 {67, 95},1214	 {35, 113},1215	 {35, 106},1216	 {35, 102},1217	 {35, 95},1218	 {3, 113},1219	 {3, 106},1220	 {3, 102},1221	 {3, 95}		/* 2.4 GHz, lowest power */1222	},1223	{1224	 {251, 127},		/* 5.x GHz, highest power */1225	 {251, 120},1226	 {251, 114},1227	 {219, 119},1228	 {219, 101},1229	 {187, 113},1230	 {187, 102},1231	 {155, 114},1232	 {155, 103},1233	 {123, 117},1234	 {123, 107},1235	 {123, 99},1236	 {123, 92},1237	 {91, 108},1238	 {59, 125},1239	 {59, 118},1240	 {59, 109},1241	 {59, 102},1242	 {59, 96},1243	 {59, 90},1244	 {27, 104},1245	 {27, 98},1246	 {27, 92},1247	 {115, 118},1248	 {115, 111},1249	 {115, 104},1250	 {83, 126},1251	 {83, 121},1252	 {83, 113},1253	 {83, 105},1254	 {83, 99},1255	 {51, 118},1256	 {51, 111},1257	 {51, 104},1258	 {51, 98},1259	 {19, 116},1260	 {19, 109},1261	 {19, 102},1262	 {19, 98},1263	 {19, 93},1264	 {171, 113},1265	 {171, 107},1266	 {171, 99},1267	 {139, 120},1268	 {139, 113},1269	 {139, 107},1270	 {139, 99},1271	 {107, 120},1272	 {107, 113},1273	 {107, 107},1274	 {107, 99},1275	 {75, 120},1276	 {75, 113},1277	 {75, 107},1278	 {75, 99},1279	 {43, 120},1280	 {43, 113},1281	 {43, 107},1282	 {43, 99},1283	 {11, 120},1284	 {11, 113},1285	 {11, 107},1286	 {11, 99},1287	 {131, 107},1288	 {131, 99},1289	 {99, 120},1290	 {99, 113},1291	 {99, 107},1292	 {99, 99},1293	 {67, 120},1294	 {67, 113},1295	 {67, 107},1296	 {67, 99},1297	 {35, 120},1298	 {35, 113},1299	 {35, 107},1300	 {35, 99},1301	 {3, 120}		/* 5.x GHz, lowest power */1302	}1303};1304 1305static inline u81306il3945_hw_reg_fix_power_idx(int idx)1307{1308	if (idx < 0)1309		return 0;1310	if (idx >= IL_MAX_GAIN_ENTRIES)1311		return IL_MAX_GAIN_ENTRIES - 1;1312	return (u8) idx;1313}1314 1315/* Kick off thermal recalibration check every 60 seconds */1316#define REG_RECALIB_PERIOD (60)1317 1318/*1319 * il3945_hw_reg_set_scan_power - Set Tx power for scan probe requests1320 *1321 * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)1322 * or 6 Mbit (OFDM) rates.1323 */1324static void1325il3945_hw_reg_set_scan_power(struct il_priv *il, u32 scan_tbl_idx, s32 rate_idx,1326			     const s8 *clip_pwrs,1327			     struct il_channel_info *ch_info, int band_idx)1328{1329	struct il3945_scan_power_info *scan_power_info;1330	s8 power;1331	u8 power_idx;1332 1333	scan_power_info = &ch_info->scan_pwr_info[scan_tbl_idx];1334 1335	/* use this channel group's 6Mbit clipping/saturation pwr,1336	 *   but cap at regulatory scan power restriction (set during init1337	 *   based on eeprom channel data) for this channel.  */1338	power = min(ch_info->scan_power, clip_pwrs[RATE_6M_IDX_TBL]);1339 1340	power = min(power, il->tx_power_user_lmt);1341	scan_power_info->requested_power = power;1342 1343	/* find difference between new scan *power* and current "normal"1344	 *   Tx *power* for 6Mb.  Use this difference (x2) to adjust the1345	 *   current "normal" temperature-compensated Tx power *idx* for1346	 *   this rate (1Mb or 6Mb) to yield new temp-compensated scan power1347	 *   *idx*. */1348	power_idx =1349	    ch_info->power_info[rate_idx].power_table_idx - (power -1350							     ch_info->1351							     power_info1352							     [RATE_6M_IDX_TBL].1353							     requested_power) *1354	    2;1355 1356	/* store reference idx that we use when adjusting *all* scan1357	 *   powers.  So we can accommodate user (all channel) or spectrum1358	 *   management (single channel) power changes "between" temperature1359	 *   feedback compensation procedures.1360	 * don't force fit this reference idx into gain table; it may be a1361	 *   negative number.  This will help avoid errors when we're at1362	 *   the lower bounds (highest gains, for warmest temperatures)1363	 *   of the table. */1364 1365	/* don't exceed table bounds for "real" setting */1366	power_idx = il3945_hw_reg_fix_power_idx(power_idx);1367 1368	scan_power_info->power_table_idx = power_idx;1369	scan_power_info->tpc.tx_gain =1370	    power_gain_table[band_idx][power_idx].tx_gain;1371	scan_power_info->tpc.dsp_atten =1372	    power_gain_table[band_idx][power_idx].dsp_atten;1373}1374 1375/*1376 * il3945_send_tx_power - fill in Tx Power command with gain settings1377 *1378 * Configures power settings for all rates for the current channel,1379 * using values from channel info struct, and send to NIC1380 */1381static int1382il3945_send_tx_power(struct il_priv *il)1383{1384	int rate_idx, i;1385	const struct il_channel_info *ch_info = NULL;1386	struct il3945_txpowertable_cmd txpower = {1387		.channel = il->active.channel,1388	};1389	u16 chan;1390 1391	if (WARN_ONCE1392	    (test_bit(S_SCAN_HW, &il->status),1393	     "TX Power requested while scanning!\n"))1394		return -EAGAIN;1395 1396	chan = le16_to_cpu(il->active.channel);1397 1398	txpower.band = (il->band == NL80211_BAND_5GHZ) ? 0 : 1;1399	ch_info = il_get_channel_info(il, il->band, chan);1400	if (!ch_info) {1401		IL_ERR("Failed to get channel info for channel %d [%d]\n", chan,1402		       il->band);1403		return -EINVAL;1404	}1405 1406	if (!il_is_channel_valid(ch_info)) {1407		D_POWER("Not calling TX_PWR_TBL_CMD on " "non-Tx channel.\n");1408		return 0;1409	}1410 1411	/* fill cmd with power settings for all rates for current channel */1412	/* Fill OFDM rate */1413	for (rate_idx = IL_FIRST_OFDM_RATE, i = 0;1414	     rate_idx <= IL39_LAST_OFDM_RATE; rate_idx++, i++) {1415 1416		txpower.power[i].tpc = ch_info->power_info[i].tpc;1417		txpower.power[i].rate = il3945_rates[rate_idx].plcp;1418 1419		D_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",1420			le16_to_cpu(txpower.channel), txpower.band,1421			txpower.power[i].tpc.tx_gain,1422			txpower.power[i].tpc.dsp_atten, txpower.power[i].rate);1423	}1424	/* Fill CCK rates */1425	for (rate_idx = IL_FIRST_CCK_RATE; rate_idx <= IL_LAST_CCK_RATE;1426	     rate_idx++, i++) {1427		txpower.power[i].tpc = ch_info->power_info[i].tpc;1428		txpower.power[i].rate = il3945_rates[rate_idx].plcp;1429 1430		D_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",1431			le16_to_cpu(txpower.channel), txpower.band,1432			txpower.power[i].tpc.tx_gain,1433			txpower.power[i].tpc.dsp_atten, txpower.power[i].rate);1434	}1435 1436	return il_send_cmd_pdu(il, C_TX_PWR_TBL,1437			       sizeof(struct il3945_txpowertable_cmd),1438			       &txpower);1439 1440}1441 1442/*1443 * il3945_hw_reg_set_new_power - Configures power tables at new levels1444 * @ch_info: Channel to update.  Uses power_info.requested_power.1445 *1446 * Replace requested_power and base_power_idx ch_info fields for1447 * one channel.1448 *1449 * Called if user or spectrum management changes power preferences.1450 * Takes into account h/w and modulation limitations (clip power).1451 *1452 * This does *not* send anything to NIC, just sets up ch_info for one channel.1453 *1454 * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to1455 *	 properly fill out the scan powers, and actual h/w gain settings,1456 *	 and send changes to NIC1457 */1458static int1459il3945_hw_reg_set_new_power(struct il_priv *il, struct il_channel_info *ch_info)1460{1461	struct il3945_channel_power_info *power_info;1462	int power_changed = 0;1463	int i;1464	const s8 *clip_pwrs;1465	int power;1466 1467	/* Get this chnlgrp's rate-to-max/clip-powers table */1468	clip_pwrs = il->_3945.clip_groups[ch_info->group_idx].clip_powers;1469 1470	/* Get this channel's rate-to-current-power settings table */1471	power_info = ch_info->power_info;1472 1473	/* update OFDM Txpower settings */1474	for (i = RATE_6M_IDX_TBL; i <= RATE_54M_IDX_TBL; i++, ++power_info) {1475		int delta_idx;1476 1477		/* limit new power to be no more than h/w capability */1478		power = min(ch_info->curr_txpow, clip_pwrs[i]);1479		if (power == power_info->requested_power)1480			continue;1481 1482		/* find difference between old and new requested powers,1483		 *    update base (non-temp-compensated) power idx */1484		delta_idx = (power - power_info->requested_power) * 2;1485		power_info->base_power_idx -= delta_idx;1486 1487		/* save new requested power value */1488		power_info->requested_power = power;1489 1490		power_changed = 1;1491	}1492 1493	/* update CCK Txpower settings, based on OFDM 12M setting ...1494	 *    ... all CCK power settings for a given channel are the *same*. */1495	if (power_changed) {1496		power =1497		    ch_info->power_info[RATE_12M_IDX_TBL].requested_power +1498		    IL_CCK_FROM_OFDM_POWER_DIFF;1499 1500		/* do all CCK rates' il3945_channel_power_info structures */1501		for (i = RATE_1M_IDX_TBL; i <= RATE_11M_IDX_TBL; i++) {1502			power_info->requested_power = power;1503			power_info->base_power_idx =1504			    ch_info->power_info[RATE_12M_IDX_TBL].1505			    base_power_idx + IL_CCK_FROM_OFDM_IDX_DIFF;1506			++power_info;1507		}1508	}1509 1510	return 0;1511}1512 1513/*1514 * il3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel1515 *1516 * NOTE: Returned power limit may be less (but not more) than requested,1517 *	 based strictly on regulatory (eeprom and spectrum mgt) limitations1518 *	 (no consideration for h/w clipping limitations).1519 */1520static int1521il3945_hw_reg_get_ch_txpower_limit(struct il_channel_info *ch_info)1522{1523	s8 max_power;1524 1525#if 01526	/* if we're using TGd limits, use lower of TGd or EEPROM */1527	if (ch_info->tgd_data.max_power != 0)1528		max_power =1529		    min(ch_info->tgd_data.max_power,1530			ch_info->eeprom.max_power_avg);1531 1532	/* else just use EEPROM limits */1533	else1534#endif1535		max_power = ch_info->eeprom.max_power_avg;1536 1537	return min(max_power, ch_info->max_power_avg);1538}1539 1540/*1541 * il3945_hw_reg_comp_txpower_temp - Compensate for temperature1542 *1543 * Compensate txpower settings of *all* channels for temperature.1544 * This only accounts for the difference between current temperature1545 *   and the factory calibration temperatures, and bases the new settings1546 *   on the channel's base_power_idx.1547 *1548 * If RxOn is "associated", this sends the new Txpower to NIC!1549 */1550static int1551il3945_hw_reg_comp_txpower_temp(struct il_priv *il)1552{1553	struct il_channel_info *ch_info = NULL;1554	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;1555	int delta_idx;1556	const s8 *clip_pwrs;	/* array of h/w max power levels for each rate */1557	u8 a_band;1558	u8 rate_idx;1559	u8 scan_tbl_idx;1560	u8 i;1561	int ref_temp;1562	int temperature = il->temperature;1563 1564	if (il->disable_tx_power_cal || test_bit(S_SCANNING, &il->status)) {1565		/* do not perform tx power calibration */1566		return 0;1567	}1568	/* set up new Tx power info for each and every channel, 2.4 and 5.x */1569	for (i = 0; i < il->channel_count; i++) {1570		ch_info = &il->channel_info[i];1571		a_band = il_is_channel_a_band(ch_info);1572 1573		/* Get this chnlgrp's factory calibration temperature */1574		ref_temp = (s16) eeprom->groups[ch_info->group_idx].temperature;1575 1576		/* get power idx adjustment based on current and factory1577		 * temps */1578		delta_idx =1579		    il3945_hw_reg_adjust_power_by_temp(temperature, ref_temp);1580 1581		/* set tx power value for all rates, OFDM and CCK */1582		for (rate_idx = 0; rate_idx < RATE_COUNT_3945; rate_idx++) {1583			int power_idx =1584			    ch_info->power_info[rate_idx].base_power_idx;1585 1586			/* temperature compensate */1587			power_idx += delta_idx;1588 1589			/* stay within table range */1590			power_idx = il3945_hw_reg_fix_power_idx(power_idx);1591			ch_info->power_info[rate_idx].power_table_idx =1592			    (u8) power_idx;1593			ch_info->power_info[rate_idx].tpc =1594			    power_gain_table[a_band][power_idx];1595		}1596 1597		/* Get this chnlgrp's rate-to-max/clip-powers table */1598		clip_pwrs =1599		    il->_3945.clip_groups[ch_info->group_idx].clip_powers;1600 1601		/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */1602		for (scan_tbl_idx = 0; scan_tbl_idx < IL_NUM_SCAN_RATES;1603		     scan_tbl_idx++) {1604			s32 actual_idx =1605			    (scan_tbl_idx ==1606			     0) ? RATE_1M_IDX_TBL : RATE_6M_IDX_TBL;1607			il3945_hw_reg_set_scan_power(il, scan_tbl_idx,1608						     actual_idx, clip_pwrs,1609						     ch_info, a_band);1610		}1611	}1612 1613	/* send Txpower command for current channel to ucode */1614	return il->ops->send_tx_power(il);1615}1616 1617int1618il3945_hw_reg_set_txpower(struct il_priv *il, s8 power)1619{1620	struct il_channel_info *ch_info;1621	s8 max_power;1622	u8 i;1623 1624	if (il->tx_power_user_lmt == power) {1625		D_POWER("Requested Tx power same as current " "limit: %ddBm.\n",1626			power);1627		return 0;1628	}1629 1630	D_POWER("Setting upper limit clamp to %ddBm.\n", power);1631	il->tx_power_user_lmt = power;1632 1633	/* set up new Tx powers for each and every channel, 2.4 and 5.x */1634 1635	for (i = 0; i < il->channel_count; i++) {1636		ch_info = &il->channel_info[i];1637 1638		/* find minimum power of all user and regulatory constraints1639		 *    (does not consider h/w clipping limitations) */1640		max_power = il3945_hw_reg_get_ch_txpower_limit(ch_info);1641		max_power = min(power, max_power);1642		if (max_power != ch_info->curr_txpow) {1643			ch_info->curr_txpow = max_power;1644 1645			/* this considers the h/w clipping limitations */1646			il3945_hw_reg_set_new_power(il, ch_info);1647		}1648	}1649 1650	/* update txpower settings for all channels,1651	 *   send to NIC if associated. */1652	il3945_is_temp_calib_needed(il);1653	il3945_hw_reg_comp_txpower_temp(il);1654 1655	return 0;1656}1657 1658static int1659il3945_send_rxon_assoc(struct il_priv *il)1660{1661	int rc = 0;1662	struct il_rx_pkt *pkt;1663	struct il3945_rxon_assoc_cmd rxon_assoc;1664	struct il_host_cmd cmd = {1665		.id = C_RXON_ASSOC,1666		.len = sizeof(rxon_assoc),1667		.flags = CMD_WANT_SKB,1668		.data = &rxon_assoc,1669	};1670	const struct il_rxon_cmd *rxon1 = &il->staging;1671	const struct il_rxon_cmd *rxon2 = &il->active;1672 1673	if (rxon1->flags == rxon2->flags &&1674	    rxon1->filter_flags == rxon2->filter_flags &&1675	    rxon1->cck_basic_rates == rxon2->cck_basic_rates &&1676	    rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates) {1677		D_INFO("Using current RXON_ASSOC.  Not resending.\n");1678		return 0;1679	}1680 1681	rxon_assoc.flags = il->staging.flags;1682	rxon_assoc.filter_flags = il->staging.filter_flags;1683	rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;1684	rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;1685	rxon_assoc.reserved = 0;1686 1687	rc = il_send_cmd_sync(il, &cmd);1688	if (rc)1689		return rc;1690 1691	pkt = (struct il_rx_pkt *)cmd.reply_page;1692	if (pkt->hdr.flags & IL_CMD_FAILED_MSK) {1693		IL_ERR("Bad return from C_RXON_ASSOC command\n");1694		rc = -EIO;1695	}1696 1697	il_free_pages(il, cmd.reply_page);1698 1699	return rc;1700}1701 1702/*1703 * il3945_commit_rxon - commit staging_rxon to hardware1704 *1705 * The RXON command in staging_rxon is committed to the hardware and1706 * the active_rxon structure is updated with the new data.  This1707 * function correctly transitions out of the RXON_ASSOC_MSK state if1708 * a HW tune is required based on the RXON structure changes.1709 */1710int1711il3945_commit_rxon(struct il_priv *il)1712{1713	/* cast away the const for active_rxon in this function */1714	struct il3945_rxon_cmd *active_rxon = (void *)&il->active;1715	struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging;1716	int rc = 0;1717	bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);1718 1719	if (test_bit(S_EXIT_PENDING, &il->status))1720		return -EINVAL;1721 1722	if (!il_is_alive(il))1723		return -1;1724 1725	/* always get timestamp with Rx frame */1726	staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;1727 1728	/* select antenna */1729	staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);1730	staging_rxon->flags |= il3945_get_antenna_flags(il);1731 1732	rc = il_check_rxon_cmd(il);1733	if (rc) {1734		IL_ERR("Invalid RXON configuration.  Not committing.\n");1735		return -EINVAL;1736	}1737 1738	/* If we don't need to send a full RXON, we can use1739	 * il3945_rxon_assoc_cmd which is used to reconfigure filter1740	 * and other flags for the current radio configuration. */1741	if (!il_full_rxon_required(il)) {1742		rc = il_send_rxon_assoc(il);1743		if (rc) {1744			IL_ERR("Error setting RXON_ASSOC "1745			       "configuration (%d).\n", rc);1746			return rc;1747		}1748 1749		memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));1750		/*1751		 * We do not commit tx power settings while channel changing,1752		 * do it now if tx power changed.1753		 */1754		il_set_tx_power(il, il->tx_power_next, false);1755		return 0;1756	}1757 1758	/* If we are currently associated and the new config requires1759	 * an RXON_ASSOC and the new config wants the associated mask enabled,1760	 * we must clear the associated from the active configuration1761	 * before we apply the new config */1762	if (il_is_associated(il) && new_assoc) {1763		D_INFO("Toggling associated bit on current RXON\n");1764		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;1765 1766		/*1767		 * reserved4 and 5 could have been filled by the iwlcore code.1768		 * Let's clear them before pushing to the 3945.1769		 */1770		active_rxon->reserved4 = 0;1771		active_rxon->reserved5 = 0;1772		rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),1773				     &il->active);1774 1775		/* If the mask clearing failed then we set1776		 * active_rxon back to what it was previously */1777		if (rc) {1778			active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;1779			IL_ERR("Error clearing ASSOC_MSK on current "1780			       "configuration (%d).\n", rc);1781			return rc;1782		}1783		il_clear_ucode_stations(il);1784		il_restore_stations(il);1785	}1786 1787	D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"1788	       "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"),1789	       le16_to_cpu(staging_rxon->channel), staging_rxon->bssid_addr);1790 1791	/*1792	 * reserved4 and 5 could have been filled by the iwlcore code.1793	 * Let's clear them before pushing to the 3945.1794	 */1795	staging_rxon->reserved4 = 0;1796	staging_rxon->reserved5 = 0;1797 1798	il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto);1799 1800	/* Apply the new configuration */1801	rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),1802			     staging_rxon);1803	if (rc) {1804		IL_ERR("Error setting new configuration (%d).\n", rc);1805		return rc;1806	}1807 1808	memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));1809 1810	if (!new_assoc) {1811		il_clear_ucode_stations(il);1812		il_restore_stations(il);1813	}1814 1815	/* If we issue a new RXON command which required a tune then we must1816	 * send a new TXPOWER command or we won't be able to Tx any frames */1817	rc = il_set_tx_power(il, il->tx_power_next, true);1818	if (rc) {1819		IL_ERR("Error setting Tx power (%d).\n", rc);1820		return rc;1821	}1822 1823	/* Init the hardware's rate fallback order based on the band */1824	rc = il3945_init_hw_rate_table(il);1825	if (rc) {1826		IL_ERR("Error setting HW rate table: %02X\n", rc);1827		return -EIO;1828	}1829 1830	return 0;1831}1832 1833/*1834 * il3945_reg_txpower_periodic -  called when time to check our temperature.1835 *1836 * -- reset periodic timer1837 * -- see if temp has changed enough to warrant re-calibration ... if so:1838 *     -- correct coeffs for temp (can reset temp timer)1839 *     -- save this temp as "last",1840 *     -- send new set of gain settings to NIC1841 * NOTE:  This should continue working, even when we're not associated,1842 *   so we can keep our internal table of scan powers current. */1843void1844il3945_reg_txpower_periodic(struct il_priv *il)1845{1846	/* This will kick in the "brute force"1847	 * il3945_hw_reg_comp_txpower_temp() below */1848	if (!il3945_is_temp_calib_needed(il))1849		goto reschedule;1850 1851	/* Set up a new set of temp-adjusted TxPowers, send to NIC.1852	 * This is based *only* on current temperature,1853	 * ignoring any previous power measurements */1854	il3945_hw_reg_comp_txpower_temp(il);1855 1856reschedule:1857	queue_delayed_work(il->workqueue, &il->_3945.thermal_periodic,1858			   REG_RECALIB_PERIOD * HZ);1859}1860 1861static void1862il3945_bg_reg_txpower_periodic(struct work_struct *work)1863{1864	struct il_priv *il = container_of(work, struct il_priv,1865					  _3945.thermal_periodic.work);1866 1867	mutex_lock(&il->mutex);1868	if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)1869		goto out;1870 1871	il3945_reg_txpower_periodic(il);1872out:1873	mutex_unlock(&il->mutex);1874}1875 1876/*1877 * il3945_hw_reg_get_ch_grp_idx - find the channel-group idx (0-4) for channel.1878 *1879 * This function is used when initializing channel-info structs.1880 *1881 * NOTE: These channel groups do *NOT* match the bands above!1882 *	 These channel groups are based on factory-tested channels;1883 *	 on A-band, EEPROM's "group frequency" entries represent the top1884 *	 channel in each group 1-4.  Group 5 All B/G channels are in group 0.1885 */1886static u161887il3945_hw_reg_get_ch_grp_idx(struct il_priv *il,1888			     const struct il_channel_info *ch_info)1889{1890	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;1891	struct il3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];1892	u8 group;1893	u16 group_idx = 0;	/* based on factory calib frequencies */1894	u8 grp_channel;1895 1896	/* Find the group idx for the channel ... don't use idx 1(?) */1897	if (il_is_channel_a_band(ch_info)) {1898		for (group = 1; group < 5; group++) {1899			grp_channel = ch_grp[group].group_channel;1900			if (ch_info->channel <= grp_channel) {1901				group_idx = group;1902				break;1903			}1904		}1905		/* group 4 has a few channels *above* its factory cal freq */1906		if (group == 5)1907			group_idx = 4;1908	} else1909		group_idx = 0;	/* 2.4 GHz, group 0 */1910 1911	D_POWER("Chnl %d mapped to grp %d\n", ch_info->channel, group_idx);1912	return group_idx;1913}1914 1915/*1916 * il3945_hw_reg_get_matched_power_idx - Interpolate to get nominal idx1917 *1918 * Interpolate to get nominal (i.e. at factory calibration temperature) idx1919 *   into radio/DSP gain settings table for requested power.1920 */1921static int1922il3945_hw_reg_get_matched_power_idx(struct il_priv *il, s8 requested_power,1923				    s32 setting_idx, s32 *new_idx)1924{1925	const struct il3945_eeprom_txpower_group *chnl_grp = NULL;1926	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;1927	s32 idx0, idx1;1928	s32 power = 2 * requested_power;1929	s32 i;1930	const struct il3945_eeprom_txpower_sample *samples;1931	s32 gains0, gains1;1932	s32 res;1933	s32 denominator;1934 1935	chnl_grp = &eeprom->groups[setting_idx];1936	samples = chnl_grp->samples;1937	for (i = 0; i < 5; i++) {1938		if (power == samples[i].power) {1939			*new_idx = samples[i].gain_idx;1940			return 0;1941		}1942	}1943 1944	if (power > samples[1].power) {1945		idx0 = 0;1946		idx1 = 1;1947	} else if (power > samples[2].power) {1948		idx0 = 1;1949		idx1 = 2;1950	} else if (power > samples[3].power) {1951		idx0 = 2;1952		idx1 = 3;1953	} else {1954		idx0 = 3;1955		idx1 = 4;1956	}1957 1958	denominator = (s32) samples[idx1].power - (s32) samples[idx0].power;1959	if (denominator == 0)1960		return -EINVAL;1961	gains0 = (s32) samples[idx0].gain_idx * (1 << 19);1962	gains1 = (s32) samples[idx1].gain_idx * (1 << 19);1963	res =1964	    gains0 + (gains1 - gains0) * ((s32) power -1965					  (s32) samples[idx0].power) /1966	    denominator + (1 << 18);1967	*new_idx = res >> 19;1968	return 0;1969}1970 1971static void1972il3945_hw_reg_init_channel_groups(struct il_priv *il)1973{1974	u32 i;1975	s32 rate_idx;1976	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;1977	const struct il3945_eeprom_txpower_group *group;1978 1979	D_POWER("Initializing factory calib info from EEPROM\n");1980 1981	for (i = 0; i < IL_NUM_TX_CALIB_GROUPS; i++) {1982		s8 *clip_pwrs;	/* table of power levels for each rate */1983		s8 satur_pwr;	/* saturation power for each chnl group */1984		group = &eeprom->groups[i];1985 1986		/* sanity check on factory saturation power value */1987		if (group->saturation_power < 40) {1988			IL_WARN("Error: saturation power is %d, "1989				"less than minimum expected 40\n",1990				group->saturation_power);1991			return;1992		}1993 1994		/*1995		 * Derive requested power levels for each rate, based on1996		 *   hardware capabilities (saturation power for band).1997		 * Basic value is 3dB down from saturation, with further1998		 *   power reductions for highest 3 data rates.  These1999		 *   backoffs provide headroom for high rate modulation2000		 *   power peaks, without too much distortion (clipping).2001		 */2002		/* we'll fill in this array with h/w max power levels */2003		clip_pwrs = (s8 *) il->_3945.clip_groups[i].clip_powers;2004 2005		/* divide factory saturation power by 2 to find -3dB level */2006		satur_pwr = (s8) (group->saturation_power >> 1);2007 2008		/* fill in channel group's nominal powers for each rate */2009		for (rate_idx = 0; rate_idx < RATE_COUNT_3945;2010		     rate_idx++, clip_pwrs++) {2011			switch (rate_idx) {2012			case RATE_36M_IDX_TBL:2013				if (i == 0)	/* B/G */2014					*clip_pwrs = satur_pwr;2015				else	/* A */2016					*clip_pwrs = satur_pwr - 5;2017				break;2018			case RATE_48M_IDX_TBL:2019				if (i == 0)2020					*clip_pwrs = satur_pwr - 7;2021				else2022					*clip_pwrs = satur_pwr - 10;2023				break;2024			case RATE_54M_IDX_TBL:2025				if (i == 0)2026					*clip_pwrs = satur_pwr - 9;2027				else2028					*clip_pwrs = satur_pwr - 12;2029				break;2030			default:2031				*clip_pwrs = satur_pwr;2032				break;2033			}2034		}2035	}2036}2037 2038/*2039 * il3945_txpower_set_from_eeprom - Set channel power info based on EEPROM2040 *2041 * Second pass (during init) to set up il->channel_info2042 *2043 * Set up Tx-power settings in our channel info database for each VALID2044 * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values2045 * and current temperature.2046 *2047 * Since this is based on current temperature (at init time), these values may2048 * not be valid for very long, but it gives us a starting/default point,2049 * and allows us to active (i.e. using Tx) scan.2050 *2051 * This does *not* write values to NIC, just sets up our internal table.2052 */2053int2054il3945_txpower_set_from_eeprom(struct il_priv *il)2055{2056	struct il_channel_info *ch_info = NULL;2057	struct il3945_channel_power_info *pwr_info;2058	struct il3945_eeprom *eeprom = (struct il3945_eeprom *)il->eeprom;2059	int delta_idx;2060	u8 rate_idx;2061	u8 scan_tbl_idx;2062	const s8 *clip_pwrs;	/* array of power levels for each rate */2063	u8 gain, dsp_atten;2064	s8 power;2065	u8 pwr_idx, base_pwr_idx, a_band;2066	u8 i;2067	int temperature;2068 2069	/* save temperature reference,2070	 *   so we can determine next time to calibrate */2071	temperature = il3945_hw_reg_txpower_get_temperature(il);2072	il->last_temperature = temperature;2073 2074	il3945_hw_reg_init_channel_groups(il);2075 2076	/* initialize Tx power info for each and every channel, 2.4 and 5.x */2077	for (i = 0, ch_info = il->channel_info; i < il->channel_count;2078	     i++, ch_info++) {2079		a_band = il_is_channel_a_band(ch_info);2080		if (!il_is_channel_valid(ch_info))2081			continue;2082 2083		/* find this channel's channel group (*not* "band") idx */2084		ch_info->group_idx = il3945_hw_reg_get_ch_grp_idx(il, ch_info);2085 2086		/* Get this chnlgrp's rate->max/clip-powers table */2087		clip_pwrs =2088		    il->_3945.clip_groups[ch_info->group_idx].clip_powers;2089 2090		/* calculate power idx *adjustment* value according to2091		 *  diff between current temperature and factory temperature */2092		delta_idx =2093		    il3945_hw_reg_adjust_power_by_temp(temperature,2094						       eeprom->groups[ch_info->2095								      group_idx].2096						       temperature);2097 2098		D_POWER("Delta idx for channel %d: %d [%d]\n", ch_info->channel,2099			delta_idx, temperature + IL_TEMP_CONVERT);2100 2101		/* set tx power value for all OFDM rates */2102		for (rate_idx = 0; rate_idx < IL_OFDM_RATES; rate_idx++) {2103			s32 power_idx;2104			int rc;2105 2106			/* use channel group's clip-power table,2107			 *   but don't exceed channel's max power */2108			s8 pwr = min(ch_info->max_power_avg,2109				     clip_pwrs[rate_idx]);2110 2111			pwr_info = &ch_info->power_info[rate_idx];2112 2113			/* get base (i.e. at factory-measured temperature)2114			 *    power table idx for this rate's power */2115			rc = il3945_hw_reg_get_matched_power_idx(il, pwr,2116								 ch_info->2117								 group_idx,2118								 &power_idx);2119			if (rc) {2120				IL_ERR("Invalid power idx\n");2121				return rc;2122			}2123			pwr_info->base_power_idx = (u8) power_idx;2124 2125			/* temperature compensate */2126			power_idx += delta_idx;2127 2128			/* stay within range of gain table */2129			power_idx = il3945_hw_reg_fix_power_idx(power_idx);2130 2131			/* fill 1 OFDM rate's il3945_channel_power_info struct */2132			pwr_info->requested_power = pwr;2133			pwr_info->power_table_idx = (u8) power_idx;2134			pwr_info->tpc.tx_gain =2135			    power_gain_table[a_band][power_idx].tx_gain;2136			pwr_info->tpc.dsp_atten =2137			    power_gain_table[a_band][power_idx].dsp_atten;2138		}2139 2140		/* set tx power for CCK rates, based on OFDM 12 Mbit settings */2141		pwr_info = &ch_info->power_info[RATE_12M_IDX_TBL];2142		power = pwr_info->requested_power + IL_CCK_FROM_OFDM_POWER_DIFF;2143		pwr_idx = pwr_info->power_table_idx + IL_CCK_FROM_OFDM_IDX_DIFF;2144		base_pwr_idx =2145		    pwr_info->base_power_idx + IL_CCK_FROM_OFDM_IDX_DIFF;2146 2147		/* stay within table range */2148		pwr_idx = il3945_hw_reg_fix_power_idx(pwr_idx);2149		gain = power_gain_table[a_band][pwr_idx].tx_gain;2150		dsp_atten = power_gain_table[a_band][pwr_idx].dsp_atten;2151 2152		/* fill each CCK rate's il3945_channel_power_info structure2153		 * NOTE:  All CCK-rate Txpwrs are the same for a given chnl!2154		 * NOTE:  CCK rates start at end of OFDM rates! */2155		for (rate_idx = 0; rate_idx < IL_CCK_RATES; rate_idx++) {2156			pwr_info =2157			    &ch_info->power_info[rate_idx + IL_OFDM_RATES];2158			pwr_info->requested_power = power;2159			pwr_info->power_table_idx = pwr_idx;2160			pwr_info->base_power_idx = base_pwr_idx;2161			pwr_info->tpc.tx_gain = gain;2162			pwr_info->tpc.dsp_atten = dsp_atten;2163		}2164 2165		/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */2166		for (scan_tbl_idx = 0; scan_tbl_idx < IL_NUM_SCAN_RATES;2167		     scan_tbl_idx++) {2168			s32 actual_idx =2169			    (scan_tbl_idx ==2170			     0) ? RATE_1M_IDX_TBL : RATE_6M_IDX_TBL;2171			il3945_hw_reg_set_scan_power(il, scan_tbl_idx,2172						     actual_idx, clip_pwrs,2173						     ch_info, a_band);2174		}2175	}2176 2177	return 0;2178}2179 2180int2181il3945_hw_rxq_stop(struct il_priv *il)2182{2183	int ret;2184 2185	_il_wr(il, FH39_RCSR_CONFIG(0), 0);2186	ret = _il_poll_bit(il, FH39_RSSR_STATUS,2187			   FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,2188			   FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,2189			   1000);2190	if (ret < 0)2191		IL_ERR("Can't stop Rx DMA.\n");2192 2193	return 0;2194}2195 2196int2197il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq)2198{2199	int txq_id = txq->q.id;2200 2201	struct il3945_shared *shared_data = il->_3945.shared_virt;2202 2203	shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32) txq->q.dma_addr);2204 2205	il_wr(il, FH39_CBCC_CTRL(txq_id), 0);2206	il_wr(il, FH39_CBCC_BASE(txq_id), 0);2207 2208	il_wr(il, FH39_TCSR_CONFIG(txq_id),2209	      FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |2210	      FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |2211	      FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |2212	      FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |2213	      FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);2214 2215	/* fake read to flush all prev. writes */2216	_il_rd(il, FH39_TSSR_CBB_BASE);2217 2218	return 0;2219}2220 2221/*2222 * HCMD utils2223 */2224static u162225il3945_get_hcmd_size(u8 cmd_id, u16 len)2226{2227	switch (cmd_id) {2228	case C_RXON:2229		return sizeof(struct il3945_rxon_cmd);2230	case C_POWER_TBL:2231		return sizeof(struct il3945_powertable_cmd);2232	default:2233		return len;2234	}2235}2236 2237static u162238il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)2239{2240	struct il3945_addsta_cmd *addsta = (struct il3945_addsta_cmd *)data;2241	addsta->mode = cmd->mode;2242	memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));2243	memcpy(&addsta->key, &cmd->key, sizeof(struct il4965_keyinfo));2244	addsta->station_flags = cmd->station_flags;2245	addsta->station_flags_msk = cmd->station_flags_msk;2246	addsta->tid_disable_tx = cpu_to_le16(0);2247	addsta->rate_n_flags = cmd->rate_n_flags;2248	addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;2249	addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;2250	addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;2251 2252	return (u16) sizeof(struct il3945_addsta_cmd);2253}2254 2255static int2256il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)2257{2258	int ret;2259	u8 sta_id;2260	unsigned long flags;2261 2262	if (sta_id_r)2263		*sta_id_r = IL_INVALID_STATION;2264 2265	ret = il_add_station_common(il, addr, 0, NULL, &sta_id);2266	if (ret) {2267		IL_ERR("Unable to add station %pM\n", addr);2268		return ret;2269	}2270 2271	if (sta_id_r)2272		*sta_id_r = sta_id;2273 2274	spin_lock_irqsave(&il->sta_lock, flags);2275	il->stations[sta_id].used |= IL_STA_LOCAL;2276	spin_unlock_irqrestore(&il->sta_lock, flags);2277 2278	return 0;2279}2280 2281static int2282il3945_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif,2283			   bool add)2284{2285	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;2286	int ret;2287 2288	if (add) {2289		ret =2290		    il3945_add_bssid_station(il, vif->bss_conf.bssid,2291					     &vif_priv->ibss_bssid_sta_id);2292		if (ret)2293			return ret;2294 2295		il3945_sync_sta(il, vif_priv->ibss_bssid_sta_id,2296				(il->band ==2297				 NL80211_BAND_5GHZ) ? RATE_6M_PLCP :2298				RATE_1M_PLCP);2299		il3945_rate_scale_init(il->hw, vif_priv->ibss_bssid_sta_id);2300 2301		return 0;2302	}2303 2304	return il_remove_station(il, vif_priv->ibss_bssid_sta_id,2305				 vif->bss_conf.bssid);2306}2307 2308/*2309 * il3945_init_hw_rate_table - Initialize the hardware rate fallback table2310 */2311int2312il3945_init_hw_rate_table(struct il_priv *il)2313{2314	int rc, i, idx, prev_idx;2315	struct il3945_rate_scaling_cmd rate_cmd = {2316		.reserved = {0, 0, 0},2317	};2318	struct il3945_rate_scaling_info *table = rate_cmd.table;2319 2320	for (i = 0; i < ARRAY_SIZE(il3945_rates); i++) {2321		idx = il3945_rates[i].table_rs_idx;2322 2323		table[idx].rate_n_flags = cpu_to_le16(il3945_rates[i].plcp);2324		table[idx].try_cnt = il->retry_rate;2325		prev_idx = il3945_get_prev_ieee_rate(i);2326		table[idx].next_rate_idx = il3945_rates[prev_idx].table_rs_idx;2327	}2328 2329	switch (il->band) {2330	case NL80211_BAND_5GHZ:2331		D_RATE("Select A mode rate scale\n");2332		/* If one of the following CCK rates is used,2333		 * have it fall back to the 6M OFDM rate */2334		for (i = RATE_1M_IDX_TBL; i <= RATE_11M_IDX_TBL; i++)2335			table[i].next_rate_idx =2336			    il3945_rates[IL_FIRST_OFDM_RATE].table_rs_idx;2337 2338		/* Don't fall back to CCK rates */2339		table[RATE_12M_IDX_TBL].next_rate_idx = RATE_9M_IDX_TBL;2340 2341		/* Don't drop out of OFDM rates */2342		table[RATE_6M_IDX_TBL].next_rate_idx =2343		    il3945_rates[IL_FIRST_OFDM_RATE].table_rs_idx;2344		break;2345 2346	case NL80211_BAND_2GHZ:2347		D_RATE("Select B/G mode rate scale\n");2348		/* If an OFDM rate is used, have it fall back to the2349		 * 1M CCK rates */2350 2351		if (!(il->_3945.sta_supp_rates & IL_OFDM_RATES_MASK) &&2352		    il_is_associated(il)) {2353 2354			idx = IL_FIRST_CCK_RATE;2355			for (i = RATE_6M_IDX_TBL; i <= RATE_54M_IDX_TBL; i++)2356				table[i].next_rate_idx =2357				    il3945_rates[idx].table_rs_idx;2358 2359			idx = RATE_11M_IDX_TBL;2360			/* CCK shouldn't fall back to OFDM... */2361			table[idx].next_rate_idx = RATE_5M_IDX_TBL;2362		}2363		break;2364 2365	default:2366		WARN_ON(1);2367		break;2368	}2369 2370	/* Update the rate scaling for control frame Tx */2371	rate_cmd.table_id = 0;2372	rc = il_send_cmd_pdu(il, C_RATE_SCALE, sizeof(rate_cmd), &rate_cmd);2373	if (rc)2374		return rc;2375 2376	/* Update the rate scaling for data frame Tx */2377	rate_cmd.table_id = 1;2378	return il_send_cmd_pdu(il, C_RATE_SCALE, sizeof(rate_cmd), &rate_cmd);2379}2380 2381/* Called when initializing driver */2382int2383il3945_hw_set_hw_params(struct il_priv *il)2384{2385	memset((void *)&il->hw_params, 0, sizeof(struct il_hw_params));2386 2387	il->_3945.shared_virt =2388	    dma_alloc_coherent(&il->pci_dev->dev, sizeof(struct il3945_shared),2389			       &il->_3945.shared_phys, GFP_KERNEL);2390	if (!il->_3945.shared_virt)2391		return -ENOMEM;2392 2393	il->hw_params.bcast_id = IL3945_BROADCAST_ID;2394 2395	/* Assign number of Usable TX queues */2396	il->hw_params.max_txq_num = il->cfg->num_of_queues;2397 2398	il->hw_params.tfd_size = sizeof(struct il3945_tfd);2399	il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K);2400	il->hw_params.max_rxq_size = RX_QUEUE_SIZE;2401	il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;2402	il->hw_params.max_stations = IL3945_STATION_COUNT;2403 2404	il->sta_key_max_num = STA_KEY_MAX_NUM;2405 2406	il->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;2407	il->hw_params.max_beacon_itrvl = IL39_MAX_UCODE_BEACON_INTERVAL;2408	il->hw_params.beacon_time_tsf_bits = IL3945_EXT_BEACON_TIME_POS;2409 2410	return 0;2411}2412 2413unsigned int2414il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame,2415			 u8 rate)2416{2417	struct il3945_tx_beacon_cmd *tx_beacon_cmd;2418	unsigned int frame_size;2419 2420	tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u;2421	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));2422 2423	tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;2424	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;2425 2426	frame_size =2427	    il3945_fill_beacon_frame(il, tx_beacon_cmd->frame,2428				     sizeof(frame->u) - sizeof(*tx_beacon_cmd));2429 2430	BUG_ON(frame_size > MAX_MPDU_SIZE);2431	tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size);2432 2433	tx_beacon_cmd->tx.rate = rate;2434	tx_beacon_cmd->tx.tx_flags =2435	    (TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK);2436 2437	/* supp_rates[0] == OFDM start at IL_FIRST_OFDM_RATE */2438	tx_beacon_cmd->tx.supp_rates[0] =2439	    (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;2440 2441	tx_beacon_cmd->tx.supp_rates[1] = (IL_CCK_BASIC_RATES_MASK & 0xF);2442 2443	return sizeof(struct il3945_tx_beacon_cmd) + frame_size;2444}2445 2446void2447il3945_hw_handler_setup(struct il_priv *il)2448{2449	il->handlers[C_TX] = il3945_hdl_tx;2450	il->handlers[N_3945_RX] = il3945_hdl_rx;2451}2452 2453void2454il3945_hw_setup_deferred_work(struct il_priv *il)2455{2456	INIT_DELAYED_WORK(&il->_3945.thermal_periodic,2457			  il3945_bg_reg_txpower_periodic);2458}2459 2460void2461il3945_hw_cancel_deferred_work(struct il_priv *il)2462{2463	cancel_delayed_work(&il->_3945.thermal_periodic);2464}2465 2466/* check contents of special bootstrap uCode SRAM */2467static int2468il3945_verify_bsm(struct il_priv *il)2469{2470	__le32 *image = il->ucode_boot.v_addr;2471	u32 len = il->ucode_boot.len;2472	u32 reg;2473	u32 val;2474 2475	D_INFO("Begin verify bsm\n");2476 2477	/* verify BSM SRAM contents */2478	val = il_rd_prph(il, BSM_WR_DWCOUNT_REG);2479	for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len;2480	     reg += sizeof(u32), image++) {2481		val = il_rd_prph(il, reg);2482		if (val != le32_to_cpu(*image)) {2483			IL_ERR("BSM uCode verification failed at "2484			       "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",2485			       BSM_SRAM_LOWER_BOUND, reg - BSM_SRAM_LOWER_BOUND,2486			       len, val, le32_to_cpu(*image));2487			return -EIO;2488		}2489	}2490 2491	D_INFO("BSM bootstrap uCode image OK\n");2492 2493	return 0;2494}2495 2496/******************************************************************************2497 *2498 * EEPROM related functions2499 *2500 ******************************************************************************/2501 2502/*2503 * Clear the OWNER_MSK, to establish driver (instead of uCode running on2504 * embedded controller) as EEPROM reader; each read is a series of pulses2505 * to/from the EEPROM chip, not a single event, so even reads could conflict2506 * if they weren't arbitrated by some ownership mechanism.  Here, the driver2507 * simply claims ownership, which should be safe when this function is called2508 * (i.e. before loading uCode!).2509 */2510static int2511il3945_eeprom_acquire_semaphore(struct il_priv *il)2512{2513	_il_clear_bit(il, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);2514	return 0;2515}2516 2517static void2518il3945_eeprom_release_semaphore(struct il_priv *il)2519{2520	return;2521}2522 2523 /*2524  * il3945_load_bsm - Load bootstrap instructions2525  *2526  * BSM operation:2527  *2528  * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program2529  * in special SRAM that does not power down during RFKILL.  When powering back2530  * up after power-saving sleeps (or during initial uCode load), the BSM loads2531  * the bootstrap program into the on-board processor, and starts it.2532  *2533  * The bootstrap program loads (via DMA) instructions and data for a new2534  * program from host DRAM locations indicated by the host driver in the2535  * BSM_DRAM_* registers.  Once the new program is loaded, it starts2536  * automatically.2537  *2538  * When initializing the NIC, the host driver points the BSM to the2539  * "initialize" uCode image.  This uCode sets up some internal data, then2540  * notifies host via "initialize alive" that it is complete.2541  *2542  * The host then replaces the BSM_DRAM_* pointer values to point to the2543  * normal runtime uCode instructions and a backup uCode data cache buffer2544  * (filled initially with starting data values for the on-board processor),2545  * then triggers the "initialize" uCode to load and launch the runtime uCode,2546  * which begins normal operation.2547  *2548  * When doing a power-save shutdown, runtime uCode saves data SRAM into2549  * the backup data cache in DRAM before SRAM is powered down.2550  *2551  * When powering back up, the BSM loads the bootstrap program.  This reloads2552  * the runtime uCode instructions and the backup data cache into SRAM,2553  * and re-launches the runtime uCode from where it left off.2554  */2555static int2556il3945_load_bsm(struct il_priv *il)2557{2558	__le32 *image = il->ucode_boot.v_addr;2559	u32 len = il->ucode_boot.len;2560	dma_addr_t pinst;2561	dma_addr_t pdata;2562	u32 inst_len;2563	u32 data_len;2564	int rc;2565	int i;2566	u32 done;2567	u32 reg_offset;2568 2569	D_INFO("Begin load bsm\n");2570 2571	/* make sure bootstrap program is no larger than BSM's SRAM size */2572	if (len > IL39_MAX_BSM_SIZE)2573		return -EINVAL;2574 2575	/* Tell bootstrap uCode where to find the "Initialize" uCode2576	 *   in host DRAM ... host DRAM physical address bits 31:0 for 3945.2577	 * NOTE:  il3945_initialize_alive_start() will replace these values,2578	 *        after the "initialize" uCode has run, to point to2579	 *        runtime/protocol instructions and backup data cache. */2580	pinst = il->ucode_init.p_addr;2581	pdata = il->ucode_init_data.p_addr;2582	inst_len = il->ucode_init.len;2583	data_len = il->ucode_init_data.len;2584 2585	il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);2586	il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);2587	il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);2588	il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);2589 2590	/* Fill BSM memory with bootstrap instructions */2591	for (reg_offset = BSM_SRAM_LOWER_BOUND;2592	     reg_offset < BSM_SRAM_LOWER_BOUND + len;2593	     reg_offset += sizeof(u32), image++)2594		_il_wr_prph(il, reg_offset, le32_to_cpu(*image));2595 2596	rc = il3945_verify_bsm(il);2597	if (rc)2598		return rc;2599 2600	/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */2601	il_wr_prph(il, BSM_WR_MEM_SRC_REG, 0x0);2602	il_wr_prph(il, BSM_WR_MEM_DST_REG, IL39_RTC_INST_LOWER_BOUND);2603	il_wr_prph(il, BSM_WR_DWCOUNT_REG, len / sizeof(u32));2604 2605	/* Load bootstrap code into instruction SRAM now,2606	 *   to prepare to load "initialize" uCode */2607	il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);2608 2609	/* Wait for load of bootstrap uCode to finish */2610	for (i = 0; i < 100; i++) {2611		done = il_rd_prph(il, BSM_WR_CTRL_REG);2612		if (!(done & BSM_WR_CTRL_REG_BIT_START))2613			break;2614		udelay(10);2615	}2616	if (i < 100)2617		D_INFO("BSM write complete, poll %d iterations\n", i);2618	else {2619		IL_ERR("BSM write did not complete!\n");2620		return -EIO;2621	}2622 2623	/* Enable future boot loads whenever power management unit triggers it2624	 *   (e.g. when powering back up after power-save shutdown) */2625	il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);2626 2627	return 0;2628}2629 2630const struct il_ops il3945_ops = {2631	.txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd,2632	.txq_free_tfd = il3945_hw_txq_free_tfd,2633	.txq_init = il3945_hw_tx_queue_init,2634	.load_ucode = il3945_load_bsm,2635	.dump_nic_error_log = il3945_dump_nic_error_log,2636	.apm_init = il3945_apm_init,2637	.send_tx_power = il3945_send_tx_power,2638	.is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr,2639	.eeprom_acquire_semaphore = il3945_eeprom_acquire_semaphore,2640	.eeprom_release_semaphore = il3945_eeprom_release_semaphore,2641 2642	.rxon_assoc = il3945_send_rxon_assoc,2643	.commit_rxon = il3945_commit_rxon,2644 2645	.get_hcmd_size = il3945_get_hcmd_size,2646	.build_addsta_hcmd = il3945_build_addsta_hcmd,2647	.request_scan = il3945_request_scan,2648	.post_scan = il3945_post_scan,2649 2650	.post_associate = il3945_post_associate,2651	.config_ap = il3945_config_ap,2652	.manage_ibss_station = il3945_manage_ibss_station,2653 2654	.send_led_cmd = il3945_send_led_cmd,2655};2656 2657static const struct il_cfg il3945_bg_cfg = {2658	.name = "3945BG",2659	.fw_name_pre = IL3945_FW_PRE,2660	.ucode_api_max = IL3945_UCODE_API_MAX,2661	.ucode_api_min = IL3945_UCODE_API_MIN,2662	.sku = IL_SKU_G,2663	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,2664	.mod_params = &il3945_mod_params,2665	.led_mode = IL_LED_BLINK,2666 2667	.eeprom_size = IL3945_EEPROM_IMG_SIZE,2668	.num_of_queues = IL39_NUM_QUEUES,2669	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,2670	.set_l0s = false,2671	.use_bsm = true,2672	.led_compensation = 64,2673	.wd_timeout = IL_DEF_WD_TIMEOUT,2674 2675	.regulatory_bands = {2676		EEPROM_REGULATORY_BAND_1_CHANNELS,2677		EEPROM_REGULATORY_BAND_2_CHANNELS,2678		EEPROM_REGULATORY_BAND_3_CHANNELS,2679		EEPROM_REGULATORY_BAND_4_CHANNELS,2680		EEPROM_REGULATORY_BAND_5_CHANNELS,2681		EEPROM_REGULATORY_BAND_NO_HT40,2682		EEPROM_REGULATORY_BAND_NO_HT40,2683	},2684};2685 2686static const struct il_cfg il3945_abg_cfg = {2687	.name = "3945ABG",2688	.fw_name_pre = IL3945_FW_PRE,2689	.ucode_api_max = IL3945_UCODE_API_MAX,2690	.ucode_api_min = IL3945_UCODE_API_MIN,2691	.sku = IL_SKU_A | IL_SKU_G,2692	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,2693	.mod_params = &il3945_mod_params,2694	.led_mode = IL_LED_BLINK,2695 2696	.eeprom_size = IL3945_EEPROM_IMG_SIZE,2697	.num_of_queues = IL39_NUM_QUEUES,2698	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,2699	.set_l0s = false,2700	.use_bsm = true,2701	.led_compensation = 64,2702	.wd_timeout = IL_DEF_WD_TIMEOUT,2703 2704	.regulatory_bands = {2705		EEPROM_REGULATORY_BAND_1_CHANNELS,2706		EEPROM_REGULATORY_BAND_2_CHANNELS,2707		EEPROM_REGULATORY_BAND_3_CHANNELS,2708		EEPROM_REGULATORY_BAND_4_CHANNELS,2709		EEPROM_REGULATORY_BAND_5_CHANNELS,2710		EEPROM_REGULATORY_BAND_NO_HT40,2711		EEPROM_REGULATORY_BAND_NO_HT40,2712	},2713};2714 2715const struct pci_device_id il3945_hw_card_ids[] = {2716	{IL_PCI_DEVICE(0x4222, 0x1005, il3945_bg_cfg)},2717	{IL_PCI_DEVICE(0x4222, 0x1034, il3945_bg_cfg)},2718	{IL_PCI_DEVICE(0x4222, 0x1044, il3945_bg_cfg)},2719	{IL_PCI_DEVICE(0x4227, 0x1014, il3945_bg_cfg)},2720	{IL_PCI_DEVICE(0x4222, PCI_ANY_ID, il3945_abg_cfg)},2721	{IL_PCI_DEVICE(0x4227, PCI_ANY_ID, il3945_abg_cfg)},2722	{0}2723};2724 2725MODULE_DEVICE_TABLE(pci, il3945_hw_card_ids);2726