linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
To: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Cc: "John W. Linville" <linville@tuxdriver.com>,
	<linux-wireless@vger.kernel.org>,
	Rodriguez Luis <rodrigue@qca.qualcomm.com>,
	<ath9k-devel@lists.ath9k.org>,
	Rajkumar Manoharan <rmanohar@qca.qualcomm.com>,
	<vadivel@qca.qualcomm.com>, <rhu@qca.qualcomm.com>,
	Senthil Balasubramanian <senthilb@qca.qualcomm.com>,
	"Luis R. Rodriguez" <rodrigue@qca.qualcomm.com>
Subject: Re: [PATCH v3 07/10] ath9k_hw: Add hardware code for WoW
Date: Tue, 26 Jun 2012 10:25:30 +0530	[thread overview]
Message-ID: <4FE940C2.7030009@qca.qualcomm.com> (raw)
In-Reply-To: <20456.45480.605936.5196@gargle.gargle.HOWL>

Hi Sujith,

On Tuesday 26 June 2012 12:14 AM, Sujith Manoharan wrote:
> Mohammed Shafi Shajakhan wrote:
>> +static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
>> +{
>> +	struct ath_common *common = ath9k_hw_common(ah);
>> +
>> +	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
>> +
>> +	/* set rx disable bit */
>> +	REG_WRITE(ah, AR_CR, AR_CR_RXD);
>> +
>> +	if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
>> +		ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
>> +			REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
>> +		return;
>> +	} else {
>> +		if (!AR_SREV_9300_20_OR_LATER(ah))
>> +			REG_WRITE(ah, AR_RXDP, 0x0);
>> +	}
>> +
>> +	/* AR9280 WoW has sleep issue, do not set it to sleep */
>> +	if (AR_SREV_9280_20(ah))
>> +		return;
>> +
>> +	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
>> +}
>
> This function needs proper error handling.

not sure, this seem to be ok while I was reviewing. thanks will check it 
out.


>
>> +#define KAL_FRAME_LEN		28
>> +#define KAL_FRAME_TYPE		0x2 /* data frame */
>> +#define KAL_FRAME_SUB_TYPE	0x4 /* null data frame */
>> +#define KAL_DURATION_ID		0x3d
>> +#define KAL_NUM_DATA_WORDS	6
>> +#define KAL_NUM_DESC_WORDS	12
>
> Move these to a header file ?

thought this was going to be used to the below function alone, will 
check it out. thanks.

>
>> +static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
>> +{
>> +	struct ath_common *common = ath9k_hw_common(ah);
>> +	u32 frame_len = KAL_FRAME_LEN;
>> +	u32 tpc = MAX_RATE_POWER;
>> +	u32 antenna_mode = 1;
>> +	u32 transmit_rate;
>> +	u32 frame_type = KAL_FRAME_TYPE; /* frame type ->  data */
>> +	u32 sub_type = KAL_FRAME_SUB_TYPE; /* subtype ->  NULL data */
>> +	u32 to_ds = 1;
>> +	u32 duration_id = KAL_DURATION_ID;
>> +	u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
>> +	u32 ctl[13] = {0};
>> +	u32 data_word[KAL_NUM_DATA_WORDS];
>> +	u8 i;
>> +	u32 wow_ka_data_word0;
>
> Most of the variables can be replaced by direct usage of the macros.

thanks will check it out.

>
>> +	memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
>> +	memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
>
> These too, the variables from 'common' can be used directly.

ok. i thought it would be more readable by using the sta_mac_addr, 
ap_mac_addr, where these are used in data words, for constructing keep 
alive frames(source address, destination address).

>
>> +	if (ah->curchan->channelFlags&  CHANNEL_CCK)
>> +		transmit_rate = 0x1b; /* CCK_1M hardware value for this rate */
>> +	else
>> +		transmit_rate = 0xb; /* OFDM_6M hardware value for this rate */
>
> We don't use CHANNEL_CCK, so this can be trimmed and 'transmit_rate' removed.

ok will check this out.

>
>> +void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
>> +				u8 *user_mask, int pattern_count,
>> +				int pattern_len)
>> +{
>> +	int i;
>> +	u32 pattern_val, mask_val;
>> +	u32 set, clr;
>> +
>> +	/* FIXME: should check count by querying the hardware capability */
>> +	if (pattern_count>= MAX_NUM_PATTERN)
>> +		return;
>> +
>> +	REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
>> +
>> +	/* set the registers for pattern */
>> +	for (i = 0; i<  MAX_PATTERN_SIZE; i += 4) {
>> +		memcpy(&pattern_val, user_pattern, 4);
>> +		REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
>> +			  pattern_val);
>> +		user_pattern += 4;
>> +	}
>> +
>> +	/* set the registers for mask */
>> +	for (i = 0; i<  MAX_PATTERN_SIZE; i += 4) {
>> +		memcpy(&mask_val, user_mask, 4);
>> +		REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
>> +		user_mask += 4;
>> +	}
>
> Shouldn't this use MAX_PATTERN_MASK_SIZE ? Also, better error checking for this
> function.

