Hi,

Well, this was my bad )) I accidentally chose cpu's gpio and realised that this is a mistake yesterday night.

So I made a patch for atheros driver and it works. A signal level on different frequencies is more or less equal and seems adequate (about -30 dbm if a client within a meter from ap).

The patch for bb 14.07 is in the attachment. It should be placed in package/kernel/mac80211/patches . The code generates a lot of messages, so it'll be easy to track what happens.


Kirill

On 05/26/2015 11:25 PM, Stefan Rompf wrote:

Until I found that I was accessing GPIO lines of the CPU (cat
/sys/devices/virtual/gpio/gpiochip0/label => ath79), not of the 928x wifi
chip. It seems that ath9k does not even export its pins to the GPIO subsystem.

Stefan


diff -urN old/drivers/net/wireless/ath/ath9k/hsr.c new/drivers/net/wireless/ath/ath9k/hsr.c
--- old/drivers/net/wireless/ath/ath9k/hsr.c	1970-01-01 03:00:00.000000000 +0300
+++ new/drivers/net/wireless/ath/ath9k/hsr.c	2015-05-27 12:47:43.000000000 +0300
@@ -0,0 +1,236 @@
+/*
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Kirill Berezin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/bitops.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ar9003_mac.h"
+#include "ar9003_mci.h"
+#include "ar9003_phy.h"
+#include "ath9k.h"
+
+#include "hsr.h"
+
+void hsr_init(struct ath_hw* ah) {
+
+	if ( NULL == ah) {
+		return;
+	}
+
+	ath9k_hw_cfg_gpio_input(ah, HSR_GPIO_DIN);
+	ath9k_hw_cfg_output(ah, HSR_GPIO_CSN, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+	ath9k_hw_cfg_output(ah, HSR_GPIO_CLK, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+	ath9k_hw_cfg_output(ah, HSR_GPIO_DOUT, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+	ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
+	ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+	ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0);
+
+	udelay(HSR_DELAY_TRAILING);
+
+	printk(KERN_NOTICE "hsr_init: done");
+
+}
+EXPORT_SYMBOL(hsr_init);
+
+static u32 hsr_write_byte(struct ath_hw* ah, int delay, u32 value){
+	int i;
+	u32 rval = 0;
+
+	udelay(delay);
+
+	ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+	udelay(HSR_DELAY_HALF_TICK);
+
+	ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0);
+	udelay(HSR_DELAY_HALF_TICK);
+
+	for( i = 0; i < 8; ++i) {
+		rval = rval << 1;
+
+		// pattern is left to right, that is 7-th bit runs first
+		ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1);
+		udelay(HSR_DELAY_HALF_TICK);
+
+		ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1);
+		udelay(HSR_DELAY_HALF_TICK);
+
+		rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN);
+
+		ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+		udelay(HSR_DELAY_HALF_TICK);
+	}
+
+	ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
+	udelay(HSR_DELAY_HALF_TICK);
+
+printk(KERN_NOTICE "hsr_write_byte: write byte %d return value is %x %d %c \n", value, rval, rval, rval > 32 ? rval : '-');
+                                                           
+	return rval & 0xff;
+}
+
+static int hsr_write_a_chain(struct ath_hw* ah, char* chain, int items) {
+	int i = 0, j;
+	int status = 0;
+	int loops = 0;
+	// a preabmle
+	hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+
+	status = hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+
+	if ( status) {
+		int loop = 2;
+		++ loops;
+		if ( loops > 42) {
+printk(KERN_NOTICE "hsr_write_a_chain: too many loops in preamble. giving up.\n");
+			return 0;
+		}
+		do {
+			status = hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+			loop = (loop + 1) & 0xffff;
+			if ( loop < 2) {
+				continue;
+			} 
+		} while(status);
+	}
+
+        for ( i =0; (i < items) && ( 0 != chain[i]); ++i) {
+		hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]);
+	}
+	hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);  
+	udelay(HSR_DELAY_FINAL);
+
+	memset(chain, 0, items);
+
+	for ( j = 0, i = 0; (i < 7) && (j < (items - 1)) ; ++i) { 
+		u32 ret;
+		if ( 31 < (ret = hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0))) {
+			chain[j] = (char)ret;
+			++ j;
+		}
+		udelay(HSR_DELAY_TRAILING);
+	}
+printk(KERN_NOTICE "hsr_write_a_chain: j %d \n", j);
+	return j > 1 ? simple_strtol(chain + 1, NULL, 10) : 0;
+}
+
+int hsr_disable(struct ath_hw* ah) {
+	char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0};
+	int  ret;
+
+	if ( NULL == ah) {
+		return 0;
+	}
+
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+printk(KERN_NOTICE "hsr_disable: return %d \n", ret);
+	if ( (ret > 0) && (*cmd == 'B')) {
+		printk(KERN_NOTICE "hsr_disable: bandwidth set %d \n", ret);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(hsr_disable);
+
+int hsr_enable(struct ath_hw* ah, int bw, int fq) {
+	char cmd[10];
+	int ret;
+
+	if ( NULL == ah) {
+		return 0;
+	}
+
+
+	if ( (bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) {
+		bw = 20;
+	}
+	memset(cmd, 0, sizeof(cmd));
+	*cmd = 'b'; // 98
+	snprintf(cmd + 1, 3, "%02d", bw);
+
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+	if ( (*cmd != 'B') || (ret != bw)) {
+printk(KERN_NOTICE "hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d) \n", 'b', bw, *cmd, ret);	  	return 0;
+	}
+
+
+
+	memset(cmd, 0, sizeof(cmd));
+	*cmd = 'x'; // 120
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+	if ( *cmd != 'X') {
+printk(KERN_NOTICE "hsr_enable: failed 'x' command -> reply (%d, %d) \n", *cmd, ret);
+		return 0;
+	}
+
+	memset(cmd, 0, sizeof(cmd));
+	*cmd = 'm'; // 109
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+	if ( *cmd != 'M') {
+printk(KERN_NOTICE "hsr_enable: failed 'm' command -> reply (%d, %d) \n", *cmd, ret);
+		return  0;
+	}
+
+	memset(cmd, 0, sizeof(cmd));
+	*cmd = 'f'; // 102
+	snprintf(cmd + 1, 6, "%05d", fq);
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+	if ( (*cmd != 'F') && (ret != fq)) {
+printk(KERN_NOTICE "hsr_enable: failed set frequency -> reply (%d, %d) \n", *cmd, ret);
+		return 0;
+	}
+
+printk(KERN_NOTICE "hsr_enable: center frequency %dMHz bandwidth %dMHz \n", fq, bw);
+
+	return 0;
+}
+EXPORT_SYMBOL(hsr_enable);
+
+int hsr_status(struct ath_hw* ah) {
+	char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 115
+	int ret;
+	if ( NULL == ah) {
+		return 0;
+	}
+
+	ret = hsr_write_a_chain(ah, cmd, sizeof(cmd));
+	if ( (*cmd != 'S')) {
+printk(KERN_NOTICE "hsr_status: returned %d,%d \n", *cmd, ret);
+		return -1;
+	}
+
+printk(KERN_NOTICE "hsr_status: current status is %d \n", ret);
+
+	return 0;
+}
+EXPORT_SYMBOL(hsr_status);
diff -urN old/drivers/net/wireless/ath/ath9k/hsr.h new/drivers/net/wireless/ath/ath9k/hsr.h
--- old/drivers/net/wireless/ath/ath9k/hsr.h	1970-01-01 03:00:00.000000000 +0300
+++ new/drivers/net/wireless/ath/ath9k/hsr.h	2015-05-27 11:30:16.000000000 +0300
@@ -0,0 +1,44 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Kirill Berezin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef HSR_H_
+#define HSR_H_
+
+#define HSR_GPIO_CSN 8
+#define HSR_GPIO_CLK 6
+#define HSR_GPIO_DOUT 7
+#define HSR_GPIO_DIN 5
+
+/* delays are in useconds */
+#define HSR_DELAY_HALF_TICK 100
+#define HSR_DELAY_PRE_WRITE 75
+#define HSR_DELAY_FINAL 20000
+#define HSR_DELAY_TRAILING 200
+
+void hsr_init(struct ath_hw* ah);
+int hsr_disable(struct ath_hw* ah);
+int hsr_enable(struct ath_hw* ah, int bw, int fq);
+int hsr_status(struct ath_hw* ah);
+
+#endif /* HSR_H_ */
diff -urN old/drivers/net/wireless/ath/ath9k/main.c new/drivers/net/wireless/ath/ath9k/main.c
--- old/drivers/net/wireless/ath/ath9k/main.c	2015-04-22 11:20:18.000000000 +0300
+++ new/drivers/net/wireless/ath/ath9k/main.c	2015-05-27 11:58:38.000000000 +0300
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include "ath9k.h"
 #include "btcoex.h"
