Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] cfg80211: allow scanning on specified frequencies when using wext-compatibility
From: Holger Schurig @ 2009-09-09 11:09 UTC (permalink / raw)
  To: John W Linville, linux-wireless, Johannes Berg

Handles the case when SIOCSIWSCAN specified iw_scan_req.num_channels and
iw_scan_req.channels[].

Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>

Index: linux-wl/net/wireless/scan.c
===================================================================
--- linux-wl.orig/net/wireless/scan.c	2009-09-09 10:38:58.000000000 +0200
+++ linux-wl/net/wireless/scan.c	2009-09-09 11:59:39.000000000 +0200
@@ -607,6 +607,9 @@ int cfg80211_wext_siwscan(struct net_dev
 	if (!netif_running(dev))
 		return -ENETDOWN;
 
+	if (wrqu->data.length == sizeof(struct iw_scan_req))
+		wreq = (struct iw_scan_req *)extra;
+
 	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
 
 	if (IS_ERR(rdev))
@@ -619,9 +622,14 @@ int cfg80211_wext_siwscan(struct net_dev
 
 	wiphy = &rdev->wiphy;
 
-	for (band = 0; band < IEEE80211_NUM_BANDS; band++)
-		if (wiphy->bands[band])
-			n_channels += wiphy->bands[band]->n_channels;
+	/* Determine number of channels, needed to allocate creq */
+	if (wreq && wreq->num_channels)
+		n_channels = wreq->num_channels;
+	else {
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+			if (wiphy->bands[band])
+				n_channels += wiphy->bands[band]->n_channels;
+	}
 
 	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
 		       n_channels * sizeof(void *),
@@ -638,22 +646,41 @@ int cfg80211_wext_siwscan(struct net_dev
 	creq->n_channels = n_channels;
 	creq->n_ssids = 1;
 
-	/* all channels */
+	/* translate "Scan on frequencies" request */
 	i = 0;
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		int j;
 		if (!wiphy->bands[band])
 			continue;
 		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+
+			/* If we have a wireless request structure and the
+			 * wireless request specifies frequencies, then search
+			 * for the matching hardware channel.
+			 */
+			if (wreq && wreq->num_channels) {
+				int k;
+				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
+				for (k = 0; k < wreq->num_channels; k++) {
+					int wext_freq = wreq->channel_list[k].m / 100000;
+					if (wext_freq == wiphy_freq)
+						goto wext_freq_found;
+				}
+				goto wext_freq_not_found;
+			}
+
+		wext_freq_found:
 			creq->channels[i] = &wiphy->bands[band]->channels[j];
 			i++;
+		wext_freq_not_found: ;
 		}
 	}
 
-	/* translate scan request */
-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
-		wreq = (struct iw_scan_req *)extra;
+	/* Set real number of channels specified in creq->channels[] */
+	creq->n_channels = i;
 
+	/* translate "Scan for SSID" request */
+	if (wreq) {
 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
 				return -EINVAL;

^ permalink raw reply

* Re: AP: ath5k + hostapd occasionally sulks
From: Bob Copeland @ 2009-09-09 13:00 UTC (permalink / raw)
  To: Philip Prindeville, jon.fairbairn; +Cc: linux-wireless
In-Reply-To: <4AA69A0D.3040608@redfish-solutions.com>

On Tue, Sep 8, 2009 at 1:53 PM, Philip Prindeville
<philipp_subx@redfish-solutions.com> wrote:
> I pulled compat-wireless from GIT last night (or about 1:30am mountain,
> really) and rebuilt a 2.6.27.29 kernel.
>
> I'm seeing a lot of:
>
> Sep  8 11:44:09 pbx user.err kernel: ath5k phy0: no further txbuf available, dropping packet
>
>
> one every 10 seconds, in fact.  This is with an Engenius EMP-8062+ card:

Ok, the timing information is useful.  This is probably something (beacon
sending?) racing with the periodic calibration, which temporarily stops
all of the tx traffic and frees the tx buffers, then starts it all up
again.  In short, apart from the logging this shouldn't cause any
problems, but we should probably disable the beacon tasklet during this
time.

If this only appeared all of a sudden in recent compat snapshots, it
would be useful to know the last one that worked normally.

> I'll probably have to reboot regularly, since this is on an embedded box
> with limited CF filesystem, and I can't overflow my /var partition...

Ouch.  For now, just take it out or demote it to debug.

As for the original problem, I don't know offhand why a large download
would trigger a cascade of these errors.  The best way to track it down
is to try to come up with a case that reproduces it and sprinkle printks
throughout the driver, especially when we free and allocate the tx
buffers.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Mel Gorman @ 2009-09-09 15:04 UTC (permalink / raw)
  To: Larry Finger
  Cc: John W. Linville, Pekka Enberg, Frans Pop, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl
In-Reply-To: <4AA67139.80301@lwfinger.net>

On Tue, Sep 08, 2009 at 09:59:05AM -0500, Larry Finger wrote:
> John W. Linville wrote:
> > On Tue, Sep 08, 2009 at 02:11:35PM +0300, Pekka Enberg wrote:
> >> On Tue, Sep 8, 2009 at 1:54 PM, Mel Gorman<mel@csn.ul.ie> wrote:
> >>> My feeling is also that a number of these page allocation failures have
> >>> been related to wireless drivers. Is that accurate? If so, have there
> >>> been changes made to the wireless stack in this cycle that would have
> >>> increased the order of pages allocated?
> >> That's my general feeling as well. We have linux-wireless CC'd so
> >> maybe this rings a bell for them.
> > 
> > AFAIK, this is only the second separate report.  The other related
> > to ipw2200, which actually shares no code with the iwlagn driver and
> > is not based on the mac80211 stack.
> 
> A previous issue concerned the interaction between wireless and SLUB
> debugging that caused O(0) allocations to get bumped to O(1), but that

Ok, but now they are getting bumped to order-2 because that is the allocation
failure that's happening here. That's pretty risky for a __GFP_HIGH|__GFP_COMP
allocation - i.e. high-priority and atomic allocation.

> was not relevant to this case either. I'm not aware of any other page
> allocation problems with wireless.
> 

Are atomic order-2 allocations really expected in wireless or has something
else changed recently? Other than slub-debug, what options have been
recently added that can push kmalloc() requests up slightly and possible
make an order-1 allocation an order-2? If it's not in wireless, has there
been additional padding added to skbuffs in the networking layer that might
have pushed an allocation over an order-1 boundary increasing the size of
the allocation to order-2?

The reporter says that the machine grinds for a bit and recovers which
is consistent with kswapd kicking in to reclaim the contiguous pages but
it's hardly desirable.

Franz, in the full dmesg was there any mention of "SLUB: Unable to allocate
memory on node"? If so, could you post the contents of that as well because
it should tell us more about the slab allocation that failed which vaguely
looks like the path that went splat. Also, did you have any slub debug
options enabled on the command line?

Thanks

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Frans Pop @ 2009-09-09 15:59 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Larry Finger, John W. Linville, Pekka Enberg, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl
In-Reply-To: <20090909150418.GI24614@csn.ul.ie>

On Wednesday 09 September 2009, Mel Gorman wrote:
> Franz, in the full dmesg was there any mention of "SLUB: Unable to
> allocate memory on node"?

No, nothing at all. I double checked the kernel log, but it was completely 
quiet in the hours before and after the messages I already posted.

> Also, did you have any slub debug options enabled on the command line?

Nope.

Cheers,
FJP

^ permalink raw reply

* wireless/sme.c:617 __cfg80211_disconnected I still get these daily
From: ASIC Felix @ 2009-09-09 16:03 UTC (permalink / raw)
  To: linux-wireless, Johannes Berg; +Cc: Luis R. Rodriguez

Hi,

I still get these daily.

Thinkpad T43,
phy0: Atheros AR9280 MAC/BB Rev:2 AR5133 RF Rev:d0: mem=0xfa360000, irq=21

kernel: linville master-2009-09-08 2.6.31-rc9-wl-36500-g918dc92 

auth: WPA-EAP   PEAP

Best regards,
Felix

Sep  9 08:46:01 darkslate CROND[14154]: (root) CMD (   /usr/share/msec/promisc_check.sh)
Sep  9 08:46:22 darkslate klogd: ------------[ cut here ]------------
Sep  9 08:46:22 darkslate klogd: WARNING: at net/wireless/sme.c:617 __cfg80211_disconnected+0x1ff/0x210 [cfg80211]()
Sep  9 08:46:22 darkslate klogd: Hardware name: 1875DLU
Sep  9 08:46:22 darkslate klogd: deauth failed: -67
Sep  9 08:46:22 darkslate klogd: Modules linked in: xt_time xt_connlimit xt_realm iptable_raw xt_comment ipt_ULOG ipt_REJECT ipt_REDIRECT ipt_NETMAP ipt_MASQUERADE ipt_LOG ipt_ECN ipt_ecn ipt_ah ipt_addrtype nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda ts_kmp nf_conntrack_amanda nf_conntrack_tftp nf_conntrack_sip nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nf_conntrack_netbios_ns nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp xt_tcpmss xt_recent xt_pkttype xt_physdev xt_owner xt_NFQUEUE xt_NFLOG nfnetlink_log xt_multiport xt_MARK xt_mark xt_mac xt_limit xt_length xt_iprange xt_helper xt_hashlimit xt_DSCP xt_dscp xt_dccp xt_conntrack xt_CONNMARK xt_connmark xt_CLASSIFY xt_tcpudp xt_state iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack iptable_mangle nfnetlink iptable_filter ip_tables x_tables i915 drm i2c_algo_bit aes_i586 aes_generic af_packet bridge stp llc bnep sco rfcomm l2cap bluetooth binfmt_misc 
Sep  9 08:46:22 darkslate klogd: oop fuse cpufreq_ondemand cpufreq_conservative cpufreq_powersave acpi_cpufreq freq_table arc4 ecb ath9k mac80211 ath cfg80211 thinkpad_acpi rfkill video tg3 joydev led_class evdev output nsc_ircc irda ehci_hcd crc_ccitt i2c_i801 i2c_core uhci_hcd intel_agp rtc_cmos sr_mod libphy sg iTCO_wdt iTCO_vendor_support pcspkr yenta_socket rsrc_nonstatic button agpgart thermal ac processor battery pcmcia_core nvram usbcore ata_generic ide_pci_generic ide_gd_mod ide_core pata_acpi ata_piix ahci libata sd_mod scsi_mod crc_t10dif ext3 jbd
Sep  9 08:46:22 darkslate klogd: Pid: 1142, comm: phy0 Tainted: G        W  2.6.31-rc9-wl-mnbStrip-36500-g918dc92 #77
Sep  9 08:46:22 darkslate klogd: Call Trace:
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<c0138d9c>] warn_slowpath_common+0x6c/0xc0
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<c0138e36>] warn_slowpath_fmt+0x26/0x30
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f8910262>] ? nl80211_send_deauth+0x22/0x30 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f8911463>] __cfg80211_send_deauth+0x213/0x260 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89ea7a3>] ? __sta_info_free+0x33/0x40 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f89ea9d3>] ? sta_info_destroy+0xf3/0x100 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f89f1384>] ? ieee80211_set_disassoc+0x174/0x1d0 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f891150e>] cfg80211_send_deauth+0x5e/0x70 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89f2f31>] ieee80211_sta_work+0x901/0x1820 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<c0134ca1>] ? update_curr+0x1b1/0x1c0
Sep  9 08:46:22 darkslate klogd:  [<c013502d>] ? dequeue_task_fair+0x29d/0x2b0
Sep  9 08:46:22 darkslate klogd:  [<c010254d>] ? __switch_to+0xad/0x1a0
Sep  9 08:46:22 darkslate klogd:  [<c012a10f>] ? set_next_entity+0x11f/0x1b0
Sep  9 08:46:22 darkslate klogd:  [<c03a3c65>] ? schedule+0x495/0xa40
Sep  9 08:46:22 darkslate klogd:  [<c014fbea>] ? prepare_to_wait+0x3a/0x70
Sep  9 08:46:22 darkslate klogd:  [<c014b178>] worker_thread+0x148/0x210
Sep  9 08:46:22 darkslate klogd:  [<f89f2630>] ? ieee80211_sta_work+0x0/0x1820 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<c014f9a0>] ? autoremove_wake_function+0x0/0x50
Sep  9 08:46:22 darkslate klogd:  [<c014b030>] ? worker_thread+0x0/0x210
Sep  9 08:46:22 darkslate klogd:  [<c014f644>] kthread+0x84/0x90
Sep  9 08:46:22 darkslate klogd:  [<c014f5c0>] ? kthread+0x0/0x90
Sep  9 08:46:22 darkslate klogd:  [<c0104667>] kernel_thread_helper+0x7/0x10
Sep  9 08:46:22 darkslate klogd: ---[ end trace 46565fb73d858208 ]---
Sep  9 08:46:22 darkslate ifplugd(wlan0)[30335]: Link beat lost.
Sep  9 08:46:22 darkslate klogd: ------------[ cut here ]------------
Sep  9 08:46:22 darkslate klogd: WARNING: at net/wireless/sme.c:617 __cfg80211_disconnected+0x1ff/0x210 [cfg80211]()
Sep  9 08:46:22 darkslate klogd: Hardware name: 1875DLU
Sep  9 08:46:22 darkslate klogd: deauth failed: -67
Sep  9 08:46:22 darkslate klogd: Modules linked in: xt_time xt_connlimit xt_realm iptable_raw xt_comment ipt_ULOG ipt_REJECT ipt_REDIRECT ipt_NETMAP ipt_MASQUERADE ipt_LOG ipt_ECN ipt_ecn ipt_ah ipt_addrtype nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda ts_kmp nf_conntrack_amanda nf_conntrack_tftp nf_conntrack_sip nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nf_conntrack_netbios_ns nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp xt_tcpmss xt_recent xt_pkttype xt_physdev xt_owner xt_NFQUEUE xt_NFLOG nfnetlink_log xt_multiport xt_MARK xt_mark xt_mac xt_limit xt_length xt_iprange xt_helper xt_hashlimit xt_DSCP xt_dscp xt_dccp xt_conntrack xt_CONNMARK xt_connmark xt_CLASSIFY xt_tcpudp xt_state iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack iptable_mangle nfnetlink iptable_filter ip_tables x_tables i915 drm i2c_algo_bit aes_i586 aes_generic af_packet bridge stp llc bnep sco rfcomm l2cap bluetooth binfmt_misc 
Sep  9 08:46:22 darkslate klogd: oop fuse cpufreq_ondemand cpufreq_conservative cpufreq_powersave acpi_cpufreq freq_table arc4 ecb ath9k mac80211 ath cfg80211 thinkpad_acpi rfkill video tg3 joydev led_class evdev output nsc_ircc irda ehci_hcd crc_ccitt i2c_i801 i2c_core uhci_hcd intel_agp rtc_cmos sr_mod libphy sg iTCO_wdt iTCO_vendor_support pcspkr yenta_socket rsrc_nonstatic button agpgart thermal ac processor battery pcmcia_core nvram usbcore ata_generic ide_pci_generic ide_gd_mod ide_core pata_acpi ata_piix ahci libata sd_mod scsi_mod crc_t10dif ext3 jbd
Sep  9 08:46:22 darkslate klogd: Pid: 1142, comm: phy0 Tainted: G        W  2.6.31-rc9-wl-mnbStrip-36500-g918dc92 #77
Sep  9 08:46:22 darkslate klogd: Call Trace:
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<c0138d9c>] warn_slowpath_common+0x6c/0xc0
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<c0138e36>] warn_slowpath_fmt+0x26/0x30
Sep  9 08:46:22 darkslate klogd:  [<f89134af>] __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f8910262>] ? nl80211_send_deauth+0x22/0x30 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f8911463>] __cfg80211_send_deauth+0x213/0x260 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89ea7a3>] ? __sta_info_free+0x33/0x40 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f89ea9d3>] ? sta_info_destroy+0xf3/0x100 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f89f1384>] ? ieee80211_set_disassoc+0x174/0x1d0 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<f891150e>] cfg80211_send_deauth+0x5e/0x70 [cfg80211]
Sep  9 08:46:22 darkslate klogd:  [<f89f2f31>] ieee80211_sta_work+0x901/0x1820 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<c0134ca1>] ? update_curr+0x1b1/0x1c0
Sep  9 08:46:22 darkslate klogd:  [<c013502d>] ? dequeue_task_fair+0x29d/0x2b0
Sep  9 08:46:22 darkslate klogd:  [<c010254d>] ? __switch_to+0xad/0x1a0
Sep  9 08:46:22 darkslate klogd:  [<c012a10f>] ? set_next_entity+0x11f/0x1b0
Sep  9 08:46:22 darkslate klogd:  [<c03a3c65>] ? schedule+0x495/0xa40
Sep  9 08:46:22 darkslate klogd:  [<c014fbea>] ? prepare_to_wait+0x3a/0x70
Sep  9 08:46:22 darkslate klogd:  [<c014b178>] worker_thread+0x148/0x210
Sep  9 08:46:22 darkslate klogd:  [<f89f2630>] ? ieee80211_sta_work+0x0/0x1820 [mac80211]
Sep  9 08:46:22 darkslate klogd:  [<c014f9a0>] ? autoremove_wake_function+0x0/0x50
Sep  9 08:46:22 darkslate klogd:  [<c014b030>] ? worker_thread+0x0/0x210
Sep  9 08:46:22 darkslate klogd:  [<c014f644>] kthread+0x84/0x90
Sep  9 08:46:22 darkslate klogd:  [<c014f5c0>] ? kthread+0x0/0x90
Sep  9 08:46:22 darkslate klogd:  [<c0104667>] kernel_thread_helper+0x7/0x10
Sep  9 08:46:22 darkslate klogd: ---[ end trace 46565fb73d858208 ]---
Sep  9 08:46:22 darkslate ifplugd(wlan0)[30335]: Link beat lost.
Sep  9 08:46:23 darkslate ifplugd(wlan0)[30335]: Link beat detected.
Sep  9 08:46:23 darkslate ifplugd(wlan0)[30335]: Link beat detected.