thanks, i missed it. will change this.

>
>> +	set = AR_PMCTRL_WOW_PME_CLR;
>> +	clr = AR_PMCTRL_PWR_STATE_D1D3;
>> +	/* do we need to check the bit value 0x01000000 (7-10) ?? */
>> +	REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
>> +
>> +	/*
>> +	 * clear all events
>> +	 */
>> +	REG_WRITE(ah, AR_WOW_PATTERN,
>> +		  AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
>> +
>> +	/*
>> +	 * tie reset register for AR9002 family of chipsets
>> +	 * NB: not tieing it back might have some repurcussions.
>> +	 */
>> +
>> +	if (!AR_SREV_9300_20_OR_LATER(ah)) {
>> +		set = AR_WA_UNTIE_RESET_EN |
>> +		      AR_WA_POR_SHORT |
>> +		      AR_WA_RESET_EN;
>> +		REG_SET_BIT(ah, AR_WA, set);
>> +	}
>
> What's the point in the set/clr variables ?

this is being to done to use REG_RMW_* and REG_SET_BIT* with a quite
few of values being set or cleared. I would just see if i have a better 
option.

>
>> +	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
>
> This doesn't seem right, you are overwriting the value that is set when a
> station is associated.


thanks, i was thinking how can i bring in
  REG_RMW_FIELD(ah, AR_RSSI_THR,
                       AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
i believe we would do a re-connection and update the same value. will 
check it out. i think it would be 7 or 5.

>
>> +void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
>> +{
>> +	/*
>> +	 * set the power states appropriately and enable PME
>> +	 */
>> +	set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
>> +	      AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
>> +
>> +	/*
>> +	 * set and clear WOW_PME_CLEAR registers for the chip
>> +	 * to generate next wow signal.
>> +	 */
>> +	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
>> +	clr = AR_PMCTRL_WOW_PME_CLR;
>> +	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
>> +
>> +	/*
>> +	 * Setup for:
>> +	 *	- beacon misses
>> +	 *	- magic pattern
>> +	 *	- keep alive timeout
>> +	 *	- pattern matching
>> +	 */
>> +
>> +	/*
>> +	 * Program default values for pattern backoff, aifs/slot/KAL count,
>> +	 * beacon miss timeout, KAL timeout, etc.
>> +	 */
>> +
>> +	set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
>> +	REG_SET_BIT(ah, AR_WOW_PATTERN, set);
>> +
>> +	set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
>> +	      AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
>> +	      AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
>> +	REG_SET_BIT(ah, AR_WOW_COUNT, set);
>> +
>> +	if (pattern_enable&  AH_WOW_BEACON_MISS)
>> +		set = AR_WOW_BEACON_TIMO;
>> +	/* We are not using beacon miss, program a large value */
>> +	else
>> +		set = AR_WOW_BEACON_TIMO_MAX;
>> +
>> +	REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
>> +
>> +	/*
>> +	 * Keep alive timo in ms except AR9280
>> +	 */
>> +	if (!pattern_enable || AR_SREV_9280(ah))
>> +		set = AR_WOW_KEEP_ALIVE_NEVER;
>> +	else
>> +		set = KAL_TIMEOUT * 32;
>> +
>> +	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
>> +
>> +	/*
>> +	 * Keep alive delay in us. based on 'power on clock',
>> +	 * therefore in usec
>> +	 */
>> +	set = KA_DELAY * 1000;
>> +	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
>> +
>> +	/*
>> +	 * Create keep alive pattern to respond to beacons
>> +	 */
>> +	ath9k_wow_create_keep_alive_pattern(ah);
>> +
>> +	/*
>> +	 * Configure MAC WoW Registers
>> +	 */
>> +
>> +	set = 0;
>> +	/* Send keep alive timeouts anyway */
>> +	clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
>> +
>> +	if (pattern_enable&  AH_WOW_LINK_CHANGE)
>> +		wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
>> +	else
>> +		set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
>> +
>> +	/*
>> +	 * FIXME: For now disable keep alive frame
>> +	 * failure. This seems to sometimes trigger
>> +	 * unnecessary wake up with AR9485 chipsets.
>> +	 */
>> +	set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
>> +
>> +	REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
>> +
>> +
>> +	/*
>> +	 * we are relying on a bmiss failure. ensure we have
>> +	 * enough threshold to prevent false positives
>> +	 */
>> +	REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
>> +		      AR_WOW_BMISSTHRESHOLD);
>> +
>> +	set = 0;
>> +	clr = 0;
>> +
>> +	if (pattern_enable&  AH_WOW_BEACON_MISS) {
>> +		set = AR_WOW_BEACON_FAIL_EN;
>> +		wow_event_mask |= AR_WOW_BEACON_FAIL;
>> +	} else {
>> +		clr = AR_WOW_BEACON_FAIL_EN;
>> +	}
>> +
>> +	REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
>> +
>> +	set = 0;
>> +	clr = 0;
>> +	/*
>> +	 * Enable the magic packet registers
>> +	 */
>> +	if (pattern_enable&  AH_WOW_MAGIC_PATTERN_EN) {
>> +		set = AR_WOW_MAGIC_EN;
>> +		wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
>> +	} else {
>> +		clr = AR_WOW_MAGIC_EN;
>> +	}
>> +	set |= AR_WOW_MAC_INTR_EN;
>> +	REG_RMW(ah, AR_WOW_PATTERN, set, clr);
>> +
>> +	/*
>> +	 * For AR9285 and later version of chipsets
>> +	 * enable WoW pattern match for packets less
>> +	 * than 256 bytes for all patterns
>> +	 */
>> +	if (AR_SREV_9285_12_OR_LATER(ah))
>> +		REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
>> +			  AR_WOW_PATTERN_SUPPORTED);
>> +
>> +	/*
>> +	 * Set the power states appropriately and enable PME
>> +	 */
>> +	clr = 0;
>> +	set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
>> +	      AR_PMCTRL_PWR_PM_CTRL_ENA;
>> +	/*
>> +	 * This is needed for AR9300 chipsets to wake-up
>> +	 * the host.
>> +	 */
>> +	if (AR_SREV_9300_20_OR_LATER(ah))
>> +		clr = AR_PCIE_PM_CTRL_ENA;
>> +
>> +	REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
>> +
>> +	if (AR_SREV_9462(ah)) {
>> +		/*
>> +		 * this is needed to prevent the chip waking up
>> +		 * the host within 3-4 seconds with certain
>> +		 * platform/BIOS. the fix it to enable
>> +		 * D1&  D3 to match original definition and
>> +		 * also match the OTP value. Anyway this
>> +		 * is more related to SW WOW.
>> +		 */
>> +		clr = AR_PMCTRL_PWR_STATE_D1D3;
>> +		REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
>> +
>> +		set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
>> +		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
>> +	}
>> +
>> +
>> +
>> +	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
>> +
>> +	if (AR_SREV_9300_20_OR_LATER(ah)) {
>> +		/* to bring down WOW power low margin */
>> +		set = BIT(13);
>> +		REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
>> +		/* HW WoW */
>> +		clr = BIT(5);
>> +		REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
>> +	}
>> +
>> +	ath9k_hw_set_powermode_wow_sleep(ah);
>> +	ah->wow_event_mask = wow_event_mask;
>> +}
>> +EXPORT_SYMBOL(ath9k_hw_wow_enable);
>
> This function badly needs a cleanup. The set/clr variables are kinda ugly and
> the routine would become quite simpler if the various registers are programmed
> directly.