+#include "hsr.h"
 
 static void ath9k_set_assoc_state(struct ath_softc *sc,
 				  struct ieee80211_vif *vif);
@@ -353,6 +354,9 @@
 	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
 		chan->center_freq, chandef->width);
 
+	hsr_enable(ah, chandef->width, chan->center_freq);
+	hsr_status(ah);
+
 	/* update survey stats for the old channel before switching */
 	spin_lock_bh(&common->cc_lock);
 	ath_update_survey_stats(sc);
@@ -793,6 +797,9 @@
 		ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 	}
 
+	hsr_init(ah);
+	hsr_disable(ah);
+
 	/*
 	 * Reset key cache to sane defaults (all entries cleared) instead of
 	 * semi-random values after suspend/resume.
diff -urN old/drivers/net/wireless/ath/ath9k/Makefile new/drivers/net/wireless/ath/ath9k/Makefile
--- old/drivers/net/wireless/ath/ath9k/Makefile	2015-04-22 11:20:18.000000000 +0300
+++ new/drivers/net/wireless/ath/ath9k/Makefile	2015-05-27 08:35:46.000000000 +0300
@@ -41,7 +41,8 @@
 		ar9002_mac.o \
 		ar9003_mac.o \
 		ar9003_eeprom.o \
-		ar9003_paprd.o
+		ar9003_paprd.o \
+		hsr.o
 
 ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_wow.o
 
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to