dmesg -c
wlan0: deauthenticated from 00:0b:85:6f:12:ac (Reason: 1)
wlan0: direct probe to AP 00:0b:85:6f:20:8c (try 1)
wlan0 direct probe responded
wlan0: authenticate with AP 00:0b:85:6f:20:8c (try 1)
wlan0: authenticated
wlan0: associate with AP 00:0b:85:6f:20:8c (try 1)
wlan0: RX AssocResp from 00:0b:85:6f:20:8c (capab=0x421 status=17 aid=0)
wlan0: AP denied association (code=17)
wlan0: deauthenticating by local choice (reason=3)
wlan0: direct probe to AP 00:0b:85:6f:20:8c (try 1)
wlan0 direct probe responded
wlan0: authenticate with AP 00:0b:85:6f:20:8c (try 1)
wlan0: authenticated
wlan0: associate with AP 00:0b:85:6f:20:8c (try 1)
wlan0: RX AssocResp from 00:0b:85:6f:20:8c (capab=0x431 status=1 aid=16)
wlan0: AP denied association (code=1)
wlan0: direct probe to AP 00:0b:85:6f:12:ac (try 1)
wlan0 direct probe responded
wlan0: authenticate with AP 00:0b:85:6f:12:ac (try 1)
wlan0: authenticated
wlan0: associate with AP 00:0b:85:6f:12:ac (try 1)
wlan0: RX AssocResp from 00:0b:85:6f:12:ac (capab=0x431 status=0 aid=26)
wlan0: associated
wlan0: deauthenticated from 00:0b:85:6f:12:ac (Reason: 1)
wlan0: deauthenticating by local choice (reason=3)
------------[ cut here ]------------
WARNING: at net/wireless/sme.c:617 __cfg80211_disconnected+0x1ff/0x210 [cfg80211]()
Hardware name: 1875DLU
deauth failed: -67
Modules linked in: xt_time xt_connlimit xt_realm iptable_raw xt_comment ipt_ULOG ipt_REJECT ipt_REDIRECT ipt_NETMAP ipt_MASQUERADE ipt_LOG ipt_ECN ipt_ecn ipt_ah ipt_addrtype nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda ts_kmp nf_conntrack_amanda nf_conntrack_tftp nf_conntrack_sip nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nf_conntrack_netbios_ns nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp xt_tcpmss xt_recent xt_pkttype xt_physdev xt_owner xt_NFQUEUE xt_NFLOG nfnetlink_log xt_multiport xt_MARK xt_mark xt_mac xt_limit xt_length xt_iprange xt_helper xt_hashlimit xt_DSCP xt_dscp xt_dccp xt_conntrack xt_CONNMARK xt_connmark xt_CLASSIFY xt_tcpudp xt_state iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack iptable_mangle nfnetlink iptable_filter ip_tables x_tables i915 drm i2c_algo_bit aes_i586 aes_generic af_packet bridge stp llc bnep sco rfcomm l2cap bluetooth binfmt_misc loop fuse cpufreq_ondemand cpufreq_conservative cpufreq_powersave acpi_cpufreq freq_table arc4 ecb ath9k mac80211 ath cfg80211 thinkpad_acpi rfkill video tg3 joydev led_class evdev output nsc_ircc irda ehci_hcd crc_ccitt i2c_i801 i2c_core uhci_hcd intel_agp rtc_cmos sr_mod libphy sg iTCO_wdt iTCO_vendor_support pcspkr yenta_socket rsrc_nonstatic button agpgart thermal ac processor battery pcmcia_core nvram usbcore ata_generic ide_pci_generic ide_gd_mod ide_core pata_acpi ata_piix ahci libata sd_mod scsi_mod crc_t10dif ext3 jbd
Pid: 1142, comm: phy0 Tainted: G        W  2.6.31-rc9-wl-mnbStrip-36500-g918dc92 #77
Call Trace:
 [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
 [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
 [<c0138d9c>] warn_slowpath_common+0x6c/0xc0
 [<f89134af>] ? __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
 [<c0138e36>] warn_slowpath_fmt+0x26/0x30
 [<f89134af>] __cfg80211_disconnected+0x1ff/0x210 [cfg80211]
 [<f8910262>] ? nl80211_send_deauth+0x22/0x30 [cfg80211]
 [<f8911463>] __cfg80211_send_deauth+0x213/0x260 [cfg80211]
 [<f89ea7a3>] ? __sta_info_free+0x33/0x40 [mac80211]
 [<f89ea9d3>] ? sta_info_destroy+0xf3/0x100 [mac80211]
 [<f89f1384>] ? ieee80211_set_disassoc+0x174/0x1d0 [mac80211]
 [<f891150e>] cfg80211_send_deauth+0x5e/0x70 [cfg80211]
 [<f89f2f31>] ieee80211_sta_work+0x901/0x1820 [mac80211]
 [<c0134ca1>] ? update_curr+0x1b1/0x1c0
 [<c013502d>] ? dequeue_task_fair+0x29d/0x2b0
 [<c010254d>] ? __switch_to+0xad/0x1a0
 [<c012a10f>] ? set_next_entity+0x11f/0x1b0
 [<c03a3c65>] ? schedule+0x495/0xa40
 [<c014fbea>] ? prepare_to_wait+0x3a/0x70
 [<c014b178>] worker_thread+0x148/0x210
 [<f89f2630>] ? ieee80211_sta_work+0x0/0x1820 [mac80211]
 [<c014f9a0>] ? autoremove_wake_function+0x0/0x50
 [<c014b030>] ? worker_thread+0x0/0x210
 [<c014f644>] kthread+0x84/0x90
 [<c014f5c0>] ? kthread+0x0/0x90
 [<c0104667>] kernel_thread_helper+0x7/0x10
---[ end trace 46565fb73d858208 ]---
wlan0: direct probe to AP 00:0b:85:6f:12:ac (try 1)
wlan0 direct probe responded
wlan0: authenticate with AP 00:0b:85:6f:12:ac (try 1)
wlan0: authenticated
wlan0: associate with AP 00:0b:85:6f:12:ac (try 1)
wlan0: RX ReassocResp from 00:0b:85:6f:12:ac (capab=0x431 status=0 aid=25)
wlan0: associated

 sometimes no re-connect, until manual /etc/init.d/network restart



^ permalink raw reply

* Re: AP: ath5k + hostapd occasionally sulks
From: Philip Prindeville @ 2009-09-09 16:44 UTC (permalink / raw)
  To: Bob Copeland; +Cc: jon.fairbairn, linux-wireless
In-Reply-To: <b6c5339f0909090600o267ae376o432cb36b912b7c2a@mail.gmail.com>

Bob Copeland wrote:
> On Tue, Sep 8, 2009 at 1:53 PM, Philip Prindeville
> <philipp_subx@redfish-solutions.com> wrote:
>   
>> I pulled compat-wireless from GIT last night (or about 1:30am mountain,
>> really) and rebuilt a 2.6.27.29 kernel.
>>
>> I'm seeing a lot of:
>>
>> Sep  8 11:44:09 pbx user.err kernel: ath5k phy0: no further txbuf available, dropping packet
>>
>>
>> one every 10 seconds, in fact.  This is with an Engenius EMP-8062+ card:
>>     
>
> Ok, the timing information is useful.  This is probably something (beacon
> sending?) racing with the periodic calibration, which temporarily stops
> all of the tx traffic and frees the tx buffers, then starts it all up
> again.  In short, apart from the logging this shouldn't cause any
> problems, but we should probably disable the beacon tasklet during this
> time.
>   

Alas it is causing problems.  I have a Windows 7 client with an Atheros
card (I forget which... it's the mini-PCIe card that comes with Zotac
ION mini-itx motherboards).

I either can't associate, or associate but don't get a DHCP address or
don't pass traffic... I forget which.

I can do more testing tomorrow...
> If this only appeared all of a sudden in recent compat snapshots, it
> would be useful to know the last one that worked normally.
>   

I could walk it backwards, I suppose...  2009-08-23 was definitely
working with an 9K board.

I've not tried it with a 5K board (I'm not at this location very often).


>> I'll probably have to reboot regularly, since this is on an embedded box
>> with limited CF filesystem, and I can't overflow my /var partition...
>>     
>
> Ouch.  For now, just take it out or demote it to debug.
>
> As for the original problem, I don't know offhand why a large download
> would trigger a cascade of these errors.  The best way to track it down
> is to try to come up with a case that reproduces it and sprinkle printks
> throughout the driver, especially when we free and allocate the tx
> buffers.
>
>   


^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Mel Gorman @ 2009-09-09 16:55 UTC (permalink / raw)
  To: Frans Pop
  Cc: Larry Finger, John W. Linville, Pekka Enberg, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <200909091759.33655.elendil@planet.nl>

On Wed, Sep 09, 2009 at 05:59:30PM +0200, Frans Pop wrote:
> On Wednesday 09 September 2009, Mel Gorman wrote:
> > Franz, in the full dmesg was there any mention of "SLUB: Unable to
> > allocate memory on node"?
> 
> No, nothing at all. I double checked the kernel log, but it was completely 
> quiet in the hours before and after the messages I already posted.
> 

Ok, that in itself is unexpected.

Pekka, it looks from the stack trace that the failure is from
__alloc_skb and I am guessing the failure path is around here

        size = SKB_DATA_ALIGN(size);
        data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
                        gfp_mask, node);
        if (!data)
                goto nodata;

