brintos

brintos / linux-shallow public Read only

0
0
Text · 36.6 KiB · c67f163 Raw
1381 lines · c
1/*2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>4 * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>5 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>7 *8 * Permission to use, copy, modify, and distribute this software for any9 * purpose with or without fee is hereby granted, provided that the above10 * copyright notice and this permission notice appear in all copies.11 *12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.19 *20 */21 22/****************************\23  Reset function and helpers24\****************************/25 26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt27 28#include <linux/unaligned.h>29 30#include <linux/pci.h>		/* To determine if a card is pci-e */31#include <linux/log2.h>32#include <linux/platform_device.h>33#include "ath5k.h"34#include "reg.h"35#include "debug.h"36 37 38/**39 * DOC: Reset function and helpers40 *41 * Here we implement the main reset routine, used to bring the card42 * to a working state and ready to receive. We also handle routines43 * that don't fit on other places such as clock, sleep and power control44 */45 46 47/******************\48* Helper functions *49\******************/50 51/**52 * ath5k_hw_register_timeout() - Poll a register for a flag/field change53 * @ah: The &struct ath5k_hw54 * @reg: The register to read55 * @flag: The flag/field to check on the register56 * @val: The field value we expect (if we check a field)57 * @is_set: Instead of checking if the flag got cleared, check if it got set58 *59 * Some registers contain flags that indicate that an operation is60 * running. We use this function to poll these registers and check61 * if these flags get cleared. We also use it to poll a register62 * field (containing multiple flags) until it gets a specific value.63 *64 * Returns -EAGAIN if we exceeded AR5K_TUNE_REGISTER_TIMEOUT * 15us or 065 */66int67ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,68			      bool is_set)69{70	int i;71	u32 data;72 73	for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {74		data = ath5k_hw_reg_read(ah, reg);75		if (is_set && (data & flag))76			break;77		else if ((data & flag) == val)78			break;79		udelay(15);80	}81 82	return (i <= 0) ? -EAGAIN : 0;83}84 85 86/*************************\87* Clock related functions *88\*************************/89 90/**91 * ath5k_hw_htoclock() - Translate usec to hw clock units92 * @ah: The &struct ath5k_hw93 * @usec: value in microseconds94 *95 * Translate usecs to hw clock units based on the current96 * hw clock rate.97 *98 * Returns number of clock units99 */100unsigned int101ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)102{103	struct ath_common *common = ath5k_hw_common(ah);104	return usec * common->clockrate;105}106 107/**108 * ath5k_hw_clocktoh() - Translate hw clock units to usec109 * @ah: The &struct ath5k_hw110 * @clock: value in hw clock units111 *112 * Translate hw clock units to usecs based on the current113 * hw clock rate.114 *115 * Returns number of usecs116 */117unsigned int118ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)119{120	struct ath_common *common = ath5k_hw_common(ah);121	return clock / common->clockrate;122}123 124/**125 * ath5k_hw_init_core_clock() - Initialize core clock126 * @ah: The &struct ath5k_hw127 *128 * Initialize core clock parameters (usec, usec32, latencies etc),129 * based on current bwmode and chipset properties.130 */131static void132ath5k_hw_init_core_clock(struct ath5k_hw *ah)133{134	struct ieee80211_channel *channel = ah->ah_current_channel;135	struct ath_common *common = ath5k_hw_common(ah);136	u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;137 138	/*139	 * Set core clock frequency140	 */141	switch (channel->hw_value) {142	case AR5K_MODE_11A:143		clock = 40;144		break;145	case AR5K_MODE_11B:146		clock = 22;147		break;148	case AR5K_MODE_11G:149	default:150		clock = 44;151		break;152	}153 154	/* Use clock multiplier for non-default155	 * bwmode */156	switch (ah->ah_bwmode) {157	case AR5K_BWMODE_40MHZ:158		clock *= 2;159		break;160	case AR5K_BWMODE_10MHZ:161		clock /= 2;162		break;163	case AR5K_BWMODE_5MHZ:164		clock /= 4;165		break;166	default:167		break;168	}169 170	common->clockrate = clock;171 172	/*173	 * Set USEC parameters174	 */175	/* Set USEC counter on PCU*/176	usec = clock - 1;177	usec = AR5K_REG_SM(usec, AR5K_USEC_1);178 179	/* Set usec duration on DCU */180	if (ah->ah_version != AR5K_AR5210)181		AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,182					AR5K_DCU_GBL_IFS_MISC_USEC_DUR,183					clock);184 185	/* Set 32MHz USEC counter */186	if ((ah->ah_radio == AR5K_RF5112) ||187	    (ah->ah_radio == AR5K_RF2413) ||188	    (ah->ah_radio == AR5K_RF5413) ||189	    (ah->ah_radio == AR5K_RF2316) ||190	    (ah->ah_radio == AR5K_RF2317))191		/* Remain on 40MHz clock ? */192		sclock = 40 - 1;193	else194		sclock = 32 - 1;195	sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);196 197	/*198	 * Set tx/rx latencies199	 */200	usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);201	txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);202	rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);203 204	/*205	 * Set default Tx frame to Tx data start delay206	 */207	txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;208 209	/*210	 * 5210 initvals don't include usec settings211	 * so we need to use magic values here for212	 * tx/rx latencies213	 */214	if (ah->ah_version == AR5K_AR5210) {215		/* same for turbo */216		txlat = AR5K_INIT_TX_LATENCY_5210;217		rxlat = AR5K_INIT_RX_LATENCY_5210;218	}219 220	if (ah->ah_mac_srev < AR5K_SREV_AR5211) {221		/* 5311 has different tx/rx latency masks222		 * from 5211, since we deal 5311 the same223		 * as 5211 when setting initvals, shift224		 * values here to their proper locations225		 *226		 * Note: Initvals indicate tx/rx/ latencies227		 * are the same for turbo mode */228		txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);229		rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);230	} else231	switch (ah->ah_bwmode) {232	case AR5K_BWMODE_10MHZ:233		txlat = AR5K_REG_SM(txlat * 2,234				AR5K_USEC_TX_LATENCY_5211);235		rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,236				AR5K_USEC_RX_LATENCY_5211);237		txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;238		break;239	case AR5K_BWMODE_5MHZ:240		txlat = AR5K_REG_SM(txlat * 4,241				AR5K_USEC_TX_LATENCY_5211);242		rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,243				AR5K_USEC_RX_LATENCY_5211);244		txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;245		break;246	case AR5K_BWMODE_40MHZ:247		txlat = AR5K_INIT_TX_LAT_MIN;248		rxlat = AR5K_REG_SM(rxlat / 2,249				AR5K_USEC_RX_LATENCY_5211);250		txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;251		break;252	default:253		break;254	}255 256	usec_reg = (usec | sclock | txlat | rxlat);257	ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);258 259	/* On 5112 set tx frame to tx data start delay */260	if (ah->ah_radio == AR5K_RF5112) {261		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,262					AR5K_PHY_RF_CTL2_TXF2TXD_START,263					txf2txs);264	}265}266 267/**268 * ath5k_hw_set_sleep_clock() - Setup sleep clock operation269 * @ah: The &struct ath5k_hw270 * @enable: Enable sleep clock operation (false to disable)271 *272 * If there is an external 32KHz crystal available, use it273 * as ref. clock instead of 32/40MHz clock and baseband clocks274 * to save power during sleep or restore normal 32/40MHz275 * operation.276 *277 * NOTE: When operating on 32KHz certain PHY registers (27 - 31,278 * 123 - 127) require delay on access.279 */280static void281ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)282{283	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;284	u32 scal, spending, sclock;285 286	/* Only set 32KHz settings if we have an external287	 * 32KHz crystal present */288	if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||289	AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&290	enable) {291 292		/* 1 usec/cycle */293		AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);294		/* Set up tsf increment on each cycle */295		AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);296 297		/* Set baseband sleep control registers298		 * and sleep control rate */299		ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);300 301		if ((ah->ah_radio == AR5K_RF5112) ||302		(ah->ah_radio == AR5K_RF5413) ||303		(ah->ah_radio == AR5K_RF2316) ||304		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))305			spending = 0x14;306		else307			spending = 0x18;308		ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);309 310		if ((ah->ah_radio == AR5K_RF5112) ||311		(ah->ah_radio == AR5K_RF5413) ||312		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {313			ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);314			ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);315			ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);316			ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);317			AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,318				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);319		} else {320			ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);321			ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);322			ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);323			ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);324			AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,325				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);326		}327 328		/* Enable sleep clock operation */329		AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,330				AR5K_PCICFG_SLEEP_CLOCK_EN);331 332	} else {333 334		/* Disable sleep clock operation and335		 * restore default parameters */336		AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,337				AR5K_PCICFG_SLEEP_CLOCK_EN);338 339		AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,340				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);341 342		/* Set DAC/ADC delays */343		ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);344		ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);345 346		if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))347			scal = AR5K_PHY_SCAL_32MHZ_2417;348		else if (ee->ee_is_hb63)349			scal = AR5K_PHY_SCAL_32MHZ_HB63;350		else351			scal = AR5K_PHY_SCAL_32MHZ;352		ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);353 354		ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);355		ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);356 357		if ((ah->ah_radio == AR5K_RF5112) ||358		(ah->ah_radio == AR5K_RF5413) ||359		(ah->ah_radio == AR5K_RF2316) ||360		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))361			spending = 0x14;362		else363			spending = 0x18;364		ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);365 366		/* Set up tsf increment on each cycle */367		AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);368 369		if ((ah->ah_radio == AR5K_RF5112) ||370			(ah->ah_radio == AR5K_RF5413) ||371			(ah->ah_radio == AR5K_RF2316) ||372			(ah->ah_radio == AR5K_RF2317))373			sclock = 40 - 1;374		else375			sclock = 32 - 1;376		AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);377	}378}379 380 381/*********************\382* Reset/Sleep control *383\*********************/384 385/**386 * ath5k_hw_nic_reset() - Reset the various chipset units387 * @ah: The &struct ath5k_hw388 * @val: Mask to indicate what units to reset389 *390 * To reset the various chipset units we need to write391 * the mask to AR5K_RESET_CTL and poll the register until392 * all flags are cleared.393 *394 * Returns 0 if we are O.K. or -EAGAIN (from athk5_hw_register_timeout)395 */396static int397ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)398{399	int ret;400	u32 mask = val ? val : ~0U;401 402	/* Read-and-clear RX Descriptor Pointer*/403	ath5k_hw_reg_read(ah, AR5K_RXDP);404 405	/*406	 * Reset the device and wait until success407	 */408	ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);409 410	/* Wait at least 128 PCI clocks */411	usleep_range(15, 20);412 413	if (ah->ah_version == AR5K_AR5210) {414		val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA415			| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;416		mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA417			| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;418	} else {419		val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;420		mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;421	}422 423	ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);424 425	/*426	 * Reset configuration register (for hw byte-swap). Note that this427	 * is only set for big endian. We do the necessary magic in428	 * AR5K_INIT_CFG.429	 */430	if ((val & AR5K_RESET_CTL_PCU) == 0)431		ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);432 433	return ret;434}435 436/**437 * ath5k_hw_wisoc_reset() -  Reset AHB chipset438 * @ah: The &struct ath5k_hw439 * @flags: Mask to indicate what units to reset440 *441 * Same as ath5k_hw_nic_reset but for AHB based devices442 *443 * Returns 0 if we are O.K. or -EAGAIN (from athk5_hw_register_timeout)444 */445static int446ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)447{448	u32 mask = flags ? flags : ~0U;449	u32 __iomem *reg;450	u32 regval;451	u32 val = 0;452 453	/* ah->ah_mac_srev is not available at this point yet */454	if (ah->devid >= AR5K_SREV_AR2315_R6) {455		reg = (u32 __iomem *) AR5K_AR2315_RESET;456		if (mask & AR5K_RESET_CTL_PCU)457			val |= AR5K_AR2315_RESET_WMAC;458		if (mask & AR5K_RESET_CTL_BASEBAND)459			val |= AR5K_AR2315_RESET_BB_WARM;460	} else {461		reg = (u32 __iomem *) AR5K_AR5312_RESET;462		if (to_platform_device(ah->dev)->id == 0) {463			if (mask & AR5K_RESET_CTL_PCU)464				val |= AR5K_AR5312_RESET_WMAC0;465			if (mask & AR5K_RESET_CTL_BASEBAND)466				val |= AR5K_AR5312_RESET_BB0_COLD |467				       AR5K_AR5312_RESET_BB0_WARM;468		} else {469			if (mask & AR5K_RESET_CTL_PCU)470				val |= AR5K_AR5312_RESET_WMAC1;471			if (mask & AR5K_RESET_CTL_BASEBAND)472				val |= AR5K_AR5312_RESET_BB1_COLD |473				       AR5K_AR5312_RESET_BB1_WARM;474		}475	}476 477	/* Put BB/MAC into reset */478	regval = ioread32(reg);479	iowrite32(regval | val, reg);480	regval = ioread32(reg);481	udelay(100);	/* NB: should be atomic */482 483	/* Bring BB/MAC out of reset */484	iowrite32(regval & ~val, reg);485	regval = ioread32(reg);486 487	/*488	 * Reset configuration register (for hw byte-swap). Note that this489	 * is only set for big endian. We do the necessary magic in490	 * AR5K_INIT_CFG.491	 */492	if ((flags & AR5K_RESET_CTL_PCU) == 0)493		ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);494 495	return 0;496}497 498/**499 * ath5k_hw_set_power_mode() - Set power mode500 * @ah: The &struct ath5k_hw501 * @mode: One of enum ath5k_power_mode502 * @set_chip: Set to true to write sleep control register503 * @sleep_duration: How much time the device is allowed to sleep504 * when sleep logic is enabled (in 128 microsecond increments).505 *506 * This function is used to configure sleep policy and allowed507 * sleep modes. For more information check out the sleep control508 * register on reg.h and STA_ID1.509 *510 * Returns 0 on success, -EIO if chip didn't wake up or -EINVAL if an invalid511 * mode is requested.512 */513static int514ath5k_hw_set_power_mode(struct ath5k_hw *ah, enum ath5k_power_mode mode,515			      bool set_chip, u16 sleep_duration)516{517	unsigned int i;518	u32 staid, data;519 520	staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);521 522	switch (mode) {523	case AR5K_PM_AUTO:524		staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;525		fallthrough;526	case AR5K_PM_NETWORK_SLEEP:527		if (set_chip)528			ath5k_hw_reg_write(ah,529				AR5K_SLEEP_CTL_SLE_ALLOW |530				sleep_duration,531				AR5K_SLEEP_CTL);532 533		staid |= AR5K_STA_ID1_PWR_SV;534		break;535 536	case AR5K_PM_FULL_SLEEP:537		if (set_chip)538			ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,539				AR5K_SLEEP_CTL);540 541		staid |= AR5K_STA_ID1_PWR_SV;542		break;543 544	case AR5K_PM_AWAKE:545 546		staid &= ~AR5K_STA_ID1_PWR_SV;547 548		if (!set_chip)549			goto commit;550 551		data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);552 553		/* If card is down we 'll get 0xffff... so we554		 * need to clean this up before we write the register555		 */556		if (data & 0xffc00000)557			data = 0;558		else559			/* Preserve sleep duration etc */560			data = data & ~AR5K_SLEEP_CTL_SLE;561 562		ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,563							AR5K_SLEEP_CTL);564		usleep_range(15, 20);565 566		for (i = 200; i > 0; i--) {567			/* Check if the chip did wake up */568			if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &569					AR5K_PCICFG_SPWR_DN) == 0)570				break;571 572			/* Wait a bit and retry */573			usleep_range(50, 75);574			ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,575							AR5K_SLEEP_CTL);576		}577 578		/* Fail if the chip didn't wake up */579		if (i == 0)580			return -EIO;581 582		break;583 584	default:585		return -EINVAL;586	}587 588commit:589	ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);590 591	return 0;592}593 594/**595 * ath5k_hw_on_hold() - Put device on hold596 * @ah: The &struct ath5k_hw597 *598 * Put MAC and Baseband on warm reset and keep that state599 * (don't clean sleep control register). After this MAC600 * and Baseband are disabled and a full reset is needed601 * to come back. This way we save as much power as possible602 * without putting the card on full sleep.603 *604 * Returns 0 on success or -EIO on error605 */606int607ath5k_hw_on_hold(struct ath5k_hw *ah)608{609	struct pci_dev *pdev = ah->pdev;610	u32 bus_flags;611	int ret;612 613	if (ath5k_get_bus_type(ah) == ATH_AHB)614		return 0;615 616	/* Make sure device is awake */617	ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);618	if (ret) {619		ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");620		return ret;621	}622 623	/*624	 * Put chipset on warm reset...625	 *626	 * Note: putting PCI core on warm reset on PCI-E cards627	 * results card to hang and always return 0xffff... so628	 * we ignore that flag for PCI-E cards. On PCI cards629	 * this flag gets cleared after 64 PCI clocks.630	 */631	bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;632 633	if (ah->ah_version == AR5K_AR5210) {634		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |635			AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |636			AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);637		usleep_range(2000, 2500);638	} else {639		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |640			AR5K_RESET_CTL_BASEBAND | bus_flags);641	}642 643	if (ret) {644		ATH5K_ERR(ah, "failed to put device on warm reset\n");645		return -EIO;646	}647 648	/* ...wakeup again!*/649	ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);650	if (ret) {651		ATH5K_ERR(ah, "failed to put device on hold\n");652		return ret;653	}654 655	return ret;656}657 658/**659 * ath5k_hw_nic_wakeup() - Force card out of sleep660 * @ah: The &struct ath5k_hw661 * @channel: The &struct ieee80211_channel662 *663 * Bring up MAC + PHY Chips and program PLL664 * NOTE: Channel is NULL for the initial wakeup.665 *666 * Returns 0 on success, -EIO on hw failure or -EINVAL for false channel infos667 */668int669ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)670{671	struct pci_dev *pdev = ah->pdev;672	u32 turbo, mode, clock, bus_flags;673	int ret;674 675	turbo = 0;676	mode = 0;677	clock = 0;678 679	if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) {680		/* Wakeup the device */681		ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);682		if (ret) {683			ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");684			return ret;685		}686	}687 688	/*689	 * Put chipset on warm reset...690	 *691	 * Note: putting PCI core on warm reset on PCI-E cards692	 * results card to hang and always return 0xffff... so693	 * we ignore that flag for PCI-E cards. On PCI cards694	 * this flag gets cleared after 64 PCI clocks.695	 */696	bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;697 698	if (ah->ah_version == AR5K_AR5210) {699		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |700			AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |701			AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);702		usleep_range(2000, 2500);703	} else {704		if (ath5k_get_bus_type(ah) == ATH_AHB)705			ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |706				AR5K_RESET_CTL_BASEBAND);707		else708			ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |709				AR5K_RESET_CTL_BASEBAND | bus_flags);710	}711 712	if (ret) {713		ATH5K_ERR(ah, "failed to reset the MAC Chip\n");714		return -EIO;715	}716 717	/* ...wakeup again!...*/718	ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);719	if (ret) {720		ATH5K_ERR(ah, "failed to resume the MAC Chip\n");721		return ret;722	}723 724	/* ...reset configuration register on Wisoc ...725	 * ...clear reset control register and pull device out of726	 * warm reset on others */727	if (ath5k_get_bus_type(ah) == ATH_AHB)728		ret = ath5k_hw_wisoc_reset(ah, 0);729	else730		ret = ath5k_hw_nic_reset(ah, 0);731 732	if (ret) {733		ATH5K_ERR(ah, "failed to warm reset the MAC Chip\n");734		return -EIO;735	}736 737	/* On initialization skip PLL programming since we don't have738	 * a channel / mode set yet */739	if (!channel)740		return 0;741 742	if (ah->ah_version != AR5K_AR5210) {743		/*744		 * Get channel mode flags745		 */746 747		if (ah->ah_radio >= AR5K_RF5112) {748			mode = AR5K_PHY_MODE_RAD_RF5112;749			clock = AR5K_PHY_PLL_RF5112;750		} else {751			mode = AR5K_PHY_MODE_RAD_RF5111;	/*Zero*/752			clock = AR5K_PHY_PLL_RF5111;		/*Zero*/753		}754 755		if (channel->band == NL80211_BAND_2GHZ) {756			mode |= AR5K_PHY_MODE_FREQ_2GHZ;757			clock |= AR5K_PHY_PLL_44MHZ;758 759			if (channel->hw_value == AR5K_MODE_11B) {760				mode |= AR5K_PHY_MODE_MOD_CCK;761			} else {762				/* XXX Dynamic OFDM/CCK is not supported by the763				 * AR5211 so we set MOD_OFDM for plain g (no764				 * CCK headers) operation. We need to test765				 * this, 5211 might support ofdm-only g after766				 * all, there are also initial register values767				 * in the code for g mode (see initvals.c).768				 */769				if (ah->ah_version == AR5K_AR5211)770					mode |= AR5K_PHY_MODE_MOD_OFDM;771				else772					mode |= AR5K_PHY_MODE_MOD_DYN;773			}774		} else if (channel->band == NL80211_BAND_5GHZ) {775			mode |= (AR5K_PHY_MODE_FREQ_5GHZ |776				 AR5K_PHY_MODE_MOD_OFDM);777 778			/* Different PLL setting for 5413 */779			if (ah->ah_radio == AR5K_RF5413)780				clock = AR5K_PHY_PLL_40MHZ_5413;781			else782				clock |= AR5K_PHY_PLL_40MHZ;783		} else {784			ATH5K_ERR(ah, "invalid radio frequency mode\n");785			return -EINVAL;786		}787 788		/*XXX: Can bwmode be used with dynamic mode ?789		 * (I don't think it supports 44MHz) */790		/* On 2425 initvals TURBO_SHORT is not present */791		if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {792			turbo = AR5K_PHY_TURBO_MODE;793			if (ah->ah_radio != AR5K_RF2425)794				turbo |= AR5K_PHY_TURBO_SHORT;795		} else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {796			if (ah->ah_radio == AR5K_RF5413) {797				mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?798					AR5K_PHY_MODE_HALF_RATE :799					AR5K_PHY_MODE_QUARTER_RATE;800			} else if (ah->ah_version == AR5K_AR5212) {801				clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?802					AR5K_PHY_PLL_HALF_RATE :803					AR5K_PHY_PLL_QUARTER_RATE;804			}805		}806 807	} else { /* Reset the device */808 809		/* ...enable Atheros turbo mode if requested */810		if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)811			ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,812					AR5K_PHY_TURBO);813	}814 815	if (ah->ah_version != AR5K_AR5210) {816 817		/* ...update PLL if needed */818		if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {819			ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);820			usleep_range(300, 350);821		}822 823		/* ...set the PHY operating mode */824		ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);825		ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);826	}827 828	return 0;829}830 831 832/**************************************\833* Post-initvals register modifications *834\**************************************/835 836/**837 * ath5k_hw_tweak_initval_settings() - Tweak initial settings838 * @ah: The &struct ath5k_hw839 * @channel: The &struct ieee80211_channel840 *841 * Some settings are not handled on initvals, e.g. bwmode842 * settings, some phy settings, workarounds etc that in general843 * don't fit anywhere else or are too small to introduce a separate844 * function for each one. So we have this function to handle845 * them all during reset and complete card's initialization.846 */847static void848ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,849				struct ieee80211_channel *channel)850{851	if (ah->ah_version == AR5K_AR5212 &&852	    ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {853 854		/* Setup ADC control */855		ath5k_hw_reg_write(ah,856				(AR5K_REG_SM(2,857				AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |858				AR5K_REG_SM(2,859				AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |860				AR5K_PHY_ADC_CTL_PWD_DAC_OFF |861				AR5K_PHY_ADC_CTL_PWD_ADC_OFF),862				AR5K_PHY_ADC_CTL);863 864 865 866		/* Disable barker RSSI threshold */867		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,868				AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);869 870		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,871			AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);872 873		/* Set the mute mask */874		ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);875	}876 877	/* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */878	if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)879		ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);880 881	/* Enable DCU double buffering */882	if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)883		AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,884				AR5K_TXCFG_DCU_DBL_BUF_DIS);885 886	/* Set fast ADC */887	if ((ah->ah_radio == AR5K_RF5413) ||888		(ah->ah_radio == AR5K_RF2317) ||889		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {890		u32 fast_adc = true;891 892		if (channel->center_freq == 2462 ||893		channel->center_freq == 2467)894			fast_adc = 0;895 896		/* Only update if needed */897		if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)898				ath5k_hw_reg_write(ah, fast_adc,899						AR5K_PHY_FAST_ADC);900	}901 902	/* Fix for first revision of the RF5112 RF chipset */903	if (ah->ah_radio == AR5K_RF5112 &&904			ah->ah_radio_5ghz_revision <905			AR5K_SREV_RAD_5112A) {906		u32 data;907		ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,908				AR5K_PHY_CCKTXCTL);909		if (channel->band == NL80211_BAND_5GHZ)910			data = 0xffb81020;911		else912			data = 0xffb80d20;913		ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);914	}915 916	if (ah->ah_mac_srev < AR5K_SREV_AR5211) {917		/* Clear QCU/DCU clock gating register */918		ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);919		/* Set DAC/ADC delays */920		ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,921						AR5K_PHY_SCAL);922		/* Enable PCU FIFO corruption ECO */923		AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,924					AR5K_DIAG_SW_ECO_ENABLE);925	}926 927	if (ah->ah_bwmode) {928		/* Increase PHY switch and AGC settling time929		 * on turbo mode (ath5k_hw_commit_eeprom_settings930		 * will override settling time if available) */931		if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {932 933			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,934						AR5K_PHY_SETTLING_AGC,935						AR5K_AGC_SETTLING_TURBO);936 937			/* XXX: Initvals indicate we only increase938			 * switch time on AR5212, 5211 and 5210939			 * only change agc time (bug?) */940			if (ah->ah_version == AR5K_AR5212)941				AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,942						AR5K_PHY_SETTLING_SWITCH,943						AR5K_SWITCH_SETTLING_TURBO);944 945			if (ah->ah_version == AR5K_AR5210) {946				/* Set Frame Control Register */947				ath5k_hw_reg_write(ah,948					(AR5K_PHY_FRAME_CTL_INI |949					AR5K_PHY_TURBO_MODE |950					AR5K_PHY_TURBO_SHORT | 0x2020),951					AR5K_PHY_FRAME_CTL_5210);952			}953		/* On 5413 PHY force window length for half/quarter rate*/954		} else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&955		(ah->ah_mac_srev <= AR5K_SREV_AR5414)) {956			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,957						AR5K_PHY_FRAME_CTL_WIN_LEN,958						3);959		}960	} else if (ah->ah_version == AR5K_AR5210) {961		/* Set Frame Control Register for normal operation */962		ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),963						AR5K_PHY_FRAME_CTL_5210);964	}965}966 967/**968 * ath5k_hw_commit_eeprom_settings() - Commit settings from EEPROM969 * @ah: The &struct ath5k_hw970 * @channel: The &struct ieee80211_channel971 *972 * Use settings stored on EEPROM to properly initialize the card973 * based on various infos and per-mode calibration data.974 */975static void976ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,977		struct ieee80211_channel *channel)978{979	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;980	s16 cck_ofdm_pwr_delta;981	u8 ee_mode;982 983	/* TODO: Add support for AR5210 EEPROM */984	if (ah->ah_version == AR5K_AR5210)985		return;986 987	ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);988 989	/* Adjust power delta for channel 14 */990	if (channel->center_freq == 2484)991		cck_ofdm_pwr_delta =992			((ee->ee_cck_ofdm_power_delta -993			ee->ee_scaled_cck_delta) * 2) / 10;994	else995		cck_ofdm_pwr_delta =996			(ee->ee_cck_ofdm_power_delta * 2) / 10;997 998	/* Set CCK to OFDM power delta on tx power999	 * adjustment register */1000	if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {1001		if (channel->hw_value == AR5K_MODE_11G)1002			ath5k_hw_reg_write(ah,1003			AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),1004				AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |1005			AR5K_REG_SM((cck_ofdm_pwr_delta * -1),1006				AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),1007				AR5K_PHY_TX_PWR_ADJ);1008		else1009			ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);1010	} else {1011		/* For older revs we scale power on sw during tx power1012		 * setup */1013		ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;1014		ah->ah_txpower.txp_cck_ofdm_gainf_delta =1015						ee->ee_cck_ofdm_gain_delta;1016	}1017 1018	/* XXX: necessary here? is called from ath5k_hw_set_antenna_mode()1019	 * too */1020	ath5k_hw_set_antenna_switch(ah, ee_mode);1021 1022	/* Noise floor threshold */1023	ath5k_hw_reg_write(ah,1024		AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),1025		AR5K_PHY_NFTHRES);1026 1027	if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&1028	(ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {1029		/* Switch settling time (Turbo) */1030		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,1031				AR5K_PHY_SETTLING_SWITCH,1032				ee->ee_switch_settling_turbo[ee_mode]);1033 1034		/* Tx/Rx attenuation (Turbo) */1035		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,1036				AR5K_PHY_GAIN_TXRX_ATTEN,1037				ee->ee_atn_tx_rx_turbo[ee_mode]);1038 1039		/* ADC/PGA desired size (Turbo) */1040		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,1041				AR5K_PHY_DESIRED_SIZE_ADC,1042				ee->ee_adc_desired_size_turbo[ee_mode]);1043 1044		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,1045				AR5K_PHY_DESIRED_SIZE_PGA,1046				ee->ee_pga_desired_size_turbo[ee_mode]);1047 1048		/* Tx/Rx margin (Turbo) */1049		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,1050				AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,1051				ee->ee_margin_tx_rx_turbo[ee_mode]);1052 1053	} else {1054		/* Switch settling time */1055		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,1056				AR5K_PHY_SETTLING_SWITCH,1057				ee->ee_switch_settling[ee_mode]);1058 1059		/* Tx/Rx attenuation */1060		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,1061				AR5K_PHY_GAIN_TXRX_ATTEN,1062				ee->ee_atn_tx_rx[ee_mode]);1063 1064		/* ADC/PGA desired size */1065		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,1066				AR5K_PHY_DESIRED_SIZE_ADC,1067				ee->ee_adc_desired_size[ee_mode]);1068 1069		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,1070				AR5K_PHY_DESIRED_SIZE_PGA,1071				ee->ee_pga_desired_size[ee_mode]);1072 1073		/* Tx/Rx margin */1074		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)1075			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,1076				AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,1077				ee->ee_margin_tx_rx[ee_mode]);1078	}1079 1080	/* XPA delays */1081	ath5k_hw_reg_write(ah,1082		(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |1083		(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |1084		(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |1085		(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);1086 1087	/* XLNA delay */1088	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,1089			AR5K_PHY_RF_CTL3_TXE2XLNA_ON,1090			ee->ee_tx_end2xlna_enable[ee_mode]);1091 1092	/* Thresh64 (ANI) */1093	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,1094			AR5K_PHY_NF_THRESH62,1095			ee->ee_thr_62[ee_mode]);1096 1097	/* False detect backoff for channels1098	 * that have spur noise. Write the new1099	 * cyclic power RSSI threshold. */1100	if (ath5k_hw_chan_has_spur_noise(ah, channel))1101		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,1102				AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,1103				AR5K_INIT_CYCRSSI_THR1 +1104				ee->ee_false_detect[ee_mode]);1105	else1106		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,1107				AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,1108				AR5K_INIT_CYCRSSI_THR1);1109 1110	/* I/Q correction (set enable bit last to match HAL sources) */1111	/* TODO: Per channel i/q infos ? */1112	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {1113		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,1114			    ee->ee_i_cal[ee_mode]);1115		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,1116			    ee->ee_q_cal[ee_mode]);1117		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);1118	}1119 1120	/* Heavy clipping -disable for now */1121	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)1122		ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);1123}1124 1125 1126/*********************\1127* Main reset function *1128\*********************/1129 1130/**1131 * ath5k_hw_reset() - The main reset function1132 * @ah: The &struct ath5k_hw1133 * @op_mode: One of enum nl80211_iftype1134 * @channel: The &struct ieee80211_channel1135 * @fast: Enable fast channel switching1136 * @skip_pcu: Skip pcu initialization1137 *1138 * This is the function we call each time we want to (re)initialize the1139 * card and pass new settings to hw. We also call it when hw runs into1140 * trouble to make it come back to a working state.1141 *1142 * Returns 0 on success, -EINVAL on false op_mode or channel infos, or -EIO1143 * on failure.1144 */1145int1146ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,1147		struct ieee80211_channel *channel, bool fast, bool skip_pcu)1148{1149	u32 s_seq[10], s_led[3], tsf_up, tsf_lo;1150	u8 mode;1151	int i, ret;1152 1153	tsf_up = 0;1154	tsf_lo = 0;1155	mode = 0;1156 1157	/*1158	 * Sanity check for fast flag1159	 * Fast channel change only available1160	 * on AR2413/AR5413.1161	 */1162	if (fast && (ah->ah_radio != AR5K_RF2413) &&1163	(ah->ah_radio != AR5K_RF5413))1164		fast = false;1165 1166	/* Disable sleep clock operation1167	 * to avoid register access delay on certain1168	 * PHY registers */1169	if (ah->ah_version == AR5K_AR5212)1170		ath5k_hw_set_sleep_clock(ah, false);1171 1172	mode = channel->hw_value;1173	switch (mode) {1174	case AR5K_MODE_11A:1175		break;1176	case AR5K_MODE_11G:1177		if (ah->ah_version <= AR5K_AR5211) {1178			ATH5K_ERR(ah,1179				"G mode not available on 5210/5211");1180			return -EINVAL;1181		}1182		break;1183	case AR5K_MODE_11B:1184		if (ah->ah_version < AR5K_AR5211) {1185			ATH5K_ERR(ah,1186				"B mode not available on 5210");1187			return -EINVAL;1188		}1189		break;1190	default:1191		ATH5K_ERR(ah,1192			"invalid channel: %d\n", channel->center_freq);1193		return -EINVAL;1194	}1195 1196	/*1197	 * If driver requested fast channel change and DMA has stopped1198	 * go on. If it fails continue with a normal reset.1199	 */1200	if (fast) {1201		ret = ath5k_hw_phy_init(ah, channel, mode, true);1202		if (ret) {1203			ATH5K_DBG(ah, ATH5K_DEBUG_RESET,1204				"fast chan change failed, falling back to normal reset\n");1205			/* Non fatal, can happen eg.1206			 * on mode change */1207			ret = 0;1208		} else {1209			ATH5K_DBG(ah, ATH5K_DEBUG_RESET,1210				"fast chan change successful\n");1211			return 0;1212		}1213	}1214 1215	/*1216	 * Save some registers before a reset1217	 */1218	if (ah->ah_version != AR5K_AR5210) {1219		/*1220		 * Save frame sequence count1221		 * For revs. after Oahu, only save1222		 * seq num for DCU 0 (Global seq num)1223		 */1224		if (ah->ah_mac_srev < AR5K_SREV_AR5211) {1225 1226			for (i = 0; i < 10; i++)1227				s_seq[i] = ath5k_hw_reg_read(ah,1228					AR5K_QUEUE_DCU_SEQNUM(i));1229 1230		} else {1231			s_seq[0] = ath5k_hw_reg_read(ah,1232					AR5K_QUEUE_DCU_SEQNUM(0));1233		}1234 1235		/* TSF accelerates on AR5211 during reset1236		 * As a workaround save it here and restore1237		 * it later so that it's back in time after1238		 * reset. This way it'll get re-synced on the1239		 * next beacon without breaking ad-hoc.1240		 *1241		 * On AR5212 TSF is almost preserved across a1242		 * reset so it stays back in time anyway and1243		 * we don't have to save/restore it.1244		 *1245		 * XXX: Since this breaks power saving we have1246		 * to disable power saving until we receive the1247		 * next beacon, so we can resync beacon timers */1248		if (ah->ah_version == AR5K_AR5211) {1249			tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);1250			tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);1251		}1252	}1253 1254 1255	/*GPIOs*/1256	s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &1257					AR5K_PCICFG_LEDSTATE;1258	s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);1259	s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);1260 1261 1262	/*1263	 * Since we are going to write rf buffer1264	 * check if we have any pending gain_F1265	 * optimization settings1266	 */1267	if (ah->ah_version == AR5K_AR5212 &&1268	(ah->ah_radio <= AR5K_RF5112)) {1269		if (!fast && ah->ah_rf_banks != NULL)1270				ath5k_hw_gainf_calibrate(ah);1271	}1272 1273	/* Wakeup the device */1274	ret = ath5k_hw_nic_wakeup(ah, channel);1275	if (ret)1276		return ret;1277 1278	/* PHY access enable */1279	if (ah->ah_mac_srev >= AR5K_SREV_AR5211)1280		ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));1281	else1282		ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,1283							AR5K_PHY(0));1284 1285	/* Write initial settings */1286	ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);1287	if (ret)1288		return ret;1289 1290	/* Initialize core clock settings */1291	ath5k_hw_init_core_clock(ah);1292 1293	/*1294	 * Tweak initval settings for revised1295	 * chipsets and add some more config1296	 * bits1297	 */1298	ath5k_hw_tweak_initval_settings(ah, channel);1299 1300	/* Commit values from EEPROM */1301	ath5k_hw_commit_eeprom_settings(ah, channel);1302 1303 1304	/*1305	 * Restore saved values1306	 */1307 1308	/* Seqnum, TSF */1309	if (ah->ah_version != AR5K_AR5210) {1310		if (ah->ah_mac_srev < AR5K_SREV_AR5211) {1311			for (i = 0; i < 10; i++)1312				ath5k_hw_reg_write(ah, s_seq[i],1313					AR5K_QUEUE_DCU_SEQNUM(i));1314		} else {1315			ath5k_hw_reg_write(ah, s_seq[0],1316				AR5K_QUEUE_DCU_SEQNUM(0));1317		}1318 1319		if (ah->ah_version == AR5K_AR5211) {1320			ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);1321			ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);1322		}1323	}1324 1325	/* Ledstate */1326	AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);1327 1328	/* Gpio settings */1329	ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);1330	ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);1331 1332	/*1333	 * Initialize PCU1334	 */1335	ath5k_hw_pcu_init(ah, op_mode);1336 1337	/*1338	 * Initialize PHY1339	 */1340	ret = ath5k_hw_phy_init(ah, channel, mode, false);1341	if (ret) {1342		ATH5K_ERR(ah,1343			"failed to initialize PHY (%i) !\n", ret);1344		return ret;1345	}1346 1347	/*1348	 * Configure QCUs/DCUs1349	 */1350	ret = ath5k_hw_init_queues(ah);1351	if (ret)1352		return ret;1353 1354 1355	/*1356	 * Initialize DMA/Interrupts1357	 */1358	ath5k_hw_dma_init(ah);1359 1360 1361	/*1362	 * Enable 32KHz clock function for AR5212+ chips1363	 * Set clocks to 32KHz operation and use an1364	 * external 32KHz crystal when sleeping if one1365	 * exists.1366	 * Disabled by default because it is also disabled in1367	 * other drivers and it is known to cause stability1368	 * issues on some devices1369	 */1370	if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 &&1371	    op_mode != NL80211_IFTYPE_AP)1372		ath5k_hw_set_sleep_clock(ah, true);1373 1374	/*1375	 * Disable beacons and reset the TSF1376	 */1377	AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);1378	ath5k_hw_reset_tsf(ah);1379	return 0;1380}1381