will check it out if it can be done better.


>
> Sujith


-- 
thanks,
shafi

  reply	other threads:[~2012-06-26  4:55 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-25 14:12 [PATCH v3 00/10] Add support for WOW in ath9k Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 01/10] ath9k_hw: Add register definitions for WoW support Mohammed Shafi Shajakhan
2012-06-25 17:19   ` Sujith Manoharan
2012-06-26  4:28     ` Mohammed Shafi Shajakhan
2012-07-07 11:46       ` Mohammed Shafi
2012-06-25 14:12 ` [PATCH v3 02/10] ath9k: Add definitions and structures to support WoW Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 03/10] ath9k_hw: Add WoW hardware capability flags Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 04/10] ath9k_hw: advertise WoW support for capable chipsets Mohammed Shafi Shajakhan
2012-06-25 17:24   ` Sujith Manoharan
2012-06-26  4:34     ` Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 05/10] ath9k: advertise supported WoW flags to upper layer Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 06/10] ath9k_hw: INI changes for WoW for AR9002 chipsets Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 07/10] ath9k_hw: Add hardware code for WoW Mohammed Shafi Shajakhan
2012-06-25 18:44   ` Sujith Manoharan
2012-06-26  4:55     ` Mohammed Shafi Shajakhan [this message]
2012-06-25 14:12 ` [PATCH v3 08/10] ath: Add Wake-on-Wireless debug mask Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 09/10] ath9k: Add WoW related mac80211 callbacks Mohammed Shafi Shajakhan
2012-06-25 19:21   ` Sujith Manoharan
2012-06-26  5:24     ` Mohammed Shafi Shajakhan
2012-06-26  6:50       ` Johannes Berg
2012-06-26  7:28         ` Mohammed Shafi Shajakhan
2012-06-25 14:12 ` [PATCH v3 10/10] ath9k: do not disable hardware while wow is enabled Mohammed Shafi Shajakhan
2012-07-06 19:35 ` [PATCH v3 00/10] Add support for WOW in ath9k John W. Linville
2012-07-07  9:30   ` Mohammed Shafi Shajakhan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4FE940C2.7030009@qca.qualcomm.com \
    --to=mohammed@qca.qualcomm.com \
    --cc=ath9k-devel@lists.ath9k.org \
    --cc=c_manoha@qca.qualcomm.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=rhu@qca.qualcomm.com \
    --cc=rmanohar@qca.qualcomm.com \
    --cc=rodrigue@qca.qualcomm.com \
    --cc=senthilb@qca.qualcomm.com \
    --cc=vadivel@qca.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).