Why would the SLUB out-of-memory message not appear? It's hardly
tripping up on printk_ratelimit() is it?

> > Also, did you have any slub debug options enabled on the command line?
> 
> Nope.
> 

Ok, just best to rule it out.

Apologies for the scattershot approach to figuring out where the order-2
failures are coming from and am not familiar at all with the driver.

According to the logs, the card is a 4965 AG so I can only assume the relevant
driver code is iwl4965. Since commit 1ea8739648cfff4027c3db0f4cee5de87bfd3886,
this has enabled by default a module option called amsdu_size_8K. At a glance,
it looks like this will guarantee that at least order-1 allocations will be
required. Assaf and other wireless folks, is that intentional? What are the
consequences of defaulting that to being off?

What might have made this worse is commit
4018517a1a69a85c3d61b20fa02f187b80773137 which intends to fix an RX skb
alignment problem but looks like it would have the side-effect of 8192
byte allocations becoming 8448 byte allocations and kmalloc() having to do
an order-2 allocation instead of order-1. The problem with this theory is
that the patches have been in since Nov 2008 but reports are only showing
up now.  Frans, how sure are you that this is a recent problem? Is it readily
reproducible?

Conceivably a better candidate for this problem is commit
4752c93c30441f98f7ed723001b1a5e3e5619829 introduced in May 2009. If there
are less than RX_QUEUE_SIZE/2 left, it starts replenishing buffers. Mohamed,
is it absolutly necessary it use GFP_ATOMIC there? If an allocation fails,
does it always mean frames are dropped or could it just replenish what it
can and try again later printing a warning only if allocation failures are
resulting in packet loss?

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* Re: wireless/sme.c:617 __cfg80211_disconnected I still get these daily
From: Bob Copeland @ 2009-09-09 17:04 UTC (permalink / raw)
  To: ASIC Felix; +Cc: linux-wireless, Johannes Berg, Luis R. Rodriguez
In-Reply-To: <1252512190.25355.15.camel@darkslate>

On Wed, Sep 9, 2009 at 12:03 PM, ASIC Felix <ic.felix@gmail.com> wrote:
> Hi,
>
> I still get these daily.
>
> Thinkpad T43,
> phy0: Atheros AR9280 MAC/BB Rev:2 AR5133 RF Rev:d0: mem=0xfa360000, irq=21
>
> kernel: linville master-2009-09-08 2.6.31-rc9-wl-36500-g918dc92

Same here...

[ 4692.369907] wlan0: associated
[ 4692.369921] phy0: Allocated STA 00:23:ab:26:4d:80
[ 4692.371064] phy0: Inserted STA 00:23:ab:26:4d:80
[ 4800.046263] wlan0: deauthenticating by local choice (reason=3)
[ 4800.046329] phy0: Removed STA 00:23:ab:26:4d:80
[ 4800.051446] phy0: device now idle
[ 4800.053456] phy0: Destroyed STA 00:23:ab:26:4d:80
[ 4800.053550] wlan0: deauthenticating by local choice (reason=3)
[ 4800.053556] ------------[ cut here ]------------
[ 4800.053573] WARNING: at net/wireless/sme.c:617
__cfg80211_disconnected+0x1c9/0x210 [cfg80211]()
[ 4800.053576] Hardware name: MacBook1,1
[ 4800.053579] deauth failed: -67

Looks like we deauthed twice in a row (no idea why the second one happened)
and that made the sme code unhappy:

		for (i = 0; i < MAX_AUTH_BSSES; i++) {
			if (!wdev->auth_bsses[i])
				continue;
			bssid = wdev->auth_bsses[i]->pub.bssid;
			ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
						WLAN_REASON_DEAUTH_LEAVING);
			WARN(ret, "deauth failed: %d\n", ret);
		}

iw event output (this is wext)... connect failed, then we did deauth
anyway?

1252515598.767300: wlan0 (phy #0): deauth 00:17:f2:43:be:3a ->
00:23:ab:26:4d:80 reason 3: Deauthenticated because sending station is
leaving (or has left) the IBSS or ESS
1252515598.767545: wlan0 (phy #0): disconnected (local request)
1252515598.767663: wlan0 (phy #0): deauth 00:17:f2:43:be:3a ->
00:23:ab:26:4d:80 reason 3: Deauthenticated because sending station is
leaving (or has left) the IBSS or ESS
1252515598.767821: wlan0 (phy #0): failed to connect to
00:23:ab:26:4d:80, status: 1: Unspecified failure
1252515598.770943: wlan0 (phy #0): scan started
1252515598.965265: wlan0 (phy #0): failed to connect, status: 1:
Unspecified failure
1252515598.965425: wlan0 (phy #0): scan finished: 2462,
"\x02\xf4\xb2\xedr\x16\xec\xf3\x01M\xf0\x00\x10\x8bg\xcf\x99P[\x17\x9f\x8e\xd4\x98\x0aa\x03\xd1\xbc\xa7\x0d\xbe"
1252515598.965736: wlan0 (phy #0): scan started
1252515598.965882: wlan0 (phy #0): deauth 00:17:f2:43:be:3a ->
00:23:ab:26:4d:80 reason 3: Deauthenticated because sending station is
leaving (or has left) the IBSS or ESS
1252515598.966042: wlan0 (phy #0): failed to connect to
00:23:ab:26:4d:80, status: 1: Unspecified failure
1252515599.161286: wlan0 (phy #0): scan finished: 2462,
"\x02\xf4\xb2\xedr\x16\xec\xf3\x01M\xf0\x00\x10\x8bg\xcf\x99P[\x17\x9f\x8e\xd4\x98\x0aa\x03\xd1\xbc\xa7\x0d\xbe"
1252515599.167130: wlan0 (phy #0): auth 00:23:ab:26:4d:80 ->
00:17:f2:43:be:3a status: 0: Successful
1252515599.171144: wlan0 (phy #0): assoc 00:23:ab:26:4d:80 ->
00:17:f2:43:be:3a status: 0: Successful
1252515599.171283: wlan0 (phy #0): connected to 00:23:ab:26:4d:80

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Frans Pop @ 2009-09-09 17:19 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Larry Finger, John W. Linville, Pekka Enberg, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <20090909165545.GK24614@csn.ul.ie>

On Wednesday 09 September 2009, you wrote:
> The problem with this theory is that the patches have been in since Nov
> 2008 but reports are only showing up now.  Frans, how sure are you that
> this is a recent problem? Is it readily reproducible?

The only thing I can say here is that I've never seen the issue before 
(and thanks to logcheck I certainly would have).
The laptop is in constant use, but I rarely stress the memory like that. 
Swap is almost always at 0.

I would have to make an effort to try and reproduce it, probably by again 
creating some very large images and loading those in konqueror, maybe 
while streaming a movie over wireless or something.

Thanks for your efforts,
FJP

^ permalink raw reply

* Re: [PATCH] ath5k: do not free irq after resume when card has been removed
From: Thadeu Lima de Souza Cascardo @ 2009-09-09 17:50 UTC (permalink / raw)
  To: Bob Copeland
  Cc: ath5k-devel, linux-wireless, netdev, linux-kernel, lrodriguez,
	mickflemm, jirislaby, linville, johannes
In-Reply-To: <20090909033237.GC13550@hash.localnet>

[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]

On Tue, Sep 08, 2009 at 11:32:37PM -0400, Bob Copeland wrote:
> On Tue, Sep 08, 2009 at 09:52:31PM -0300, Thadeu Lima de Souza Cascardo wrote:
> > ath5k will try to request irq when resuming and fails if the device
> > (like a PCMCIA card) has been removed.
> 
> That's not true, ath5k no longer requests an irq when resuming.
> 

I've just saw there's a commit by you in the next tree that just removes
the irq requesting and releasing in resume/suspend functions.

> > This solves this issue defining a new flag for the status bitmap to
> > indicate when irq has been successfully requested and does not try to
> > release it if not.
> 
> I'd rather not fix it with a status bit.  What kernel is this against?
> 

This is against v2.6.31-rc9, so I get a warning with a version that's
about to get stable. Sorry I am late in the release cycle.

I've used a status bit because the drivers I took a look at did
release/request irq in suspend/resume. I couldn't find a message about
not doing it was the right thing which I thought I saw in the latest
updates to v2.6.31-rcX. I guess it was something just like your commit
which I did see some weeks ago.

Since this is warning, is this worth backporting to rc?

> -- 
> Bob Copeland %% www.bobcopeland.com
> 

Regards,
Cascardo.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] ath5k: do not free irq after resume when card has been removed
From: Bob Copeland @ 2009-09-09 19:31 UTC (permalink / raw)
  To: Thadeu Lima de Souza Cascardo
  Cc: ath5k-devel, linux-wireless, netdev, linux-kernel, lrodriguez,
	mickflemm, jirislaby, linville, johannes
In-Reply-To: <20090909175006.GA7945@vespa.holoscopio.com>

On Wed, Sep 09, 2009 at 02:50:06PM -0300, Thadeu Lima de Souza Cascardo wrote:
> This is against v2.6.31-rc9, so I get a warning with a version that's
> about to get stable. Sorry I am late in the release cycle.

Ok yes, that makes sense then.

> Since this is warning, is this worth backporting to rc?

It's too late probably, but we can send it to stable for 2.6.31.1.

Thank you for the patch by the way, just keep in mind that wireless
patches should be against the wireless-testing kernel in the future.

-- 
Bob Copeland %% www.bobcopeland.com


^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: reinette chatre @ 2009-09-09 20:05 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Frans Pop, Larry Finger, John W. Linville, Pekka Enberg,
	linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
	ipw3945-devel@lists.sourceforge.net, Andrew Morton,
	cl@linux-foundation.org, Krauss, Assaf, Johannes Berg,
	Abbas, Mohamed
In-Reply-To: <20090909165545.GK24614@csn.ul.ie>

Mel and Frans, 

Thank you very much for digging into this.

On Wed, 2009-09-09 at 09:55 -0700, Mel Gorman wrote:
> Conceivably a better candidate for this problem is commit
> 4752c93c30441f98f7ed723001b1a5e3e5619829 introduced in May 2009. If there
> are less than RX_QUEUE_SIZE/2 left, it starts replenishing buffers. Mohamed,
> is it absolutly necessary it use GFP_ATOMIC there? If an allocation fails,
> does it always mean frames are dropped or could it just replenish what it
> can and try again later printing a warning only if allocation failures are
> resulting in packet loss?

I agree that this patch may be the reason we are seeing this issue. We
would like to keep using GFP_ATOMIC here, but it is not necessary for an
allocation failure to be so noisy since the function doing the
allocation (iwl_rx_allocate) is always followed by a call to
iwl_rx_queue_restock which will schedule a refill if the buffers are
running low. We can thus use ___GFP_NOWARN for the allocations in
iwl_rx_allocate and leave it to the restocking to find the needed memory
when it tried its allocations using GFP_KERNEL.

I do think it is useful to let user know about these allocation
failures, even if it does not result in packet loss. Wrapping it in
net_ratelimit() will help though.

How about the patch below?

diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b90adcb..f0ee72e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -252,10 +252,11 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 
 		/* Alloc a new receive buffer */
 		skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
-						priority);
+				priority | __GFP_NOWARN);
 
 		if (!skb) {
-			IWL_CRIT(priv, "Can not allocate SKB buffers\n");
+			if (net_ratelimit())
+				IWL_CRIT(priv, "Can not allocate SKB buffer.\n");
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
 			 * more buffers it will schedule replenish */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 0909668..5d9fb78 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1147,10 +1147,10 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		/* Alloc a new receive buffer */
-		skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
+		skb = alloc_skb(priv->hw_params.rx_buf_size, priority | __GFP_NOWARN);
 		if (!skb) {
 			if (net_ratelimit())
-				IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
+				IWL_CRIT(priv, "Can not allocate SKB buffer.\n");
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
 			 * more buffers it will schedule replenish */



^ permalink raw reply related

* [PATCH 03/15] ath9k: move hw specific btcoex info to ath_hw
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Since we now access it via the ath_hw declare the ath_hw pointer
at the header of some routines and se it. ath9k.h no longer needs to
access btcoex.h and to adjust for this move ath_btcoex_set_weight()
into btcoex.h and instead give main.c a helper for setting initial
values upon drv_start()

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |    2 -
 drivers/net/wireless/ath/ath9k/btcoex.c |   57 +++++++++++++++++--------
 drivers/net/wireless/ath/ath9k/btcoex.h |   14 +-----
 drivers/net/wireless/ath/ath9k/hw.c     |    3 +-
 drivers/net/wireless/ath/ath9k/hw.h     |    7 +++
 drivers/net/wireless/ath/ath9k/main.c   |   70 +++++++++++++++++--------------
 6 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 831874c..e8a630c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -26,7 +26,6 @@
 #include "rc.h"
 #include "debug.h"
 #include "../ath.h"
-#include "btcoex.h"
 
 struct ath_node;
 
@@ -622,7 +621,6 @@ struct ath_softc {
 	struct ath_bus_ops *bus_ops;
 	struct ath_beacon_config cur_beacon_conf;
 	struct delayed_work tx_complete_work;
-	struct ath_btcoex_info btcoex_info;
 	struct ath_btcoex btcoex;
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index e88a0a3..dfbcbd0 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -43,14 +43,29 @@ bool ath_btcoex_supported(u16 subsysid)
 	return false;
 }
 
+static void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
+				  u32 bt_weight,
+				  u32 wlan_weight)
+{
+	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
+}
+
+void ath9k_hw_btcoex_init_weight(struct ath_hw *ah)
+{
+	ath_btcoex_set_weight(&ah->btcoex_info, AR_BT_COEX_WGHT,
+			      AR_STOMP_LOW_WLAN_WGHT);
+}
+
 /*
  * Detects if there is any priority bt traffic
  */
 static void ath_detect_bt_priority(struct ath_softc *sc)
 {
 	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
 
-	if (ath9k_hw_gpio_get(sc->sc_ah, sc->btcoex_info.btpriority_gpio))
+	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_info.btpriority_gpio))
 		btcoex->bt_priority_cnt++;
 
 	if (time_after(jiffies, btcoex->bt_priority_time +
@@ -106,8 +121,9 @@ static void ath_btcoex_bt_stomp(struct ath_softc *sc,
 static void ath_btcoex_period_timer(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
 
 	ath_detect_bt_priority(sc);
 
@@ -119,9 +135,9 @@ static void ath_btcoex_period_timer(unsigned long data)
 
 	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
 		if (btcoex->hw_timer_enabled)
-			ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+			ath_gen_timer_stop(ah, btinfo->no_stomp_timer);
 
-		ath_gen_timer_start(sc->sc_ah,
+		ath_gen_timer_start(ah,
 			btinfo->no_stomp_timer,
 			(ath9k_hw_gettsf32(sc->sc_ah) +
 				btcoex->btcoex_no_stomp),
@@ -141,10 +157,11 @@ static void ath_btcoex_period_timer(unsigned long data)
 static void ath_btcoex_no_stomp_timer(void *arg)
 {
 	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
 
-	DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
+	DPRINTF(ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
@@ -156,14 +173,14 @@ static void ath_btcoex_no_stomp_timer(void *arg)
 	spin_unlock_bh(&btcoex->btcoex_lock);
 }
 
-static int ath_init_btcoex_info(struct ath_hw *hw,
+static int ath_init_btcoex_info(struct ath_hw *ah,
 				struct ath_btcoex_info *btcoex_info)
 {
-	struct ath_btcoex *btcoex = &hw->ah_sc->btcoex;
+	struct ath_btcoex *btcoex = &ah->ah_sc->btcoex;
 	u32 i;
 	int qnum;
 
-	qnum = ath_tx_get_qnum(hw->ah_sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+	qnum = ath_tx_get_qnum(ah->ah_sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
 
 	btcoex_info->bt_coex_mode =
 		(btcoex_info->bt_coex_mode & AR_BT_QCU_THRESH) |
@@ -190,15 +207,15 @@ static int ath_init_btcoex_info(struct ath_hw *hw,
 		btcoex->btcoex_period / 100;
 
 	for (i = 0; i < 32; i++)
-		hw->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
+		ah->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
 
 	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
-			(unsigned long) hw->ah_sc);
+			(unsigned long) ah->ah_sc);
 
-	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(hw,
+	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(ah,
 			ath_btcoex_no_stomp_timer,
 			ath_btcoex_no_stomp_timer,
-			(void *)hw->ah_sc, AR_FIRST_NDP_TIMER);
+			(void *)ah->ah_sc, AR_FIRST_NDP_TIMER);
 
 	if (btcoex_info->no_stomp_timer == NULL)
 		return -ENOMEM;
@@ -210,7 +227,7 @@ static int ath_init_btcoex_info(struct ath_hw *hw,
 
 int ath9k_hw_btcoex_init(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 	int ret = 0;
 
 	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
@@ -258,7 +275,7 @@ int ath9k_hw_btcoex_init(struct ath_hw *ah)
 
 void ath9k_hw_btcoex_enable(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
 	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
 		/* Configure the desired GPIO port for TX_FRAME output */
@@ -291,7 +308,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
 
 void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
 	ath9k_hw_set_gpio(ah, btcoex_info->wlanactive_gpio, 0);
 
@@ -313,11 +330,12 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 void ath_btcoex_timer_pause(struct ath_softc *sc)
 {
 	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
 
 	del_timer_sync(&btcoex->period_timer);
 
 	if (btcoex->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
+		ath_gen_timer_stop(ah, ah->btcoex_info.no_stomp_timer);
 
 	btcoex->hw_timer_enabled = false;
 }
@@ -328,12 +346,13 @@ void ath_btcoex_timer_pause(struct ath_softc *sc)
 void ath_btcoex_timer_resume(struct ath_softc *sc)
 {
 	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
 
-	DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Starting btcoex timers");
+	DPRINTF(ah, ATH_DBG_BTCOEX, "Starting btcoex timers");
 
 	/* make sure duty cycle timer is also stopped when resuming */
 	if (btcoex->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
+		ath_gen_timer_stop(sc->sc_ah, ah->btcoex_info.no_stomp_timer);
 
 	btcoex->bt_priority_cnt = 0;
 	btcoex->bt_priority_time = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 6cbbc14..12e86b7 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -17,6 +17,8 @@
 #ifndef BTCOEX_H
 #define BTCOEX_H
 
+#include "hw.h"
+
 #define ATH_WLANACTIVE_GPIO	5
 #define ATH_BTACTIVE_GPIO	6
 #define ATH_BTPRIORITY_GPIO	7
@@ -74,19 +76,9 @@ struct ath_btcoex_info {
 };
 
 bool ath_btcoex_supported(u16 subsysid);
+void ath9k_hw_btcoex_init_weight(struct ath_hw *ah);
 int ath9k_hw_btcoex_init(struct ath_hw *ah);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
 
-void ath_btcoex_timer_resume(struct ath_softc *sc);
-void ath_btcoex_timer_pause(struct ath_softc *sc);
-
-static inline void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
-					 u32 bt_weight,
-					 u32 wlan_weight)
-{
-		btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
-				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
-}
-
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 39431c3..9be5587 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -18,6 +18,7 @@
 #include <asm/unaligned.h>
 #include <linux/pci.h>
 
+#include "hw.h"
 #include "ath9k.h"
 #include "initvals.h"
 
@@ -3510,7 +3511,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
 	u16 capField = 0, eeval;
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9106a0b..774dc08 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -27,6 +27,7 @@
 #include "calib.h"
 #include "reg.h"
 #include "phy.h"
+#include "btcoex.h"
 
 #include "../regd.h"
 
@@ -553,6 +554,9 @@ struct ath_hw {
 	int firpwr[5];
 	enum ath9k_ani_cmd ani_function;
 
+	/* Bluetooth coexistance */
+	struct ath_btcoex_info btcoex_info;
+
 	u32 intr_txqs;
 	enum ath9k_ht_extprotspacing extprotspacing;
 	u8 txchainmask;
@@ -675,4 +679,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
 #define ATH_PCIE_CAP_LINK_L1	2
 
 void ath_pcie_aspm_disable(struct ath_softc *sc);
+
+void ath_btcoex_timer_resume(struct ath_softc *sc);
+void ath_btcoex_timer_pause(struct ath_softc *sc);
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 7805323..defbe9f 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -16,6 +16,7 @@
 
 #include <linux/nl80211.h>
 #include "ath9k.h"
+#include "btcoex.h"
 
 static char *dev_info = "ath9k";
 
@@ -439,8 +440,10 @@ static void ath_start_ani(struct ath_softc *sc)
  */
 void ath_update_chainmask(struct ath_softc *sc, int is_ht)
 {
+	struct ath_hw *ah = sc->sc_ah;
+
 	if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
-	    (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) {
+	    (ah->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) {
 		sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
 		sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
 	} else {
@@ -448,7 +451,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
 		sc->rx_chainmask = 1;
 	}
 
-	DPRINTF(sc->sc_ah, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
+	DPRINTF(ah, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
 		sc->tx_chainmask, sc->rx_chainmask);
 }
 
@@ -478,6 +481,8 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
 static void ath9k_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
+	struct ath_hw *ah = sc->sc_ah;
+
 	u32 status = sc->intrstatus;
 
 	ath9k_ps_wakeup(sc);
@@ -502,16 +507,16 @@ static void ath9k_tasklet(unsigned long data)
 		 * TSF sync does not look correct; remain awake to sync with
 		 * the next Beacon.
 		 */
-		DPRINTF(sc->sc_ah, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
+		DPRINTF(ah, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
 		sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
 	}
 
-	if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+	if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
 		if (status & ATH9K_INT_GENTIMER)
 			ath_gen_timer_isr(sc->sc_ah);
 
 	/* re-enable hardware interrupt */
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 	ath9k_ps_restore(sc);
 }
 
@@ -1285,12 +1290,12 @@ void ath_detach(struct ath_softc *sc)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	if ((sc->btcoex_info.no_stomp_timer) &&
-	    sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-		ath_gen_timer_free(ah, sc->btcoex_info.no_stomp_timer);
+	if ((ah->btcoex_info.no_stomp_timer) &&
+	    ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+		ath_gen_timer_free(ah, ah->btcoex_info.no_stomp_timer);
 
 	ath9k_hw_detach(ah);
-	ath9k_exit_debug(sc->sc_ah);
+	ath9k_exit_debug(ah);
 	sc->sc_ah = NULL;
 }
 
@@ -1520,7 +1525,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
 			ARRAY_SIZE(ath9k_5ghz_chantable);
 	}
 
-	if (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) {
+	if (ah->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) {
 		r = ath9k_hw_btcoex_init(ah);
 		if (r)
 			goto bad2;
@@ -1909,11 +1914,12 @@ static int ath9k_start(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ieee80211_channel *curchan = hw->conf.channel;
 	struct ath9k_channel *init_channel;
 	int r;
 
-	DPRINTF(sc->sc_ah, ATH_DBG_CONFIG, "Starting driver with "
+	DPRINTF(ah, ATH_DBG_CONFIG, "Starting driver with "
 		"initial channel: %d MHz\n", curchan->center_freq);
 
 	mutex_lock(&sc->mutex);
@@ -1946,7 +1952,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	init_channel = ath_get_curchannel(sc, hw);
 
 	/* Reset SERDES registers */
-	ath9k_hw_configpcipowersave(sc->sc_ah, 0);
+	ath9k_hw_configpcipowersave(ah, 0);
 
 	/*
 	 * The basic interface to setting the hardware in a good
@@ -1956,9 +1962,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	 * and then setup of the interrupt mask.
 	 */
 	spin_lock_bh(&sc->sc_resetlock);
-	r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+	r = ath9k_hw_reset(ah, init_channel, false);
 	if (r) {
-		DPRINTF(sc->sc_ah, ATH_DBG_FATAL,
+		DPRINTF(ah, ATH_DBG_FATAL,
 			"Unable to reset hardware; reset status %d "
 			"(freq %u MHz)\n", r,
 			curchan->center_freq);
@@ -1981,7 +1987,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	 * here except setup the interrupt mask.
 	 */
 	if (ath_startrecv(sc) != 0) {
-		DPRINTF(sc->sc_ah, ATH_DBG_FATAL, "Unable to start recv logic\n");
+		DPRINTF(ah, ATH_DBG_FATAL, "Unable to start recv logic\n");
 		r = -EIO;
 		goto mutex_unlock;
 	}
@@ -1991,10 +1997,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
 		| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
 		| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
 		sc->imask |= ATH9K_INT_GTT;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
 		sc->imask |= ATH9K_INT_CST;
 
 	ath_cache_conf_rate(sc, &hw->conf);
@@ -2003,20 +2009,19 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
 	/* Disable BMISS interrupt when we're not associated */
 	sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 
 	ieee80211_wake_queues(hw);
 
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 
-	if ((sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) &&
+	if ((ah->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) &&
 	    !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) {
-		ath_btcoex_set_weight(&sc->btcoex_info, AR_BT_COEX_WGHT,
-				      AR_STOMP_LOW_WLAN_WGHT);
-		ath9k_hw_btcoex_enable(sc->sc_ah);
+		ath9k_hw_btcoex_init_weight(ah);
+		ath9k_hw_btcoex_enable(ah);
 
 		ath_pcie_aspm_disable(sc);
-		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+		if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
 			ath_btcoex_timer_resume(sc);
 	}
 
@@ -2129,6 +2134,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
 
 	mutex_lock(&sc->mutex);
 
@@ -2143,7 +2149,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	}
 
 	if (sc->sc_flags & SC_OP_INVALID) {
-		DPRINTF(sc->sc_ah, ATH_DBG_ANY, "Device not present\n");
+		DPRINTF(ah, ATH_DBG_ANY, "Device not present\n");
 		mutex_unlock(&sc->mutex);
 		return;
 	}
@@ -2154,34 +2160,34 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	}
 
 	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
-		ath9k_hw_btcoex_disable(sc->sc_ah);
-		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+		ath9k_hw_btcoex_disable(ah);
+		if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
 			ath_btcoex_timer_pause(sc);
 	}
 
 	/* make sure h/w will not generate any interrupt
 	 * before setting the invalid flag. */
-	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	ath9k_hw_set_interrupts(ah, 0);
 
 	if (!(sc->sc_flags & SC_OP_INVALID)) {
 		ath_drain_all_txq(sc, false);
 		ath_stoprecv(sc);
-		ath9k_hw_phy_disable(sc->sc_ah);
+		ath9k_hw_phy_disable(ah);
 	} else
 		sc->rx.rxlink = NULL;
 
 	wiphy_rfkill_stop_polling(sc->hw->wiphy);
 
 	/* disable HAL and put h/w to sleep */
-	ath9k_hw_disable(sc->sc_ah);
-	ath9k_hw_configpcipowersave(sc->sc_ah, 1);
-	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_hw_disable(ah);
+	ath9k_hw_configpcipowersave(ah, 1);
+	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 
 	sc->sc_flags |= SC_OP_INVALID;
 
 	mutex_unlock(&sc->mutex);
 
-	DPRINTF(sc->sc_ah, ATH_DBG_CONFIG, "Driver halt\n");
+	DPRINTF(ah, ATH_DBG_CONFIG, "Driver halt\n");
 }
 
 static int ath9k_add_interface(struct ieee80211_hw *hw,
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 06/15] ath9k: split ath9k_hw_btcoex_enable() into two helpers
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

One for 2-wire and another for 3-wire.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.c |   57 ++++++++++++++++++++-----------
 1 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 6209a56..61a8e1d 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -117,30 +117,47 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
 }
 
+static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
+
+	/* Configure the desired GPIO port for TX_FRAME output */
+	ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
+
+static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
+
+	/*
+	 * Program coex mode and weight registers to
+	 * enable coex 3-wire
+	 */
+	REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_info->bt_coex_mode);
+	REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_info->bt_coex_weights);
+	REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_info->bt_coex_mode2);
+
+	REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+	REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
+
+	ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+			    AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+}
+
 void ath9k_hw_btcoex_enable(struct ath_hw *ah)
 {
 	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
-		/* Configure the desired GPIO port for TX_FRAME output */
-		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
-				AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
-	} else {
-		/*
-		 * Program coex mode and weight registers to
-		 * enable coex 3-wire
-		 */
-		REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_info->bt_coex_mode);
-		REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_info->bt_coex_weights);
-		REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_info->bt_coex_mode2);
-
-		REG_RMW_FIELD(ah, AR_QUIET1,
-				AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
-		REG_RMW_FIELD(ah, AR_PCU_MISC,
-				AR_PCU_BT_ANT_PREVENT_RX, 0);
-
-		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
-				AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+	switch (btcoex_info->btcoex_scheme) {
+	case ATH_BTCOEX_CFG_NONE:
+		break;
+	case ATH_BTCOEX_CFG_2WIRE:
+		ath9k_hw_btcoex_enable_2wire(ah);
+		break;
+	case ATH_BTCOEX_CFG_3WIRE:
+		ath9k_hw_btcoex_enable_3wire(ah);
+		break;
 	}
 
 	REG_RMW(ah, AR_GPIO_PDPU,
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 02/15] ath9k: move btcoex core driver info to its own struct
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez,
	Vasanthakumar Thiagarajan
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

There is some bluetooth coexistance data which is driver
specific, stuff that into its own structure.

Cc: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |   11 +++++
 drivers/net/wireless/ath/ath9k/btcoex.c |   73 ++++++++++++++++---------------
 drivers/net/wireless/ath/ath9k/btcoex.h |   16 ++-----
 drivers/net/wireless/ath/ath9k/main.c   |    4 +-
 4 files changed, 55 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1d59f10..831874c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -451,6 +451,16 @@ struct ath_ani {
 	struct timer_list timer;
 };
 
+struct ath_btcoex {
+	bool hw_timer_enabled;
+	spinlock_t btcoex_lock;
+	struct timer_list period_timer; /* Timer for BT period */
+	u32 bt_priority_cnt;
+	unsigned long bt_priority_time;
+	u32 btcoex_no_stomp; /* in usec */
+	u32 btcoex_period; /* in usec */
+};
+
 /********************/
 /*   LED Control    */
 /********************/
@@ -613,6 +623,7 @@ struct ath_softc {
 	struct ath_beacon_config cur_beacon_conf;
 	struct delayed_work tx_complete_work;
 	struct ath_btcoex_info btcoex_info;
+	struct ath_btcoex btcoex;
 };
 
 struct ath_wiphy {
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index e19a9c9..e88a0a3 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -48,14 +48,14 @@ bool ath_btcoex_supported(u16 subsysid)
  */
 static void ath_detect_bt_priority(struct ath_softc *sc)
 {
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+	struct ath_btcoex *btcoex = &sc->btcoex;
 
-	if (ath9k_hw_gpio_get(sc->sc_ah, btinfo->btpriority_gpio))
-		btinfo->bt_priority_cnt++;
+	if (ath9k_hw_gpio_get(sc->sc_ah, sc->btcoex_info.btpriority_gpio))
+		btcoex->bt_priority_cnt++;
 
-	if (time_after(jiffies, btinfo->bt_priority_time +
+	if (time_after(jiffies, btcoex->bt_priority_time +
 			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
-		if (btinfo->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
 			DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX,
 				"BT priority traffic detected");
 			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
@@ -63,8 +63,8 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
 			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
 		}
 
-		btinfo->bt_priority_cnt = 0;
-		btinfo->bt_priority_time = jiffies;
+		btcoex->bt_priority_cnt = 0;
+		btcoex->bt_priority_time = jiffies;
 	}
 }
 
@@ -106,29 +106,30 @@ static void ath_btcoex_bt_stomp(struct ath_softc *sc,
 static void ath_btcoex_period_timer(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_btcoex *btcoex = &sc->btcoex;
 	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
 
 	ath_detect_bt_priority(sc);
 
-	spin_lock_bh(&btinfo->btcoex_lock);
+	spin_lock_bh(&btcoex->btcoex_lock);
 
 	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
 
-	spin_unlock_bh(&btinfo->btcoex_lock);
+	spin_unlock_bh(&btcoex->btcoex_lock);
 
-	if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
-		if (btinfo->hw_timer_enabled)
+	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
+		if (btcoex->hw_timer_enabled)
 			ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
 
 		ath_gen_timer_start(sc->sc_ah,
 			btinfo->no_stomp_timer,
 			(ath9k_hw_gettsf32(sc->sc_ah) +
-				btinfo->btcoex_no_stomp),
-				btinfo->btcoex_no_stomp * 10);
-		btinfo->hw_timer_enabled = true;
+				btcoex->btcoex_no_stomp),
+				btcoex->btcoex_no_stomp * 10);
+		btcoex->hw_timer_enabled = true;
 	}
 
-	mod_timer(&btinfo->period_timer, jiffies +
+	mod_timer(&btcoex->period_timer, jiffies +
 				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
 }
 
@@ -140,23 +141,25 @@ static void ath_btcoex_period_timer(unsigned long data)
 static void ath_btcoex_no_stomp_timer(void *arg)
 {
 	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_btcoex *btcoex = &sc->btcoex;
 	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
 
 	DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
 
-	spin_lock_bh(&btinfo->btcoex_lock);
+	spin_lock_bh(&btcoex->btcoex_lock);
 
 	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
 		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
 	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
 		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
 
-	spin_unlock_bh(&btinfo->btcoex_lock);
+	spin_unlock_bh(&btcoex->btcoex_lock);
 }
 
 static int ath_init_btcoex_info(struct ath_hw *hw,
 				struct ath_btcoex_info *btcoex_info)
 {
+	struct ath_btcoex *btcoex = &hw->ah_sc->btcoex;
 	u32 i;
 	int qnum;
 
@@ -181,15 +184,15 @@ static int ath_init_btcoex_info(struct ath_hw *hw,
 
 	btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
 
-	btcoex_info->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
+	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
 
-	btcoex_info->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
-		btcoex_info->btcoex_period / 100;
+	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+		btcoex->btcoex_period / 100;
 
 	for (i = 0; i < 32; i++)
 		hw->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
 
-	setup_timer(&btcoex_info->period_timer, ath_btcoex_period_timer,
+	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
 			(unsigned long) hw->ah_sc);
 
 	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(hw,
@@ -200,7 +203,7 @@ static int ath_init_btcoex_info(struct ath_hw *hw,
 	if (btcoex_info->no_stomp_timer == NULL)
 		return -ENOMEM;
 
-	spin_lock_init(&btcoex_info->btcoex_lock);
+	spin_lock_init(&btcoex->btcoex_lock);
 
 	return 0;
 }
@@ -307,34 +310,34 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 /*
  * Pause btcoex timer and bt duty cycle timer
  */
-void ath_btcoex_timer_pause(struct ath_softc *sc,
-			    struct ath_btcoex_info *btinfo)
+void ath_btcoex_timer_pause(struct ath_softc *sc)
 {
+	struct ath_btcoex *btcoex = &sc->btcoex;
 
-	del_timer_sync(&btinfo->period_timer);
+	del_timer_sync(&btcoex->period_timer);
 
-	if (btinfo->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+	if (btcoex->hw_timer_enabled)
+		ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
 
-	btinfo->hw_timer_enabled = false;
+	btcoex->hw_timer_enabled = false;
 }
 
 /*
  * (Re)start btcoex timers
  */
-void ath_btcoex_timer_resume(struct ath_softc *sc,
-			     struct ath_btcoex_info *btinfo)
+void ath_btcoex_timer_resume(struct ath_softc *sc)
 {
+	struct ath_btcoex *btcoex = &sc->btcoex;
 
 	DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Starting btcoex timers");
 
 	/* make sure duty cycle timer is also stopped when resuming */
-	if (btinfo->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+	if (btcoex->hw_timer_enabled)
+		ath_gen_timer_stop(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
 
-	btinfo->bt_priority_cnt = 0;
-	btinfo->bt_priority_time = jiffies;
+	btcoex->bt_priority_cnt = 0;
+	btcoex->bt_priority_time = jiffies;
 	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
 
-	mod_timer(&btinfo->period_timer, jiffies);
+	mod_timer(&btcoex->period_timer, jiffies);
 }
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 297b027..6cbbc14 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -70,13 +70,6 @@ struct ath_btcoex_info {
 	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
 	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
-	u32 btcoex_no_stomp;   /* in usec */
-	u32 btcoex_period;     	/* in usec */
-	u32 bt_priority_cnt;
-	unsigned long bt_priority_time;
-	bool hw_timer_enabled;
-	spinlock_t btcoex_lock;
-	struct timer_list period_timer;      /* Timer for BT period */
 	struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
 };
 
@@ -84,16 +77,15 @@ bool ath_btcoex_supported(u16 subsysid);
 int ath9k_hw_btcoex_init(struct ath_hw *ah);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
-void ath_btcoex_timer_resume(struct ath_softc *sc,
-			     struct ath_btcoex_info *btinfo);
-void ath_btcoex_timer_pause(struct ath_softc *sc,
-			    struct ath_btcoex_info *btinfo);
+
+void ath_btcoex_timer_resume(struct ath_softc *sc);
+void ath_btcoex_timer_pause(struct ath_softc *sc);
 
 static inline void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
 					 u32 bt_weight,
 					 u32 wlan_weight)
 {
-	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+		btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
 				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5e05e1d..7805323 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2017,7 +2017,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
 		ath_pcie_aspm_disable(sc);
 		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_resume(sc, &sc->btcoex_info);
+			ath_btcoex_timer_resume(sc);
 	}
 
 mutex_unlock:
@@ -2156,7 +2156,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
 		ath9k_hw_btcoex_disable(sc->sc_ah);
 		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_pause(sc, &sc->btcoex_info);
+			ath_btcoex_timer_pause(sc);
 	}
 
 	/* make sure h/w will not generate any interrupt
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 09/15] ath9k: remove unused bt_duty_cycle
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index d932f01..72c613d 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -61,7 +61,6 @@ struct ath_btcoex_info {
 	u8 wlanactive_gpio;
 	u8 btactive_gpio;
 	u8 btpriority_gpio;
-	u8 bt_duty_cycle; 	/* BT duty cycle in percentage */
 	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
 	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 13/15] ath9k: now move ath9k_hw_btcoex_set_weight() to btcoex.c
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

After some necessary cleanups we now move ath9k_hw_btcoex_set_weight()
to where it belongs.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.c |   10 ++++++++++
 drivers/net/wireless/ath/ath9k/btcoex.h |    3 +++
 drivers/net/wireless/ath/ath9k/main.c   |   18 ++----------------
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 0b5a7d4..4cca023 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -124,6 +124,16 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
 			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
 }
 
+void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
+				u32 bt_weight,
+				u32 wlan_weight)
+{
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+
+	btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+				     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
+}
+
 static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 296ddd8..971d200 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -70,6 +70,9 @@ bool ath_btcoex_supported(u16 subsysid);
 void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
 void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
+void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
+				u32 bt_weight,
+				u32 wlan_weight);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c8f2ff6..5a33d01 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1336,21 +1336,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
 	}
 }
 
-static void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
-				       u32 bt_weight,
-				       u32 wlan_weight)
-{
-	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
-
-	btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
-				     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
-}
-
-static void ath9k_hw_btcoex_init_weight(struct ath_hw *ah)
-{
-	ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, AR_STOMP_LOW_WLAN_WGHT);
-}
-
 /*
  * Configures appropriate weight based on stomp type.
  */
@@ -2204,7 +2189,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
 	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
 	    !ah->btcoex_hw.enabled) {
-		ath9k_hw_btcoex_init_weight(ah);
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_LOW_WLAN_WGHT);
 		ath9k_hw_btcoex_enable(ah);
 
 		ath_pcie_aspm_disable(sc);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 14/15] ath9k: move ath_btcoex_config and ath_bt_mode to btcoex.c
From: Luis R. Rodriguez @ 2009-09-09 23:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

These are only used by btcoex.c on one routine, so stuff them
into that file.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.c |   31 +++++++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/btcoex.h |   20 --------------------
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 4cca023..ee2a834 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -16,8 +16,24 @@
 
 #include "ath9k.h"
 
-static const struct ath_btcoex_config ath_bt_config = { 0, true, true,
-			ATH_BT_COEX_MODE_SLOTTED, true, true, 2, 5, true };
+enum ath_bt_mode {
+	ATH_BT_COEX_MODE_LEGACY,        /* legacy rx_clear mode */
+	ATH_BT_COEX_MODE_UNSLOTTED,     /* untimed/unslotted mode */
+	ATH_BT_COEX_MODE_SLOTTED,       /* slotted mode */
+	ATH_BT_COEX_MODE_DISALBED,      /* coexistence disabled */
+};
+
+struct ath_btcoex_config {
+	u8 bt_time_extend;
+	bool bt_txstate_extend;
+	bool bt_txframe_extend;
+	enum ath_bt_mode bt_mode; /* coexistence mode */
+	bool bt_quiet_collision;
+	bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
+	u8 bt_priority_time;
+	u8 bt_first_slot_time;
+	bool bt_hold_rx_clear;
+};
 
 static const u16 ath_subsysid_tbl[] = {
 	AR9280_COEX2WIRE_SUBSYSID,
@@ -46,6 +62,17 @@ bool ath_btcoex_supported(u16 subsysid)
 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+	const struct ath_btcoex_config ath_bt_config = {
+		.bt_time_extend = 0,
+		.bt_txstate_extend = true,
+		.bt_txframe_extend = true,
+		.bt_mode = ATH_BT_COEX_MODE_SLOTTED,
+		.bt_quiet_collision = true,
+		.bt_rxclear_polarity = true,
+		.bt_priority_time = 2,
+		.bt_first_slot_time = 5,
+		.bt_hold_rx_clear = true,
+	};
 	u32 i;
 
 	btcoex_hw->bt_coex_mode =
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 971d200..0dc5120 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -36,25 +36,6 @@ enum ath_btcoex_scheme {
 	ATH_BTCOEX_CFG_3WIRE,
 };
 
-enum ath_bt_mode {
-	ATH_BT_COEX_MODE_LEGACY,	/* legacy rx_clear mode */
-	ATH_BT_COEX_MODE_UNSLOTTED,	/* untimed/unslotted mode */
-	ATH_BT_COEX_MODE_SLOTTED,	/* slotted mode */
-	ATH_BT_COEX_MODE_DISALBED,	/* coexistence disabled */
-};
-
-struct ath_btcoex_config {
-	u8 bt_time_extend;
-	bool bt_txstate_extend;
-	bool bt_txframe_extend;
-	enum ath_bt_mode bt_mode; /* coexistence mode */
-	bool bt_quiet_collision;
-	bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
-	u8 bt_priority_time;
-	u8 bt_first_slot_time;
-	bool bt_hold_rx_clear;
-};
-
 struct ath_btcoex_hw {
 	enum ath_btcoex_scheme scheme;
 	bool enabled;
@@ -76,5 +57,4 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
 
-
 #endif
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 07/15] ath9k: replaces SC_OP_BTCOEX_ENABLED with a bool
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Whether or not bluetooth coex has been enabled is a hardware
state and only the hardware helpers will be able to set this.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |    1 -
 drivers/net/wireless/ath/ath9k/btcoex.c |    4 ++--
 drivers/net/wireless/ath/ath9k/btcoex.h |    1 +
 drivers/net/wireless/ath/ath9k/hw.c     |    2 +-
 drivers/net/wireless/ath/ath9k/main.c   |    4 ++--
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f001cc2..891e71b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -532,7 +532,6 @@ struct ath_led {
 #define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
 #define SC_OP_WAIT_FOR_TX_ACK   BIT(18)
 #define SC_OP_BEACON_SYNC       BIT(19)
-#define SC_OP_BTCOEX_ENABLED    BIT(20)
 #define SC_OP_BT_PRIORITY_DETECTED BIT(21)
 
 struct ath_bus_ops {
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 61a8e1d..91befc7 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -164,7 +164,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
 		(0x2 << (btcoex_info->btactive_gpio * 2)),
 		(0x3 << (btcoex_info->btactive_gpio * 2)));
 
-	ah->ah_sc->sc_flags |= SC_OP_BTCOEX_ENABLED;
+	ah->btcoex_info.enabled = true;
 }
 
 void ath9k_hw_btcoex_disable(struct ath_hw *ah)
@@ -182,5 +182,5 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 		REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
 	}
 
-	ah->ah_sc->sc_flags &= ~SC_OP_BTCOEX_ENABLED;
+	ah->btcoex_info.enabled = false;
 }
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index ed8d01d..b2c3f76 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -64,6 +64,7 @@ struct ath_btcoex_config {
 
 struct ath_btcoex_info {
 	enum ath_btcoex_scheme btcoex_scheme;
+	bool enabled;
 	u8 wlanactive_gpio;
 	u8 btactive_gpio;
 	u8 btpriority_gpio;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9be5587..30d83cb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2560,7 +2560,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 #endif
 	}
 
-	if (ah->ah_sc->sc_flags & SC_OP_BTCOEX_ENABLED)
+	if (ah->btcoex_info.enabled)
 		ath9k_hw_btcoex_enable(ah);
 
 	return 0;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e6a42d2..90be4ed 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2203,7 +2203,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 
 	if ((ah->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) &&
-	    !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) {
+	    !ah->btcoex_info.enabled) {
 		ath9k_hw_btcoex_init_weight(ah);
 		ath9k_hw_btcoex_enable(ah);
 
@@ -2362,7 +2362,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 		return; /* another wiphy still in use */
 	}
 
-	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
+	if (ah->btcoex_info.enabled) {
 		ath9k_hw_btcoex_disable(ah);
 		if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
 			ath9k_btcoex_timer_pause(sc);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 00/15] ath9k: cleanups to help other core drivers
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez

We want the common hardware access stuff to not rely on a specific
driver core. We want this so that different driver cores can share
the same hw code, both for ath9k_htc and perhaps ath5k. I've spotted
a few places where we do use ath_softc internally on hw code, and
have strated to move core-specific code out and kept hw-related
code apart. This series addreses DPRINTF() usage and btcoex changes.

There'll be more of these, until we can bring up ath9k_htc with
shared code.

Luis R. Rodriguez (15):
  ath9k: use ath_hw for DPRINTF() and debug init/exit
  ath9k: move btcoex core driver info to its own struct
  ath9k: move hw specific btcoex info to ath_hw
  ath9k: split bluetooth hardware coex init into two helpers
  ath9k: move driver core helpers to main.c
  ath9k: split ath9k_hw_btcoex_enable() into two helpers
  ath9k: replaces SC_OP_BTCOEX_ENABLED with a bool
  ath9k: move bt_stomp_type to driver core
  ath9k: remove unused bt_duty_cycle
  ath9k: rename btcoex_scheme to just scheme
  ath9k: rename ath_btcoex_info to ath_btcoex_hw
  ath9k: simplify ath_btcoex_bt_stomp()
  ath9k: now move ath9k_hw_btcoex_set_weight() to btcoex.c
  ath9k: move ath_btcoex_config and ath_bt_mode to btcoex.c
  ath9k: rename ath_btcoex_supported() to ath9k_hw_btcoex_supported()

 drivers/net/wireless/ath/ath9k/ahb.c         |    2 +-
 drivers/net/wireless/ath/ath9k/ani.c         |   44 ++--
 drivers/net/wireless/ath/ath9k/ath9k.h       |   24 ++-
 drivers/net/wireless/ath/ath9k/beacon.c      |   32 +-
 drivers/net/wireless/ath/ath9k/btcoex.c      |  375 ++++++++----------------
 drivers/net/wireless/ath/ath9k/btcoex.h      |   64 +----
 drivers/net/wireless/ath/ath9k/calib.c       |  102 ++++----
 drivers/net/wireless/ath/ath9k/debug.c       |   16 +-
 drivers/net/wireless/ath/ath9k/debug.h       |   15 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c   |   24 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |   24 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c  |   24 +-
 drivers/net/wireless/ath/ath9k/hw.c          |  139 +++++-----
 drivers/net/wireless/ath/ath9k/hw.h          |    4 +
 drivers/net/wireless/ath/ath9k/mac.c         |   48 ++--
 drivers/net/wireless/ath/ath9k/main.c        |  399 +++++++++++++++++++-------
 drivers/net/wireless/ath/ath9k/phy.c         |   10 +-
 drivers/net/wireless/ath/ath9k/rc.c          |   15 +-
 drivers/net/wireless/ath/ath9k/recv.c        |   18 +-
 drivers/net/wireless/ath/ath9k/xmit.c        |   46 ++--
 20 files changed, 750 insertions(+), 675 deletions(-)


^ permalink raw reply

* [PATCH 08/15] ath9k: move bt_stomp_type to driver core
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

The bt_stomp_type defines the bt coex weight, it has a one-to-one
mapping. In the future we may want to just use the weight directly.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |    9 +++++++++
 drivers/net/wireless/ath/ath9k/btcoex.c |    2 --
 drivers/net/wireless/ath/ath9k/btcoex.h |    8 --------
 drivers/net/wireless/ath/ath9k/main.c   |    7 ++++---
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 891e71b..d99c92d 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -450,12 +450,21 @@ struct ath_ani {
 	struct timer_list timer;
 };
 
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+	ATH_BTCOEX_NO_STOMP,
+	ATH_BTCOEX_STOMP_ALL,
+	ATH_BTCOEX_STOMP_LOW,
+	ATH_BTCOEX_STOMP_NONE
+};
+
 struct ath_btcoex {
 	bool hw_timer_enabled;
 	spinlock_t btcoex_lock;
 	struct timer_list period_timer; /* Timer for BT period */
 	u32 bt_priority_cnt;
 	unsigned long bt_priority_time;
+	int bt_stomp_type; /* Types of BT stomping */
 	u32 btcoex_no_stomp; /* in usec */
 	u32 btcoex_period; /* in usec */
 	struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 91befc7..ab19072 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -65,8 +65,6 @@ void ath9k_hw_init_btcoex_hw_info(struct ath_hw *ah, int qnum)
 		SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
 		AR_BT_DISABLE_BT_ANT;
 
-	btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-
 	for (i = 0; i < 32; i++)
 		ah->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
 }
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index b2c3f76..d932f01 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -36,13 +36,6 @@ enum ath_btcoex_scheme {
 	ATH_BTCOEX_CFG_3WIRE,
 };
 
-enum ath_stomp_type {
-	ATH_BTCOEX_NO_STOMP,
-	ATH_BTCOEX_STOMP_ALL,
-	ATH_BTCOEX_STOMP_LOW,
-	ATH_BTCOEX_STOMP_NONE
-};
-
 enum ath_bt_mode {
 	ATH_BT_COEX_MODE_LEGACY,	/* legacy rx_clear mode */
 	ATH_BT_COEX_MODE_UNSLOTTED,	/* untimed/unslotted mode */
@@ -69,7 +62,6 @@ struct ath_btcoex_info {
 	u8 btactive_gpio;
 	u8 btpriority_gpio;
 	u8 bt_duty_cycle; 	/* BT duty cycle in percentage */
-	int bt_stomp_type; 	/* Types of BT stomping */
 	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
 	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 90be4ed..bc3b9b0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1395,7 +1395,7 @@ static void ath_btcoex_period_timer(unsigned long data)
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
-	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
+	ath_btcoex_bt_stomp(sc, btinfo, btcoex->bt_stomp_type);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
 
@@ -1430,9 +1430,9 @@ static void ath_btcoex_no_stomp_timer(void *arg)
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
-	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
+	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
 		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
-	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
 		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
@@ -1691,6 +1691,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
 			goto bad2;
 		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
 		ath9k_hw_init_btcoex_hw_info(ah, qnum);
+		sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
 		break;
 	default:
 		WARN_ON(1);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 05/15] ath9k: move driver core helpers to main.c
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Keep on btcoex.c only hardware access helpers, move the
driver core specific code to main.c. To accomplish
this we had to split ath_init_btcoex_info() into two parts,
the driver core part -- ath_init_btcoex_timer() and the hw
specific part -- ath9k_hw_init_btcoex_hw_info(). This
highlights how ath_gen_timer is part of the driver core, not
hw related, so stuff that into ath_btcoex struct.

The ath9k_hw_btcoex_init() code is now put inline on
ath_init_softc() through a switch to it easier to follow,
since we did that we can now call ath_tx_get_qnum() from
the main.c instead of btcoex.c

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |    1 +
 drivers/net/wireless/ath/ath9k/btcoex.c |  214 +------------------------------
 drivers/net/wireless/ath/ath9k/btcoex.h |    7 +-
 drivers/net/wireless/ath/ath9k/hw.h     |    3 -
 drivers/net/wireless/ath/ath9k/main.c   |  215 ++++++++++++++++++++++++++++++-
 5 files changed, 218 insertions(+), 222 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index e8a630c..f001cc2 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -458,6 +458,7 @@ struct ath_btcoex {
 	unsigned long bt_priority_time;
 	u32 btcoex_no_stomp; /* in usec */
 	u32 btcoex_period; /* in usec */
+	struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
 };
 
 /********************/
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index be69924..6209a56 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -43,144 +43,10 @@ bool ath_btcoex_supported(u16 subsysid)
 	return false;
 }
 
-static void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
-				  u32 bt_weight,
-				  u32 wlan_weight)
+void ath9k_hw_init_btcoex_hw_info(struct ath_hw *ah, int qnum)
 {
-	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
-				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
-}
-
-void ath9k_hw_btcoex_init_weight(struct ath_hw *ah)
-{
-	ath_btcoex_set_weight(&ah->btcoex_info, AR_BT_COEX_WGHT,
-			      AR_STOMP_LOW_WLAN_WGHT);
-}
-
-/*
- * Detects if there is any priority bt traffic
- */
-static void ath_detect_bt_priority(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_info.btpriority_gpio))
-		btcoex->bt_priority_cnt++;
-
-	if (time_after(jiffies, btcoex->bt_priority_time +
-			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
-		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
-			DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX,
-				"BT priority traffic detected");
-			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
-		} else {
-			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-		}
-
-		btcoex->bt_priority_cnt = 0;
-		btcoex->bt_priority_time = jiffies;
-	}
-}
-
-/*
- * Configures appropriate weight based on stomp type.
- */
-static void ath_btcoex_bt_stomp(struct ath_softc *sc,
-				struct ath_btcoex_info *btinfo,
-				int stomp_type)
-{
-
-	switch (stomp_type) {
-	case ATH_BTCOEX_STOMP_ALL:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_ALL_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_LOW:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_LOW_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_NONE:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_NONE_WLAN_WGHT);
-		break;
-	default:
-		DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
-		break;
-	}
-
-	ath9k_hw_btcoex_enable(sc->sc_ah);
-}
-
-/*
- * This is the master bt coex timer which runs for every
- * 45ms, bt traffic will be given priority during 55% of this
- * period while wlan gets remaining 45%
- */
-
-static void ath_btcoex_period_timer(unsigned long data)
-{
-	struct ath_softc *sc = (struct ath_softc *) data;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
-
-	ath_detect_bt_priority(sc);
-
-	spin_lock_bh(&btcoex->btcoex_lock);
-
-	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
-
-	spin_unlock_bh(&btcoex->btcoex_lock);
-
-	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
-		if (btcoex->hw_timer_enabled)
-			ath_gen_timer_stop(ah, btinfo->no_stomp_timer);
-
-		ath_gen_timer_start(ah,
-			btinfo->no_stomp_timer,
-			(ath9k_hw_gettsf32(sc->sc_ah) +
-				btcoex->btcoex_no_stomp),
-				btcoex->btcoex_no_stomp * 10);
-		btcoex->hw_timer_enabled = true;
-	}
-
-	mod_timer(&btcoex->period_timer, jiffies +
-				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
-}
-
-/*
- * Generic tsf based hw timer which configures weight
- * registers to time slice between wlan and bt traffic
- */
-
-static void ath_btcoex_no_stomp_timer(void *arg)
-{
-	struct ath_softc *sc = (struct ath_softc *)arg;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
-
-	DPRINTF(ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
-
-	spin_lock_bh(&btcoex->btcoex_lock);
-
-	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
-		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
-	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
-
-	spin_unlock_bh(&btcoex->btcoex_lock);
-}
-
-static int ath_init_btcoex_info(struct ath_hw *ah,
-				struct ath_btcoex_info *btcoex_info)
-{
-	struct ath_btcoex *btcoex = &ah->ah_sc->btcoex;
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 	u32 i;
-	int qnum;
-
-	qnum = ath_tx_get_qnum(ah->ah_sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
 
 	btcoex_info->bt_coex_mode =
 		(btcoex_info->bt_coex_mode & AR_BT_QCU_THRESH) |
@@ -201,31 +67,11 @@ static int ath_init_btcoex_info(struct ath_hw *ah,
 
 	btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
 
-	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
-
-	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
-		btcoex->btcoex_period / 100;
-
 	for (i = 0; i < 32; i++)
 		ah->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
-
-	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
-			(unsigned long) ah->ah_sc);
-
-	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(ah,
-			ath_btcoex_no_stomp_timer,
-			ath_btcoex_no_stomp_timer,
-			(void *)ah->ah_sc, AR_FIRST_NDP_TIMER);
-
-	if (btcoex_info->no_stomp_timer == NULL)
-		return -ENOMEM;
-
-	spin_lock_init(&btcoex->btcoex_lock);
-
-	return 0;
 }
 
-static void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
+void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
 {
 	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
@@ -246,7 +92,7 @@ static void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
 	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
 }
 
-static void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
+void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 {
 	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
@@ -271,21 +117,6 @@ static void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
 }
 
-int ath9k_hw_btcoex_init(struct ath_hw *ah)
-{
-	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
-	int ret = 0;
-
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE)
-		ath9k_hw_btcoex_init_2wire(ah);
-	else {
-		ath9k_hw_btcoex_init_3wire(ah);
-		ret = ath_init_btcoex_info(ah, btcoex_info);
-	}
-
-	return ret;
-}
-
 void ath9k_hw_btcoex_enable(struct ath_hw *ah)
 {
 	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
@@ -336,40 +167,3 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 
 	ah->ah_sc->sc_flags &= ~SC_OP_BTCOEX_ENABLED;
 }
-
-/*
- * Pause btcoex timer and bt duty cycle timer
- */
-void ath_btcoex_timer_pause(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	del_timer_sync(&btcoex->period_timer);
-
-	if (btcoex->hw_timer_enabled)
-		ath_gen_timer_stop(ah, ah->btcoex_info.no_stomp_timer);
-
-	btcoex->hw_timer_enabled = false;
-}
-
-/*
- * (Re)start btcoex timers
- */
-void ath_btcoex_timer_resume(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	DPRINTF(ah, ATH_DBG_BTCOEX, "Starting btcoex timers");
-
-	/* make sure duty cycle timer is also stopped when resuming */
-	if (btcoex->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, ah->btcoex_info.no_stomp_timer);
-
-	btcoex->bt_priority_cnt = 0;
-	btcoex->bt_priority_time = jiffies;
-	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-
-	mod_timer(&btcoex->period_timer, jiffies);
-}
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 12e86b7..ed8d01d 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -72,13 +72,14 @@ struct ath_btcoex_info {
 	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
 	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
-	struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
 };
 
 bool ath_btcoex_supported(u16 subsysid);
-void ath9k_hw_btcoex_init_weight(struct ath_hw *ah);
-int ath9k_hw_btcoex_init(struct ath_hw *ah);
+void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
+void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
+void ath9k_hw_init_btcoex_hw_info(struct ath_hw *ah, int qnum);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
 
+
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 774dc08..6658d95 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -679,7 +679,4 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
 #define ATH_PCIE_CAP_LINK_L1	2
 
 void ath_pcie_aspm_disable(struct ath_softc *sc);
-
-void ath_btcoex_timer_resume(struct ath_softc *sc);
-void ath_btcoex_timer_pause(struct ath_softc *sc);
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index defbe9f..e6a42d2 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1290,9 +1290,9 @@ void ath_detach(struct ath_softc *sc)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	if ((ah->btcoex_info.no_stomp_timer) &&
+	if ((sc->btcoex.no_stomp_timer) &&
 	    ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-		ath_gen_timer_free(ah, ah->btcoex_info.no_stomp_timer);
+		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
 
 	ath9k_hw_detach(ah);
 	ath9k_exit_debug(ah);
@@ -1311,6 +1311,158 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
 }
 
 /*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_info.btpriority_gpio))
+		btcoex->bt_priority_cnt++;
+
+	if (time_after(jiffies, btcoex->bt_priority_time +
+			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+			DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX,
+				"BT priority traffic detected");
+			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
+		} else {
+			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+		}
+
+		btcoex->bt_priority_cnt = 0;
+		btcoex->bt_priority_time = jiffies;
+	}
+}
+
+static void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
+				  u32 bt_weight,
+				  u32 wlan_weight)
+{
+	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
+}
+
+static void ath9k_hw_btcoex_init_weight(struct ath_hw *ah)
+{
+	ath_btcoex_set_weight(&ah->btcoex_info, AR_BT_COEX_WGHT,
+			      AR_STOMP_LOW_WLAN_WGHT);
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+static void ath_btcoex_bt_stomp(struct ath_softc *sc,
+				struct ath_btcoex_info *btinfo,
+				int stomp_type)
+{
+
+	switch (stomp_type) {
+	case ATH_BTCOEX_STOMP_ALL:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_ALL_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_LOW:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_LOW_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_NONE:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_NONE_WLAN_WGHT);
+		break;
+	default:
+		DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(sc->sc_ah);
+}
+
+/*
+ * This is the master bt coex timer which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+static void ath_btcoex_period_timer(unsigned long data)
+{
+	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
+
+	ath_detect_bt_priority(sc);
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+
+	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
+		if (btcoex->hw_timer_enabled)
+			ath_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+		ath_gen_timer_start(ah,
+			btcoex->no_stomp_timer,
+			(ath9k_hw_gettsf32(ah) +
+				btcoex->btcoex_no_stomp),
+				btcoex->btcoex_no_stomp * 10);
+		btcoex->hw_timer_enabled = true;
+	}
+
+	mod_timer(&btcoex->period_timer, jiffies +
+				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
+}
+
+/*
+ * Generic tsf based hw timer which configures weight
+ * registers to time slice between wlan and bt traffic
+ */
+static void ath_btcoex_no_stomp_timer(void *arg)
+{
+	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_btcoex_info *btinfo = &ah->btcoex_info;
+
+	DPRINTF(ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
+		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
+	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+}
+
+static int ath_init_btcoex_timer(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+
+	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
+	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+		btcoex->btcoex_period / 100;
+
+	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
+			(unsigned long) sc);
+
+	spin_lock_init(&btcoex->btcoex_lock);
+
+	btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
+			ath_btcoex_no_stomp_timer,
+			ath_btcoex_no_stomp_timer,
+			(void *) sc, AR_FIRST_NDP_TIMER);
+
+	if (!btcoex->no_stomp_timer)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/*
  * Initialize and fill ath_softc, ath_sofct is the
  * "Software Carrier" struct. Historically it has existed
  * to allow the separation between hardware specific
@@ -1321,6 +1473,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
 	struct ath_hw *ah = NULL;
 	int r = 0, i;
 	int csz = 0;
+	int qnum;
 
 	/* XXX: hardware will not be ready until ath_open() being called */
 	sc->sc_flags |= SC_OP_INVALID;
@@ -1525,10 +1678,23 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
 			ARRAY_SIZE(ath9k_5ghz_chantable);
 	}
 
-	if (ah->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) {
-		r = ath9k_hw_btcoex_init(ah);
+	switch (ah->btcoex_info.btcoex_scheme) {
+	case ATH_BTCOEX_CFG_NONE:
+		break;
+	case ATH_BTCOEX_CFG_2WIRE:
+		ath9k_hw_btcoex_init_2wire(ah);
+		break;
+	case ATH_BTCOEX_CFG_3WIRE:
+		ath9k_hw_btcoex_init_3wire(ah);
+		r = ath_init_btcoex_timer(sc);
 		if (r)
 			goto bad2;
+		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+		ath9k_hw_init_btcoex_hw_info(ah, qnum);
+		break;
+	default:
+		WARN_ON(1);
+		break;
 	}
 
 	return 0;
@@ -1910,6 +2076,27 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
 /* mac80211 callbacks */
 /**********************/
 
+/*
+ * (Re)start btcoex timers
+ */
+static void ath9k_btcoex_timer_resume(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	DPRINTF(ah, ATH_DBG_BTCOEX, "Starting btcoex timers");
+
+	/* make sure duty cycle timer is also stopped when resuming */
+	if (btcoex->hw_timer_enabled)
+		ath_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
+
+	btcoex->bt_priority_cnt = 0;
+	btcoex->bt_priority_time = jiffies;
+	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+
+	mod_timer(&btcoex->period_timer, jiffies);
+}
+
 static int ath9k_start(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -2022,7 +2209,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
 		ath_pcie_aspm_disable(sc);
 		if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_resume(sc);
+			ath9k_btcoex_timer_resume(sc);
 	}
 
 mutex_unlock:
@@ -2130,6 +2317,22 @@ exit:
 	return 0;
 }
 
+/*
+ * Pause btcoex timer and bt duty cycle timer
+ */
+static void ath9k_btcoex_timer_pause(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	del_timer_sync(&btcoex->period_timer);
+
+	if (btcoex->hw_timer_enabled)
+		ath_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+	btcoex->hw_timer_enabled = false;
+}
+
 static void ath9k_stop(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -2162,7 +2365,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
 		ath9k_hw_btcoex_disable(ah);
 		if (ah->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_pause(sc);
+			ath9k_btcoex_timer_pause(sc);
 	}
 
 	/* make sure h/w will not generate any interrupt
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 12/15] ath9k: simplify ath_btcoex_bt_stomp()
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

The second argument is always the hardware bt coex struct, so
remove it, and rename the function on the path with a ath9k_ prefix.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |   43 ++++++++++++++++-----------------
 1 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1a89e47..c8f2ff6 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1336,47 +1336,48 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
 	}
 }
 
-static void ath_btcoex_set_weight(struct ath_btcoex_hw *btcoex_hw,
-				  u32 bt_weight,
-				  u32 wlan_weight)
+static void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
+				       u32 bt_weight,
+				       u32 wlan_weight)
 {
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+
 	btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
-				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
+				     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
 }
 
 static void ath9k_hw_btcoex_init_weight(struct ath_hw *ah)
 {
-	ath_btcoex_set_weight(&ah->btcoex_hw, AR_BT_COEX_WGHT,
-			      AR_STOMP_LOW_WLAN_WGHT);
+	ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, AR_STOMP_LOW_WLAN_WGHT);
 }
 
 /*
  * Configures appropriate weight based on stomp type.
  */
-static void ath_btcoex_bt_stomp(struct ath_softc *sc,
-				struct ath_btcoex_hw *btcoex_hw,
-				int stomp_type)
+static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
+				  enum ath_stomp_type stomp_type)
 {
+	struct ath_hw *ah = sc->sc_ah;
 
 	switch (stomp_type) {
 	case ATH_BTCOEX_STOMP_ALL:
-		ath_btcoex_set_weight(btcoex_hw, AR_BT_COEX_WGHT,
-				      AR_STOMP_ALL_WLAN_WGHT);
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_ALL_WLAN_WGHT);
 		break;
 	case ATH_BTCOEX_STOMP_LOW:
-		ath_btcoex_set_weight(btcoex_hw, AR_BT_COEX_WGHT,
-				      AR_STOMP_LOW_WLAN_WGHT);
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_LOW_WLAN_WGHT);
 		break;
 	case ATH_BTCOEX_STOMP_NONE:
-		ath_btcoex_set_weight(btcoex_hw, AR_BT_COEX_WGHT,
-				      AR_STOMP_NONE_WLAN_WGHT);
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_NONE_WLAN_WGHT);
 		break;
 	default:
-		DPRINTF(sc->sc_ah, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
+		DPRINTF(ah, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
 		break;
 	}
 
-	ath9k_hw_btcoex_enable(sc->sc_ah);
+	ath9k_hw_btcoex_enable(ah);
 }
 
 /*
@@ -1389,13 +1390,12 @@ static void ath_btcoex_period_timer(unsigned long data)
 	struct ath_softc *sc = (struct ath_softc *) data;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_hw *btcoex_hw= &ah->btcoex_hw;
 
 	ath_detect_bt_priority(sc);
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
-	ath_btcoex_bt_stomp(sc, btcoex_hw, btcoex->bt_stomp_type);
+	ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
 
@@ -1424,16 +1424,15 @@ static void ath_btcoex_no_stomp_timer(void *arg)
 	struct ath_softc *sc = (struct ath_softc *)arg;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_btcoex_hw *btcoex_hw= &ah->btcoex_hw;
 
 	DPRINTF(ah, ATH_DBG_BTCOEX, "no stomp timer running \n");
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
 	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
-		ath_btcoex_bt_stomp(sc, btcoex_hw, ATH_BTCOEX_STOMP_NONE);
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
 	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath_btcoex_bt_stomp(sc, btcoex_hw, ATH_BTCOEX_STOMP_LOW);
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
 }
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 04/15] ath9k: split bluetooth hardware coex init into two helpers
From: Luis R. Rodriguez @ 2009-09-09 23:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Use a helper for 2-wire and another for 3-wire.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.c |   75 ++++++++++++++++++-------------
 1 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index dfbcbd0..be69924 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -225,48 +225,61 @@ static int ath_init_btcoex_info(struct ath_hw *ah,
 	return 0;
 }
 
-int ath9k_hw_btcoex_init(struct ath_hw *ah)
+static void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
 {
 	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
-	int ret = 0;
 
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
-		/* connect bt_active to baseband */
-		REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
-				 AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+	/* connect bt_active to baseband */
+	REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+		     AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
 
-		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
 
-		/* Set input mux for bt_active to gpio pin */
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-				btcoex_info->btactive_gpio);
+	/* Set input mux for bt_active to gpio pin */
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+		      AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+		      btcoex_info->btactive_gpio);
 
-		/* Configure the desired gpio port for input */
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
-	} else {
-		/* btcoex 3-wire */
-		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
-				 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
+	/* Configure the desired gpio port for input */
+	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
+}
+
+static void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
 
-		/* Set input mux for bt_prority_async and
-		 *                  bt_active_async to GPIO pins */
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-				btcoex_info->btactive_gpio);
+	/* btcoex 3-wire */
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+			(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
+			 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
 
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_PRIORITY,
-				btcoex_info->btpriority_gpio);
+	/* Set input mux for bt_prority_async and
+	 *                  bt_active_async to GPIO pins */
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+			AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+			btcoex_info->btactive_gpio);
 
-		/* Configure the desired GPIO ports for input */
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+			AR_GPIO_INPUT_MUX1_BT_PRIORITY,
+			btcoex_info->btpriority_gpio);
 
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
+	/* Configure the desired GPIO ports for input */
+
+	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
+	ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
+}
+
+int ath9k_hw_btcoex_init(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->btcoex_info;
+	int ret = 0;
 
+	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE)
+		ath9k_hw_btcoex_init_2wire(ah);
+	else {
+		ath9k_hw_btcoex_init_3wire(ah);
 		ret = ath_init_btcoex_info(ah, btcoex_info);
 	}
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 15/15] ath9k: rename ath_btcoex_supported() to ath9k_hw_btcoex_supported()
From: Luis R. Rodriguez @ 2009-09-09 23:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252539901-20679-1-git-send-email-lrodriguez@atheros.com>

Also just pass the ath_hw as the parameter.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/btcoex.c |    6 +++---
 drivers/net/wireless/ath/ath9k/btcoex.h |    2 +-
 drivers/net/wireless/ath/ath9k/hw.c     |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index ee2a834..5d1095f 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -45,15 +45,15 @@ static const u16 ath_subsysid_tbl[] = {
  * Checks the subsystem id of the device to see if it
  * supports btcoex
  */
-bool ath_btcoex_supported(u16 subsysid)
+bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
 {
 	int i;
 
-	if (!subsysid)
+	if (!ah->hw_version.subsysid)
 		return false;
 
 	for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
-		if (subsysid == ath_subsysid_tbl[i])
+		if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
 			return true;
 
 	return false;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 0dc5120..1ba31a7 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -47,7 +47,7 @@ struct ath_btcoex_hw {
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
 };
 
-bool ath_btcoex_supported(u16 subsysid);
+bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
 void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
 void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0fc4c6e..24157d2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3688,7 +3688,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
 
 	if (AR_SREV_9280_10_OR_LATER(ah) &&
-	    ath_btcoex_supported(ah->hw_version.subsysid)) {
+	    ath9k_hw_btcoex_supported(ah)) {
 		btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
 		btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
 
-- 
1.6.3.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox