Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 08/17] mwifiex: add calibration data download feature
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

User can provide a text file containing calibration data in hex
format while loading mwifiex module. It will be downloaded to
firmware.
eg. insmod mwifiex.ko cal_data_cfg=cal_data.conf

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/fw.h          | 10 +++++
 drivers/net/wireless/mwifiex/main.c        | 13 +++++++
 drivers/net/wireless/mwifiex/main.h        |  1 +
 drivers/net/wireless/mwifiex/sta_cmd.c     | 62 ++++++++++++++++++++++++++++++
 drivers/net/wireless/mwifiex/sta_cmdresp.c | 15 ++++++++
 5 files changed, 101 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index d3c1e01..d6ada73 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -271,6 +271,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HostCmd_CMD_802_11_SUBSCRIBE_EVENT            0x0075
 #define HostCmd_CMD_802_11_TX_RATE_QUERY              0x007f
 #define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS     0x0083
+#define HostCmd_CMD_CFG_DATA                          0x008f
 #define HostCmd_CMD_VERSION_EXT                       0x0097
 #define HostCmd_CMD_MEF_CFG                           0x009a
 #define HostCmd_CMD_RSSI_INFO                         0x00a4
@@ -465,6 +466,8 @@ enum P2P_MODES {
 #define MWIFIEX_CRITERIA_UNICAST	BIT(1)
 #define MWIFIEX_CRITERIA_MULTICAST	BIT(3)
 
+#define CFG_DATA_TYPE_CAL		2
+
 struct mwifiex_ie_types_header {
 	__le16 type;
 	__le16 len;
@@ -1579,6 +1582,12 @@ struct mwifiex_ie_list {
 	struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
 } __packed;
 
+struct host_cmd_ds_802_11_cfg_data {
+	__le16 action;
+	__le16 type;
+	__le16 data_len;
+} __packed;
+
 struct host_cmd_ds_command {
 	__le16 command;
 	__le16 size;
@@ -1638,6 +1647,7 @@ struct host_cmd_ds_command {
 		struct host_cmd_ds_sys_config uap_sys_config;
 		struct host_cmd_ds_sta_deauth sta_deauth;
 		struct host_cmd_11ac_vht_cfg vht_cfg;
+		struct host_cmd_ds_802_11_cfg_data cfg_data;
 	} params;
 } __packed;
 
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 4e7270c..5bc7ef8 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -25,6 +25,8 @@
 #define VERSION	"1.0"
 
 const char driver_version[] = "mwifiex " VERSION " (%s) ";
+static char *cal_data_cfg;
+module_param(cal_data_cfg, charp, 0);
 
 /*
  * This function registers the device and performs all the necessary
@@ -336,6 +338,13 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 
 	dev_notice(adapter->dev, "WLAN FW is active\n");
 
+	if (cal_data_cfg) {
+		if ((request_firmware(&adapter->cal_data, cal_data_cfg,
+				      adapter->dev)) < 0)
+			dev_err(adapter->dev,
+				"Cal data request_firmware() failed\n");
+	}
+
 	adapter->init_wait_q_woken = false;
 	ret = mwifiex_init_fw(adapter);
 	if (ret == -1) {
@@ -390,6 +399,10 @@ err_init_fw:
 	pr_debug("info: %s: unregister device\n", __func__);
 	adapter->if_ops.unregister_dev(adapter);
 done:
+	if (adapter->cal_data) {
+		release_firmware(adapter->cal_data);
+		adapter->cal_data = NULL;
+	}
 	release_firmware(adapter->firmware);
 	complete(&adapter->fw_load);
 	return;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 9cf6852..0832c24 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -730,6 +730,7 @@ struct mwifiex_adapter {
 	u16 max_mgmt_ie_index;
 	u8 scan_delay_cnt;
 	u8 empty_tx_q_cnt;
+	const struct firmware *cal_data;
 
 	/* 11AC */
 	u32 is_hw_11ac_capable;
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index b193e25..8ece485 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1134,6 +1134,55 @@ mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
 	return 0;
 }
 
+/* This function parse cal data from ASCII to hex */
+static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
+{
+	u8 *s = src, *d = dst;
+
+	while (s - src < len) {
+		if (*s && (isspace(*s) || *s == '\t')) {
+			s++;
+			continue;
+		}
+		if (isxdigit(*s)) {
+			*d++ = simple_strtol(s, NULL, 16);
+			s += 2;
+		} else {
+			s++;
+		}
+	}
+
+	return d - dst;
+}
+
+/* This function prepares command of set_cfg_data. */
+static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *cmd,
+				u16 cmd_action)
+{
+	struct host_cmd_ds_802_11_cfg_data *cfg_data = &cmd->params.cfg_data;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 len, cal_data_offset;
+	u8 *tmp_cmd = (u8 *)cmd;
+
+	cal_data_offset = S_DS_GEN + sizeof(*cfg_data);
+	if ((adapter->cal_data->data) && (adapter->cal_data->size > 0))
+		len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
+					    adapter->cal_data->size,
+					    (u8 *)(tmp_cmd + cal_data_offset));
+	else
+		return -1;
+
+	cfg_data->action = cpu_to_le16(cmd_action);
+	cfg_data->type = cpu_to_le16(CFG_DATA_TYPE_CAL);
+	cfg_data->data_len = cpu_to_le16(len);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
+	cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*cfg_data) + len);
+
+	return 0;
+}
+
 /*
  * This function prepares the commands before sending them to the firmware.
  *
@@ -1152,6 +1201,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
 	case HostCmd_CMD_GET_HW_SPEC:
 		ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
 		break;
+	case HostCmd_CMD_CFG_DATA:
+		ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, cmd_action);
+		break;
 	case HostCmd_CMD_MAC_CONTROL:
 		ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
 					      data_buf);
@@ -1384,6 +1436,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
  */
 int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 {
+	struct mwifiex_adapter *adapter = priv->adapter;
 	int ret;
 	u16 enable = true;
 	struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
@@ -1404,6 +1457,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 					    HostCmd_ACT_GEN_SET, 0, NULL);
 		if (ret)
 			return -1;
+
+		/* Download calibration data to firmware */
+		if (adapter->cal_data) {
+			ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
+						HostCmd_ACT_GEN_SET, 0, NULL);
+			if (ret)
+				return -1;
+		}
+
 		/* Read MAC address from HW */
 		ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
 					    HostCmd_ACT_GEN_GET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index c710a1b..d85df15 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -818,6 +818,18 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
 	return 0;
 }
 
+/* This function handles the command response of set_cfg_data */
+static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *resp)
+{
+	if (resp->result != HostCmd_RESULT_OK) {
+		dev_err(priv->adapter->dev, "Cal data cmd resp failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * This function handles the command responses.
  *
@@ -841,6 +853,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
 	case HostCmd_CMD_GET_HW_SPEC:
 		ret = mwifiex_ret_get_hw_spec(priv, resp);
 		break;
+	case HostCmd_CMD_CFG_DATA:
+		ret = mwifiex_ret_cfg_data(priv, resp);
+		break;
 	case HostCmd_CMD_MAC_CONTROL:
 		break;
 	case HostCmd_CMD_802_11_MAC_ADDRESS:
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 11/17] mwifiex: replace unnecessary u32 variables with u8 in sdio.c
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Some u32 variables in sdio.c are used to store/pass u8 values.
Replace them with u8 variables.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/sdio.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 022e9fd..e4357a6 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -294,13 +294,13 @@ static struct sdio_driver mwifiex_sdio = {
  * This function writes data into SDIO card register.
  */
 static int
-mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
 {
 	struct sdio_mmc_card *card = adapter->card;
 	int ret = -1;
 
 	sdio_claim_host(card->func);
-	sdio_writeb(card->func, (u8) data, reg, &ret);
+	sdio_writeb(card->func, data, reg, &ret);
 	sdio_release_host(card->func);
 
 	return ret;
@@ -310,7 +310,7 @@ mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
  * This function reads data from SDIO card register.
  */
 static int
-mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
 {
 	struct sdio_mmc_card *card = adapter->card;
 	int ret = -1;
@@ -421,7 +421,7 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
  */
 static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
 {
-	u32 reg;
+	u8 reg;
 	struct sdio_mmc_card *card = adapter->card;
 
 	adapter->ioport = 0;
@@ -580,7 +580,7 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
 {
 	struct sdio_mmc_card *card = adapter->card;
 	u32 tries;
-	u32 cs;
+	u8 cs;
 
 	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
 		if (mwifiex_read_reg(adapter, card->reg->poll_reg, &cs))
@@ -604,7 +604,7 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
 {
 	struct sdio_mmc_card *card = adapter->card;
 	const struct mwifiex_sdio_card_reg *reg = card->reg;
-	u32 fws0, fws1;
+	u8 fws0, fws1;
 
 	if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
 		return -1;
@@ -625,14 +625,14 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
  */
 static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 {
-	u32 host_int_mask;
+	u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
 
 	/* Read back the host_int_mask register */
 	if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
 		return -1;
 
 	/* Update with the mask and write back to the register */
-	host_int_mask &= ~HOST_INT_DISABLE;
+	host_int_mask &= ~host_int_disable;
 
 	if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
 		dev_err(adapter->dev, "disable host interrupt failed\n");
@@ -712,7 +712,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 	u8 *firmware = fw->fw_buf;
 	u32 firmware_len = fw->fw_len;
 	u32 offset = 0;
-	u32 base0, base1;
+	u8 base0, base1;
 	u8 *fwbuf;
 	u16 len = 0;
 	u32 txlen, tx_blocks = 0, tries;
@@ -854,7 +854,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 	int ret = 0;
 	u16 firmware_stat;
 	u32 tries;
-	u32 winner_status;
+	u8 winner_status;
 
 	/* Wait for firmware initialization event */
 	for (tries = 0; tries < poll_num; tries++) {
@@ -889,7 +889,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u32 sdio_ireg;
+	u8 sdio_ireg;
 	unsigned long flags;
 
 	if (mwifiex_read_data_sync(adapter, card->mp_regs,
@@ -1284,7 +1284,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 
 			if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
 							      port)) {
-				u32 cr = 0;
+				u8 cr = 0;
 
 				dev_err(adapter->dev, "card_to_host_mpa failed:"
 					" int status=%#x\n", sdio_ireg);
@@ -1644,7 +1644,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
 	struct sdio_mmc_card *card = adapter->card;
 	const struct mwifiex_sdio_card_reg *reg = card->reg;
 	int ret;
-	u32 sdio_ireg;
+	u8 sdio_ireg;
 
 	/*
 	 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 09/17] mwifiex: use u32 variables for SDIO read/write port bitmap
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Currently supported SDIO chipsets (SD87XX) have 16 ports.
This change is a prerequisite for new chipset.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/sdio.c | 40 ++++++++++++++++++-------------------
 drivers/net/wireless/mwifiex/sdio.h | 10 +++++-----
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 363ba31..7368ee1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -486,21 +486,21 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
 static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u16 rd_bitmap = card->mp_rd_bitmap;
+	u32 rd_bitmap = card->mp_rd_bitmap;
 
-	dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap);
+	dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);
 
 	if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
 		return -1;
 
 	if (card->mp_rd_bitmap & CTRL_PORT_MASK) {
-		card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
+		card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK);
 		*port = CTRL_PORT;
-		dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
+		dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
 			*port, card->mp_rd_bitmap);
 	} else {
 		if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
-			card->mp_rd_bitmap &= (u16)
+			card->mp_rd_bitmap &= (u32)
 						(~(1 << card->curr_rd_port));
 			*port = card->curr_rd_port;
 
@@ -511,7 +511,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 		}
 
 		dev_dbg(adapter->dev,
-			"data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
+			"data: port=%d mp_rd_bitmap=0x%08x -> 0x%08x\n",
 			*port, rd_bitmap, card->mp_rd_bitmap);
 	}
 	return 0;
@@ -527,15 +527,15 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u16 wr_bitmap = card->mp_wr_bitmap;
+	u32 wr_bitmap = card->mp_wr_bitmap;
 
-	dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
+	dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
 
 	if (!(wr_bitmap & card->mp_data_port_mask))
 		return -1;
 
 	if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
-		card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port));
+		card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
 		*port = card->curr_wr_port;
 		if (++card->curr_wr_port == card->mp_end_port)
 			card->curr_wr_port = 1;
@@ -545,14 +545,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
 	}
 
 	if (*port == CTRL_PORT) {
-		dev_err(adapter->dev, "invalid data port=%d cur port=%d"
-			" mp_wr_bitmap=0x%04x -> 0x%04x\n",
+		dev_err(adapter->dev,
+			"invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
 			*port, card->curr_wr_port, wr_bitmap,
 			card->mp_wr_bitmap);
 		return -1;
 	}
 
-	dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
+	dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
 		*port, wr_bitmap, card->mp_wr_bitmap);
 
 	return 0;
@@ -1024,7 +1024,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 		goto rx_curr_single;
 	}
 
-	if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) {
+	if (card->mp_rd_bitmap & (~((u32) CTRL_PORT_MASK))) {
 		/* Some more data RX pending */
 		dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
 
@@ -1185,9 +1185,9 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 		return ret;
 
 	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
-		card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
-		card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
-		dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
+		card->mp_wr_bitmap = ((u32) card->mp_regs[WR_BITMAP_U]) << 8;
+		card->mp_wr_bitmap |= (u32) card->mp_regs[WR_BITMAP_L];
+		dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%08x\n",
 			card->mp_wr_bitmap);
 		if (adapter->data_sent &&
 		    (card->mp_wr_bitmap & card->mp_data_port_mask)) {
@@ -1204,7 +1204,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 		/* Check if firmware has attach buffer at command port and
 		   update just that in wr_bit_map. */
 		card->mp_wr_bitmap |=
-			(u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
+			(u32) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
 		if (card->mp_wr_bitmap & CTRL_PORT_MASK)
 			adapter->cmd_sent = false;
 	}
@@ -1212,9 +1212,9 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 	dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
 		adapter->cmd_sent, adapter->data_sent);
 	if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
-		card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
-		card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
-		dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
+		card->mp_rd_bitmap = ((u32) card->mp_regs[RD_BITMAP_U]) << 8;
+		card->mp_rd_bitmap |= (u32) card->mp_regs[RD_BITMAP_L];
+		dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%08x\n",
 			card->mp_rd_bitmap);
 
 		while (true) {
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 8cc5468..6588069 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -261,7 +261,7 @@ struct mwifiex_sdio_mpa_tx {
 	u8 *buf;
 	u32 buf_len;
 	u32 pkt_cnt;
-	u16 ports;
+	u32 ports;
 	u16 start_port;
 	u8 enabled;
 	u32 buf_size;
@@ -272,7 +272,7 @@ struct mwifiex_sdio_mpa_rx {
 	u8 *buf;
 	u32 buf_len;
 	u32 pkt_cnt;
-	u16 ports;
+	u32 ports;
 	u16 start_port;
 
 	struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
@@ -290,11 +290,11 @@ struct sdio_mmc_card {
 	struct sdio_func *func;
 	struct mwifiex_adapter *adapter;
 
-	u16 mp_rd_bitmap;
-	u16 mp_wr_bitmap;
+	u32 mp_rd_bitmap;
+	u32 mp_wr_bitmap;
 
 	u16 mp_end_port;
-	u16 mp_data_port_mask;
+	u32 mp_data_port_mask;
 
 	u8 curr_rd_port;
 	u8 curr_wr_port;
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 04/17] mwifiex: abort remaining scan commands when association started
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

A full-channel scan is split to multiple scan commands in driver
before they are sent to firmware. When each scan result is back
the SSID entries are parsed and informed to cfg80211 directly.

It's observed that sometimes userspace may initiate association
as soon as the target AP is found. During the 4-way handshake
firmware may go off-channel to scan the remaining channels.
This causes the 4-way handshake to fail.

Fix it by checking 'scan_block' flag and aborting the remaining
scan in this case. 'scan_block' flag is set after association
and before 4-way handshake. It gets cleared after 4-way handshake
is completed.

Tested-by: Jason Abele <jabele@chromium.org>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/scan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 7b2566b..801b6b7 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1793,7 +1793,8 @@ check_next_scan:
 			dev_dbg(adapter->dev, "info: scan already aborted\n");
 		}
 	} else {
-		if (priv->scan_aborting && !priv->scan_request) {
+		if ((priv->scan_aborting && !priv->scan_request) ||
+		    priv->scan_block) {
 			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
 					       flags);
 			adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 07/17] mwifiex: replace spin_lock_irqsave with spin_lock and fix warn_on
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

We see this WARN_ON during PCIe unload:
WARNING: at kernel/smp.c:382 smp_call_function_many+0x66/0x1e1()

This happens because we are doing PCI iounmap operations while
holding spinlock via spin_lock_irqsave(). Holding spinlock this
way causes disabling IRQs and hence PCI iounmap shows warning on
irqs_disabled() check.

Use non-irq variant of spin_lock i.e. spin_lock() instead.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/init.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 1343725f..c7f11c0 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -687,7 +687,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 	int ret = -EINPROGRESS;
 	struct mwifiex_private *priv;
 	s32 i;
-	unsigned long flags;
 	struct sk_buff *skb;
 
 	/* mwifiex already shutdown */
@@ -722,7 +721,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 		}
 	}
 
-	spin_lock_irqsave(&adapter->mwifiex_lock, flags);
+	spin_lock(&adapter->mwifiex_lock);
 
 	if (adapter->if_ops.data_complete) {
 		while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) {
@@ -738,7 +737,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 
 	mwifiex_adapter_cleanup(adapter);
 
-	spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
+	spin_unlock(&adapter->mwifiex_lock);
 
 	/* Notify completion */
 	ret = mwifiex_shutdown_fw_complete(adapter);
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 01/17] mwifiex: rename mwifiex_free_adapter() routine in init.c
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

We have two different static routines with name
mwifiex_free_adapter(). The routine in main.c actually frees the
adapter structure.

We will rename other routine in init.c to mwifiex_adapter_cleanup()
to avoid confusion.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/init.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 9f44fda..58e151e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -447,17 +447,16 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
 }
 
 /*
- * This function frees the adapter structure.
+ * This function performs cleanup for adapter structure.
  *
- * The freeing operation is done recursively, by canceling all
- * pending commands, freeing the member buffers previously
- * allocated (command buffers, scan table buffer, sleep confirm
- * command buffer), stopping the timers and calling the cleanup
- * routines for every interface, before the actual adapter
- * structure is freed.
+ * The cleanup is done recursively, by canceling all pending
+ * commands, freeing the member buffers previously allocated
+ * (command buffers, scan table buffer, sleep confirm command
+ * buffer), stopping the timers and calling the cleanup routines
+ * for every interface.
  */
 static void
-mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 {
 	if (!adapter) {
 		pr_err("%s: adapter is NULL\n", __func__);
@@ -733,8 +732,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 		}
 	}
 
-	/* Free adapter structure */
-	mwifiex_free_adapter(adapter);
+	mwifiex_adapter_cleanup(adapter);
 
 	spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 05/17] mwifiex: avoid deleting all stations during mwifiex_del_sta_entry()
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

During deleting a station entry from associated sta_list, we are
supposed to delete entry only for this particular mac address.
This patch is a bug fix wherein we were deleting all entries from
list; fix this by removing list_for_each_entry_safe() call.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/uap_event.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 21c640d..77fb533 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -107,18 +107,15 @@ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
  */
 static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
 {
-	struct mwifiex_sta_node *node, *tmp;
+	struct mwifiex_sta_node *node;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->sta_list_spinlock, flags);
 
 	node = mwifiex_get_sta_entry(priv, mac);
 	if (node) {
-		list_for_each_entry_safe(node, tmp, &priv->sta_list,
-					 list) {
-			list_del(&node->list);
-			kfree(node);
-		}
+		list_del(&node->list);
+		kfree(node);
 	}
 
 	spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 02/17] mwifiex: scan delay timer cleanup in unload path
From: Bing Zhao @ 2013-05-14  1:14 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Daniel Drake, Paul Fox, Tim Shepard,
	Jason Abele, John Rhodes, Amitkumar Karwar, Avinash Patil,
	Yogesh Ashok Powar, Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1368494101-23651-1-git-send-email-bzhao@marvell.com>

From: Amitkumar Karwar <akarwar@marvell.com>

Return from scan delay timer routine if surprise_removed flag
is true. Also, cancel the timer in unload path.

This fixes a crash when scan delay timer accesses structures
that have been freed already.

Tested with "iwlist mlan0 scan & sleep 1; rmmod mwifiex_sdio"

Reported-by: Daniel Drake <dsd@laptop.org>
Tested-by: Daniel Drake <dsd@laptop.org>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/init.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 58e151e..71bbf12 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -59,6 +59,9 @@ static void scan_delay_timer_fn(unsigned long data)
 	struct cmd_ctrl_node *cmd_node, *tmp_node;
 	unsigned long flags;
 
+	if (adapter->surprise_removed)
+		return;
+
 	if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
 		/*
 		 * Abort scan operation by cancelling all pending scan
@@ -458,11 +461,18 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
 static void
 mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 {
+	int i;
+
 	if (!adapter) {
 		pr_err("%s: adapter is NULL\n", __func__);
 		return;
 	}
 
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i])
+			del_timer_sync(&adapter->priv[i]->scan_delay_timer);
+	}
+
 	mwifiex_cancel_all_pending_cmd(adapter);
 
 	/* Free lock variables */
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH] mac80211: Move mesh estab_plinks outside mesh_stats debug group
From: Ashok Nagarajan @ 2013-05-14  0:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, johannes, devel, javier, ashok

As estab_plinks is not a statistics member, don't show its debug information
along with other mesh stat members

Signed-off-by: Ashok Nagarajan <ashok@cozybit.com>
---
 net/mac80211/debugfs_netdev.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 14abcf4..f83074f 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -471,6 +471,8 @@ __IEEE80211_IF_FILE_W(tsf);
 IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
 #ifdef CONFIG_MAC80211_MESH
+IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
+
 /* Mesh stats attributes */
 IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
 IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
@@ -480,7 +482,6 @@ IEEE80211_IF_FILE(dropped_frames_congestion,
 		  u.mesh.mshstats.dropped_frames_congestion, DEC);
 IEEE80211_IF_FILE(dropped_frames_no_route,
 		  u.mesh.mshstats.dropped_frames_no_route, DEC);
-IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
 
 /* Mesh parameters */
 IEEE80211_IF_FILE(dot11MeshMaxRetries,
@@ -583,6 +584,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
 {
 	DEBUGFS_ADD_MODE(tsf, 0600);
+	DEBUGFS_ADD_MODE(estab_plinks, 0400);
 }
 
 static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
@@ -598,7 +600,6 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 	MESHSTATS_ADD(dropped_frames_ttl);
 	MESHSTATS_ADD(dropped_frames_no_route);
 	MESHSTATS_ADD(dropped_frames_congestion);
-	MESHSTATS_ADD(estab_plinks);
 #undef MESHSTATS_ADD
 }
 
-- 
1.7.5.4


^ permalink raw reply related

* Unable to link the first time with iwlwifi
From: Felipe Contreras @ 2013-05-13 22:50 UTC (permalink / raw)
  To: linux-wireless, ilw

Hi,

Right after booting when I try to join a network I get nothing:

May 13 17:25:22 nysa kernel: iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
May 13 17:25:22 nysa kernel: iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
May 13 17:25:22 nysa kernel: iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
May 13 17:25:22 nysa kernel: iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
May 13 17:25:22 nysa kernel: IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
May 13 17:25:26 nysa kernel: wlan0: authenticate with e0:1d:3b:46:82:a0
May 13 17:25:26 nysa kernel: wlan0: send auth to e0:1d:3b:46:82:a0 (try 1/3)
May 13 17:25:26 nysa kernel: wlan0: authenticated
May 13 17:25:26 nysa kernel: wlan0: waiting for beacon from e0:1d:3b:46:82:a0
May 13 17:25:29 nysa kernel: wlan0: authenticate with e0:1d:3b:46:82:a0
May 13 17:25:29 nysa kernel: wlan0: send auth to e0:1d:3b:46:82:a0 (try 1/3)
May 13 17:25:29 nysa kernel: wlan0: authenticated

Over and over and over. It never authenticates.

Then if I enable ad-hoc mode in wpa_supplicant:

May 13 17:25:57 nysa kernel: iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
May 13 17:25:57 nysa kernel: iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
May 13 17:25:57 nysa kernel: IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
May 13 17:26:00 nysa kernel: wlan0: Trigger new scan to find an IBSS to join
May 13 17:26:03 nysa kernel: wlan0: Trigger new scan to find an IBSS to join
May 13 17:26:07 nysa kernel: wlan0: Trigger new scan to find an IBSS to join
May 13 17:26:09 nysa kernel: wlan0: Creating new IBSS network, BSSID
86:d6:03:46:b5:54
May 13 17:26:09 nysa kernel: iwlwifi 0000:02:00.0: Unable to find TIM
Element in beacon
May 13 17:26:09 nysa kernel: iwlwifi 0000:02:00.0: Unable to find TIM
Element in beacon
May 13 17:26:09 nysa kernel: IPv6: ADDRCONF(NETDEV_CHANGE): wlan0:
link becomes ready
May 13 17:26:18 nysa kernel: iwlwifi 0000:02:00.0: REPLY_REMOVE_STA failed
May 13 17:26:18 nysa kernel: iwlwifi 0000:02:00.0: failed to remove
IBSS station 00:00:00:00:00:00

Of course, I'm not interested in ad-hoc mode, but when I disable it
and try again:

May 13 17:26:19 nysa kernel: iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
May 13 17:26:19 nysa kernel: iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
May 13 17:26:19 nysa kernel: IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
May 13 17:26:22 nysa kernel: wlan0: authenticate with e0:1d:3b:46:82:a0
May 13 17:26:22 nysa kernel: wlan0: send auth to e0:1d:3b:46:82:a0 (try 1/3)
May 13 17:26:23 nysa kernel: wlan0: send auth to e0:1d:3b:46:82:a0 (try 2/3)
May 13 17:26:23 nysa kernel: wlan0: authenticated
May 13 17:26:23 nysa kernel: wlan0: associating with AP with corrupt beacon
May 13 17:26:23 nysa kernel: wlan0: associate with e0:1d:3b:46:82:a0 (try 1/3)
May 13 17:26:23 nysa kernel: wlan0: associate with e0:1d:3b:46:82:a0 (try 2/3)
May 13 17:26:23 nysa kernel: wlan0: RX AssocResp from
e0:1d:3b:46:82:a0 (capab=0x31 status=0 aid=3)
May 13 17:26:23 nysa kernel: wlan0: associated
May 13 17:26:23 nysa kernel: IPv6: ADDRCONF(NETDEV_CHANGE): wlan0:
link becomes ready

It works this way _every single time_. So I have to with with mode=1,
then with mode=0, _every single time_. It's very annoying and I've
tried everything; I tried with older kernels as far as 3.6.0,
different versions of wpa_supplicant, different module options. It
never works correctly.

Right now I'm on v3.9.2, and the problem is still there. I believe if
I restart the AP, it works, but I haven't tried many times. Also, I
haven't tried other APs (I don't have one readily available).

Any pointers?

Cheers.

-- 
Felipe Contreras

^ permalink raw reply

* [PATCH 3/3] bcma: support SPROM rev 10
From: Rafał Miłecki @ 2013-05-13 20:07 UTC (permalink / raw)
  To: linux-wireless, John W. Linville; +Cc: b43-dev, Rafał Miłecki
In-Reply-To: <1368475673-27587-1-git-send-email-zajec5@gmail.com>

This is pretty much the same as rev 9, there are just 2 extra fields we
know about, but are not used/stored yet anyway.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/bcma/sprom.c         |   16 +++++++++-------
 include/linux/ssb/ssb_regs.h |    1 +
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index c96f71c..de15b4f 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -154,7 +154,8 @@ static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
 	return 0;
 }
 
-static int bcma_sprom_valid(const u16 *sprom, size_t words)
+static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
+			    size_t words)
 {
 	u16 revision;
 	int err;
@@ -164,11 +165,14 @@ static int bcma_sprom_valid(const u16 *sprom, size_t words)
 		return err;
 
 	revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
-	if (revision != 8 && revision != 9) {
+	if (revision != 8 && revision != 9 && revision != 10) {
 		pr_err("Unsupported SPROM revision: %d\n", revision);
 		return -ENOENT;
 	}
 
+	bus->sprom.revision = revision;
+	bcma_debug(bus, "Found SPROM revision %d\n", revision);
+
 	return 0;
 }
 
@@ -208,9 +212,6 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
 			ARRAY_SIZE(bus->sprom.core_pwr_info));
 
-	bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
-		SSB_SPROM_REVISION_REV;
-
 	for (i = 0; i < 3; i++) {
 		v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
 		*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
@@ -549,7 +550,8 @@ int bcma_sprom_get(struct bcma_bus *bus)
 {
 	u16 offset = BCMA_CC_SPROM;
 	u16 *sprom;
-	size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, };
+	size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
+				 SSB_SPROMSIZE_WORDS_R10, };
 	int i, err = 0;
 
 	if (!bus->drv_cc.core)
@@ -592,7 +594,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
 			return -ENOMEM;
 
 		bcma_sprom_read(bus, offset, sprom, words);
-		err = bcma_sprom_valid(sprom, words);
+		err = bcma_sprom_valid(bus, sprom, words);
 		if (!err)
 			break;
 
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 3a72569..f9f931c 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -172,6 +172,7 @@
 #define SSB_SPROMSIZE_WORDS_R4		220
 #define SSB_SPROMSIZE_BYTES_R123	(SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
 #define SSB_SPROMSIZE_BYTES_R4		(SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
+#define SSB_SPROMSIZE_WORDS_R10		230
 #define SSB_SPROM_BASE1			0x1000
 #define SSB_SPROM_BASE31		0x0800
 #define SSB_SPROM_REVISION		0x007E
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/3] bcma: prepare for supporting more SPROM sizes
From: Rafał Miłecki @ 2013-05-13 20:07 UTC (permalink / raw)
  To: linux-wireless, John W. Linville; +Cc: b43-dev, Rafał Miłecki
In-Reply-To: <1368475673-27587-1-git-send-email-zajec5@gmail.com>


Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/bcma/sprom.c |   35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 5386cdd..c96f71c 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -502,7 +502,6 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
 	case BCMA_CHIP_ID_BCM4331:
 		present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
 		break;
-
 	case BCMA_CHIP_ID_BCM43224:
 	case BCMA_CHIP_ID_BCM43225:
 		/* for these chips OTP is always available */
@@ -550,7 +549,8 @@ int bcma_sprom_get(struct bcma_bus *bus)
 {
 	u16 offset = BCMA_CC_SPROM;
 	u16 *sprom;
-	int err = 0;
+	size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, };
+	int i, err = 0;
 
 	if (!bus->drv_cc.core)
 		return -EOPNOTSUPP;
@@ -579,32 +579,37 @@ int bcma_sprom_get(struct bcma_bus *bus)
 		}
 	}
 
-	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
-			GFP_KERNEL);
-	if (!sprom)
-		return -ENOMEM;
-
 	if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
 	    bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
 	bcma_debug(bus, "SPROM offset 0x%x\n", offset);
-	bcma_sprom_read(bus, offset, sprom, SSB_SPROMSIZE_WORDS_R4);
+	for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
+		size_t words = sprom_sizes[i];
+
+		sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
+		if (!sprom)
+			return -ENOMEM;
+
+		bcma_sprom_read(bus, offset, sprom, words);
+		err = bcma_sprom_valid(sprom, words);
+		if (!err)
+			break;
+
+		kfree(sprom);
+	}
 
 	if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
 	    bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
 
-	err = bcma_sprom_valid(sprom, SSB_SPROMSIZE_WORDS_R4);
 	if (err) {
-		bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n");
+		bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
 		err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
-		goto out;
+	} else {
+		bcma_sprom_extract_r8(bus, sprom);
+		kfree(sprom);
 	}
 
-	bcma_sprom_extract_r8(bus, sprom);
-
-out:
-	kfree(sprom);
 	return err;
 }
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/3] bcma: don't hardcode SPROM length
From: Rafał Miłecki @ 2013-05-13 20:07 UTC (permalink / raw)
  To: linux-wireless, John W. Linville; +Cc: b43-dev, Rafał Miłecki

Pass it as an argument to all functions. This is requires as newer SPROM
revisions have different lengths.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/bcma/sprom.c |   30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 8934298..5386cdd 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -72,12 +72,12 @@ fail:
  * R/W ops.
  **************************************************/
 
-static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
+			    size_t words)
 {
 	int i;
-	for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
-		sprom[i] = bcma_read16(bus->drv_cc.core,
-				       offset + (i * 2));
+	for (i = 0; i < words; i++)
+		sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
 }
 
 /**************************************************
@@ -124,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 data)
 	return t[crc ^ data];
 }
 
-static u8 bcma_sprom_crc(const u16 *sprom)
+static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
 {
 	int word;
 	u8 crc = 0xFF;
 
-	for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
+	for (word = 0; word < words - 1; word++) {
 		crc = bcma_crc8(crc, sprom[word] & 0x00FF);
 		crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
 	}
-	crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
+	crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
 	crc ^= 0xFF;
 
 	return crc;
 }
 
-static int bcma_sprom_check_crc(const u16 *sprom)
+static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
 {
 	u8 crc;
 	u8 expected_crc;
 	u16 tmp;
 
-	crc = bcma_sprom_crc(sprom);
-	tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
+	crc = bcma_sprom_crc(sprom, words);
+	tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
 	expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
 	if (crc != expected_crc)
 		return -EPROTO;
@@ -154,16 +154,16 @@ static int bcma_sprom_check_crc(const u16 *sprom)
 	return 0;
 }
 
-static int bcma_sprom_valid(const u16 *sprom)
+static int bcma_sprom_valid(const u16 *sprom, size_t words)
 {
 	u16 revision;
 	int err;
 
-	err = bcma_sprom_check_crc(sprom);
+	err = bcma_sprom_check_crc(sprom, words);
 	if (err)
 		return err;
 
-	revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
+	revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
 	if (revision != 8 && revision != 9) {
 		pr_err("Unsupported SPROM revision: %d\n", revision);
 		return -ENOENT;
@@ -589,13 +589,13 @@ int bcma_sprom_get(struct bcma_bus *bus)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
 	bcma_debug(bus, "SPROM offset 0x%x\n", offset);
-	bcma_sprom_read(bus, offset, sprom);
+	bcma_sprom_read(bus, offset, sprom, SSB_SPROMSIZE_WORDS_R4);
 
 	if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
 	    bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
 
-	err = bcma_sprom_valid(sprom);
+	err = bcma_sprom_valid(sprom, SSB_SPROMSIZE_WORDS_R4);
 	if (err) {
 		bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n");
 		err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] B43: Handle DMA RX descriptor underrun
From: Thommy Jakobsson @ 2013-05-13 18:27 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: linville, linux-wireless, b43-dev, m, piotras, Larry.Finger
In-Reply-To: <CACna6rxWPOqQPNUaASaj=v=O+Wjt0okjX4jNwE3tv-=etfATCg@mail.gmail.com>



On Sun, 5 May 2013, Rafa? Mi?ecki wrote:

> I think we may want turning this interrupt anyway, but I wonder if
> there is another issue we just hide a bit better.
> 
Any news on the testing Rafael? Did you have any more questions about the 
solution? Just let me know if I can help

//Thommy

^ permalink raw reply

* Re: [ath5k-devel] [PATCH] ath5k: Remove AHB bus support.
From: Luis R. Rodriguez @ 2013-05-13 17:43 UTC (permalink / raw)
  To: Adrian Chadd
  Cc: Jonathan Bither, linux-wireless, Paul Bolle, Jiri Slaby,
	Wojciech Dubowik, ath5k-devel@lists.ath5k.org, John W. Linville,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <CAJ-Vmo=HOFqu8vB1=pvz79YwE8qAMDc4ZJACJHaSuxn4S92sFg@mail.gmail.com>

On Mon, May 13, 2013 at 10:09 AM, Adrian Chadd <adrian@freebsd.org> wrote:
> On 13 May 2013 09:39, Jonathan Bither <jonbither@gmail.com> wrote:
>
>>> ... is anyone using this on openwrt?
>>>
>> I am.
>> I am also reworking AR2131X drivers and will submit a patch to linux-mips
>> shortly.
>
> Sweet. Someone say NACK then? :)

NACK, looking forward to the linux-mips patches, in the future however
we want to avoid these type of placeholder patches.

  Luis

^ permalink raw reply

* Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band
From: Ashok Nagarajan @ 2013-05-13 17:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville, devel
In-Reply-To: <1368465499.8300.33.camel@jlt4.sipsolutions.net>

On Mon, May 13, 2013 at 10:18 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Mon, 2013-05-13 at 10:13 -0700, Ashok Nagarajan wrote:
>> On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>> > On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
>> >> This patch assumes 11g support
>> >> implies a 11g operation and returns the appropriate mandatory rates.
>> >
>> > Which is a problem, because it means that by default we'll create IBSS
>> > networks that are not compatible with 11b devices.
>>
>> Okay make sense. I would drop just this patch and send rest.
>
> If you just want the others as is I can do that, no need to resend. Let
> me know.
>
Yes, the rest would be as it is now. That would work.

Thanks,
Ashok
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

^ permalink raw reply

* Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band
From: Johannes Berg @ 2013-05-13 17:18 UTC (permalink / raw)
  To: Ashok Nagarajan; +Cc: linux-wireless, John Linville, devel
In-Reply-To: <CACcxo+odk2L-pymHqof+geeEmKcC4xikebra9jcNZoHOF0by4A@mail.gmail.com>

On Mon, 2013-05-13 at 10:13 -0700, Ashok Nagarajan wrote:
> On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
> >> This patch assumes 11g support
> >> implies a 11g operation and returns the appropriate mandatory rates.
> >
> > Which is a problem, because it means that by default we'll create IBSS
> > networks that are not compatible with 11b devices.
> 
> Okay make sense. I would drop just this patch and send rest.

If you just want the others as is I can do that, no need to resend. Let
me know.

johannes


^ permalink raw reply

* Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band
From: Ashok Nagarajan @ 2013-05-13 17:13 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville, devel
In-Reply-To: <1368438160.8300.11.camel@jlt4.sipsolutions.net>

On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
>> This patch assumes 11g support
>> implies a 11g operation and returns the appropriate mandatory rates.
>
> Which is a problem, because it means that by default we'll create IBSS
> networks that are not compatible with 11b devices.

Okay make sense. I would drop just this patch and send rest.

Thanks,
Ashok
>
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

^ permalink raw reply

* Re: [PATCH] ath5k: Remove AHB bus support.
From: Adrian Chadd @ 2013-05-13 17:09 UTC (permalink / raw)
  To: Jonathan Bither
  Cc: Paul Bolle, Jiri Slaby, Nick Kossifidis, Luis R. Rodriguez,
	John W. Linville, Bob Copeland, Wojciech Dubowik, nbd,
	ath5k-devel, linux-wireless, netdev, linux-kernel
In-Reply-To: <5191173D.3070709@gmail.com>

On 13 May 2013 09:39, Jonathan Bither <jonbither@gmail.com> wrote:

>> ... is anyone using this on openwrt?
>>
> I am.
> I am also reworking AR2131X drivers and will submit a patch to linux-mips
> shortly.

Sweet. Someone say NACK then? :)



Adrian

^ permalink raw reply

* [RHEL 6.5 PATCH 169/176] brcmsmac: fix u16 overflow warning
From: John Greene @ 2013-05-13 15:47 UTC (permalink / raw)
  To: rhkernel-list
  Cc: John Greene, Brett Rudley, Arend van Spriel, Franky (Zhenhui) Lin,
	Hante Meuleman, John W. Linville, Pieter-Paul Giesberts,
	Seth Forshee, Hauke Mehrtens, linux-wireless, brcm80211-dev-list,
	netdev, Tim Gardner
In-Reply-To: <1368460038-21195-1-git-send-email-jogreene@redhat.com>

Bugzilla: 757944
Brew: <https://brewweb.devel.redhat.com/taskinfo?taskID=5738553>
Upstream Status: 708eb54f20334470ad92042547db0fef0cd60462
Tested: By me. Acceptable. See BZ for details

DOT11_MIN_BEACON_PERIOD and DOT11_MAX_BEACON_PERIOD are
superfluous. The only invalid beacon period is 0. Comparing
a 16 bit quantity to 0xffff also causes a compile warning:

drivers/net/wireless/brcm80211/brcmsmac/main.c:5560 brcms_c_set_beacon_period()
 warn: impossible condition '(period > 65535) => (0-65535 > 65535)'

Observed from smatch analysis.

Cc: Brett Rudley <brudley@broadcom.com>
Cc: Arend van Spriel <arend@broadcom.com>
Cc: "Franky (Zhenhui) Lin" <frankyl@broadcom.com>
Cc: Hante Meuleman <meuleman@broadcom.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Cc: Seth Forshee <seth.forshee@canonical.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: linux-wireless@vger.kernel.org
Cc: brcm80211-dev-list@broadcom.com
Cc: netdev@vger.kernel.org
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/main.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 5c50b79..c72fbab 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -101,8 +101,6 @@
 #define DOT11_RTS_LEN			16
 #define DOT11_CTS_LEN			10
 #define DOT11_BA_BITMAP_LEN		128
-#define DOT11_MIN_BEACON_PERIOD		1
-#define DOT11_MAX_BEACON_PERIOD		0xFFFF
 #define DOT11_MAXNUMFRAGS		16
 #define DOT11_MAX_FRAG_LEN		2346
 
@@ -5548,8 +5546,7 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
 
 int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
 {
-	if (period < DOT11_MIN_BEACON_PERIOD ||
-	    period > DOT11_MAX_BEACON_PERIOD)
+	if (period == 0)
 		return -EINVAL;
 
 	wlc->default_bss->beacon_period = period;
-- 
1.7.11.7


^ permalink raw reply related

* [RHEL 6.5 PATCH 170/176] brcmsmac: avoid 512 byte stack variable
From: John Greene @ 2013-05-13 15:47 UTC (permalink / raw)
  To: rhkernel-list
  Cc: John Greene, Brett Rudley, Arend van Spriel, Franky (Zhenhui) Lin,
	Hante Meuleman, John W. Linville, Seth Forshee,
	Pieter-Paul Giesberts, Hauke Mehrtens, linux-wireless,
	brcm80211-dev-list, netdev, Tim Gardner
In-Reply-To: <1368460038-21195-1-git-send-email-jogreene@redhat.com>

Bugzilla: 757944
Brew: <https://brewweb.devel.redhat.com/taskinfo?taskID=5738553>
Upstream Status: 0d61c9177cb9bf48dcec9c3d9205a309085d4318
Tested: By me. Acceptable. See BZ for details

Dynamically allocate the probe response template which
avoids potential stack corruption. Observed with smatch:

drivers/net/wireless/brcm80211/brcmsmac/main.c:7412 brcms_c_bss_update_probe_resp()
 warn: 'prb_resp' puts 512 bytes on stack

Cc: Brett Rudley <brudley@broadcom.com>
Cc: Arend van Spriel <arend@broadcom.com>
Cc: "Franky (Zhenhui) Lin" <frankyl@broadcom.com>
Cc: Hante Meuleman <meuleman@broadcom.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Seth Forshee <seth.forshee@canonical.com>
Cc: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: linux-wireless@vger.kernel.org
Cc: brcm80211-dev-list@broadcom.com
Cc: netdev@vger.kernel.org
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/main.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index c72fbab..8ec610e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7398,9 +7398,13 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
 			      struct brcms_bss_cfg *cfg,
 			      bool suspend)
 {
-	u16 prb_resp[BCN_TMPL_LEN / 2];
+	u16 *prb_resp;
 	int len = BCN_TMPL_LEN;
 
+	prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
+	if (!prb_resp)
+		return;
+
 	/*
 	 * write the probe response to hardware, or save in
 	 * the config structure
@@ -7434,6 +7438,8 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
 
 	if (suspend)
 		brcms_c_enable_mac(wlc);
+
+	kfree(prb_resp);
 }
 
 void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
-- 
1.7.11.7


^ permalink raw reply related

* [RHEL 6.5 PATCH 087/176] bcma: suspend/resume callbacks should be conditionally compiled on CONFIG_PM_SLEEP
From: John Greene @ 2013-05-13 15:45 UTC (permalink / raw)
  To: rhkernel-list
  Cc: John Greene, John W. Linville, Rafał Miłecki,
	linux-wireless, Yuanhan Liu, Fengguang Wu
In-Reply-To: <1368460038-21195-1-git-send-email-jogreene@redhat.com>

Bugzilla: 757944
Brew: <https://brewweb.devel.redhat.com/taskinfo?taskID=5738553>
Upstream Status: ccd609538e99d3465a8d498f3655098f44cd253b
Tested: By me. Acceptable. See BZ for details

This will fix warnings like following when CONFIG_PM_SLEEP is not set:

        warning: 'xxx_suspend' defined but not used [-Wunused-function]
        warning: 'xxx_resume' defined but not used [-Wunused-function]

Because
	SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)

Only references the callbacks on CONFIG_PM_SLEEP (instead of CONFIG_PM).

Cc: John W. Linville <linville@tuxdriver.com>
Cc: "Rafał Miłecki" <zajec5@gmail.com>
Cc: linux-wireless@vger.kernel.org
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/bcma/host_pci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index b6b4b5e..98fdc3e 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -238,7 +238,7 @@ static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
 	pci_set_drvdata(dev, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int bcma_host_pci_suspend(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -261,11 +261,11 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
 			 bcma_host_pci_resume);
 #define BCMA_PM_OPS	(&bcma_pm_ops)
 
-#else /* CONFIG_PM */
+#else /* CONFIG_PM_SLEEP */
 
 #define BCMA_PM_OPS     NULL
 
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH] ath5k: Remove AHB bus support.
From: Jonathan Bither @ 2013-05-13 16:39 UTC (permalink / raw)
  To: Adrian Chadd
  Cc: Paul Bolle, Jiri Slaby, Nick Kossifidis, Luis R. Rodriguez,
	John W. Linville, Bob Copeland, Wojciech Dubowik, nbd,
	ath5k-devel, linux-wireless, netdev, linux-kernel
In-Reply-To: <CAJ-VmokciVPxzJ0LptdQyL9koa8Bw7ecJdentPH5q9+MQ4=GpA@mail.gmail.com>



On 05/13/2013 11:11 AM, Adrian Chadd wrote:
> ... is anyone using this on openwrt?
>
I am.
I am also reworking AR2131X drivers and will submit a patch to 
linux-mips shortly.
>
>
>
> Adrian
>
> On 13 May 2013 08:03, Paul Bolle <pebolle@tiscali.nl> wrote:
>> AHB bus support was added in v2.6.38, through commit a0b907ee2a ("ath5k:
>> Add AHB bus support."). That code can only be build if the Kconfig
>> symbol ATHEROS_AR231X is set. But that symbol has never been added to
>> the tree. So AHB bus support has always been dead code.
>>
>> Let's remove all code that depends on ATHEROS_AR231X. If that symbol
>> ever gets added to the tree the AHB bus support can be re-added too.
>>
>> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
>> ---
>> 0) Compile tested (I do not think I have hardware that use the ath5k
>> driver).
>>
>> 1) I mentioned the missing ATHEROS_AR231X symbol three times before (in
>> August 2011, in July 2012 and in March 2103). Nobody stepped forward to
>> tell me they were actually working on adding that symbol somehow. So
>> let's see how people react when I submit a patch to remove the (dead)
>> AHB bus support.
>>
>>   drivers/net/wireless/ath/ath5k/Kconfig  |  14 +-
>>   drivers/net/wireless/ath/ath5k/Makefile |   1 -
>>   drivers/net/wireless/ath/ath5k/ahb.c    | 239 --------------------------------
>>   drivers/net/wireless/ath/ath5k/ath5k.h  |  28 ----
>>   drivers/net/wireless/ath/ath5k/base.c   |  14 --
>>   drivers/net/wireless/ath/ath5k/led.c    |   6 -
>>   6 files changed, 3 insertions(+), 299 deletions(-)
>>   delete mode 100644 drivers/net/wireless/ath/ath5k/ahb.c
>>
>> diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
>> index c9f81a3..93caf8e68 100644
>> --- a/drivers/net/wireless/ath/ath5k/Kconfig
>> +++ b/drivers/net/wireless/ath/ath5k/Kconfig
>> @@ -1,13 +1,12 @@
>>   config ATH5K
>>          tristate "Atheros 5xxx wireless cards support"
>> -       depends on (PCI || ATHEROS_AR231X) && MAC80211
>> +       depends on PCI && MAC80211
>>          select ATH_COMMON
>>          select MAC80211_LEDS
>>          select LEDS_CLASS
>>          select NEW_LEDS
>>          select AVERAGE
>> -       select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
>> -       select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
>> +       select ATH5K_PCI
>>          ---help---
>>            This module adds support for wireless adapters based on
>>            Atheros 5xxx chipset.
>> @@ -52,16 +51,9 @@ config ATH5K_TRACER
>>
>>            If unsure, say N.
>>
>> -config ATH5K_AHB
>> -       bool "Atheros 5xxx AHB bus support"
>> -       depends on (ATHEROS_AR231X && !PCI)
>> -       ---help---
>> -         This adds support for WiSoC type chipsets of the 5xxx Atheros
>> -         family.
>> -
>>   config ATH5K_PCI
>>          bool "Atheros 5xxx PCI bus support"
>> -       depends on (!ATHEROS_AR231X && PCI)
>> +       depends on PCI
>>          ---help---
>>            This adds support for PCI type chipsets of the 5xxx Atheros
>>            family.
>> diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
>> index 1b3a34f..51e2d86 100644
>> --- a/drivers/net/wireless/ath/ath5k/Makefile
>> +++ b/drivers/net/wireless/ath/ath5k/Makefile
>> @@ -17,6 +17,5 @@ ath5k-y                               += ani.o
>>   ath5k-y                                += sysfs.o
>>   ath5k-y                                += mac80211-ops.o
>>   ath5k-$(CONFIG_ATH5K_DEBUG)    += debug.o
>> -ath5k-$(CONFIG_ATH5K_AHB)      += ahb.o
>>   ath5k-$(CONFIG_ATH5K_PCI)      += pci.o
>>   obj-$(CONFIG_ATH5K)            += ath5k.o
>> diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
>> deleted file mode 100644
>> index 8e8bcc7a..0000000
>> --- a/drivers/net/wireless/ath/ath5k/ahb.c
>> +++ /dev/null
>> @@ -1,239 +0,0 @@
>> -/*
>> - * Copyright (c) 2008-2009 Atheros Communications Inc.
>> - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
>> - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
>> - *
>> - * Permission to use, copy, modify, and/or distribute this software for any
>> - * purpose with or without fee is hereby granted, provided that the above
>> - * copyright notice and this permission notice appear in all copies.
>> - *
>> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
>> - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
>> - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
>> - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>> - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>> - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> - */
>> -
>> -#include <linux/nl80211.h>
>> -#include <linux/platform_device.h>
>> -#include <linux/etherdevice.h>
>> -#include <linux/export.h>
>> -#include <ar231x_platform.h>
>> -#include "ath5k.h"
>> -#include "debug.h"
>> -#include "base.h"
>> -#include "reg.h"
>> -
>> -/* return bus cachesize in 4B word units */
>> -static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
>> -{
>> -       *csz = L1_CACHE_BYTES >> 2;
>> -}
>> -
>> -static bool
>> -ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
>> -{
>> -       struct ath5k_hw *ah = common->priv;
>> -       struct platform_device *pdev = to_platform_device(ah->dev);
>> -       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
>> -       u16 *eeprom, *eeprom_end;
>> -
>> -
>> -
>> -       bcfg = pdev->dev.platform_data;
>> -       eeprom = (u16 *) bcfg->radio;
>> -       eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
>> -
>> -       eeprom += off;
>> -       if (eeprom > eeprom_end)
>> -               return false;
>> -
>> -       *data = *eeprom;
>> -       return true;
>> -}
>> -
>> -int ath5k_hw_read_srev(struct ath5k_hw *ah)
>> -{
>> -       struct platform_device *pdev = to_platform_device(ah->dev);
>> -       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
>> -       ah->ah_mac_srev = bcfg->devid;
>> -       return 0;
>> -}
>> -
>> -static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
>> -{
>> -       struct platform_device *pdev = to_platform_device(ah->dev);
>> -       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
>> -       u8 *cfg_mac;
>> -
>> -       if (to_platform_device(ah->dev)->id == 0)
>> -               cfg_mac = bcfg->config->wlan0_mac;
>> -       else
>> -               cfg_mac = bcfg->config->wlan1_mac;
>> -
>> -       memcpy(mac, cfg_mac, ETH_ALEN);
>> -       return 0;
>> -}
>> -
>> -static const struct ath_bus_ops ath_ahb_bus_ops = {
>> -       .ath_bus_type = ATH_AHB,
>> -       .read_cachesize = ath5k_ahb_read_cachesize,
>> -       .eeprom_read = ath5k_ahb_eeprom_read,
>> -       .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
>> -};
>> -
>> -/*Initialization*/
>> -static int ath_ahb_probe(struct platform_device *pdev)
>> -{
>> -       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
>> -       struct ath5k_hw *ah;
>> -       struct ieee80211_hw *hw;
>> -       struct resource *res;
>> -       void __iomem *mem;
>> -       int irq;
>> -       int ret = 0;
>> -       u32 reg;
>> -
>> -       if (!pdev->dev.platform_data) {
>> -               dev_err(&pdev->dev, "no platform data specified\n");
>> -               ret = -EINVAL;
>> -               goto err_out;
>> -       }
>> -
>> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> -       if (res == NULL) {
>> -               dev_err(&pdev->dev, "no memory resource found\n");
>> -               ret = -ENXIO;
>> -               goto err_out;
>> -       }
>> -
>> -       mem = ioremap_nocache(res->start, resource_size(res));
>> -       if (mem == NULL) {
>> -               dev_err(&pdev->dev, "ioremap failed\n");
>> -               ret = -ENOMEM;
>> -               goto err_out;
>> -       }
>> -
>> -       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
>> -       if (res == NULL) {
>> -               dev_err(&pdev->dev, "no IRQ resource found\n");
>> -               ret = -ENXIO;
>> -               goto err_iounmap;
>> -       }
>> -
>> -       irq = res->start;
>> -
>> -       hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
>> -       if (hw == NULL) {
>> -               dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
>> -               ret = -ENOMEM;
>> -               goto err_iounmap;
>> -       }
>> -
>> -       ah = hw->priv;
>> -       ah->hw = hw;
>> -       ah->dev = &pdev->dev;
>> -       ah->iobase = mem;
>> -       ah->irq = irq;
>> -       ah->devid = bcfg->devid;
>> -
>> -       if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
>> -               /* Enable WMAC AHB arbitration */
>> -               reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
>> -               reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
>> -               iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
>> -
>> -               /* Enable global WMAC swapping */
>> -               reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
>> -               reg |= AR5K_AR2315_BYTESWAP_WMAC;
>> -               iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
>> -       } else {
>> -               /* Enable WMAC DMA access (assuming 5312 or 231x*/
>> -               /* TODO: check other platforms */
>> -               reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
>> -               if (to_platform_device(ah->dev)->id == 0)
>> -                       reg |= AR5K_AR5312_ENABLE_WLAN0;
>> -               else
>> -                       reg |= AR5K_AR5312_ENABLE_WLAN1;
>> -               iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
>> -
>> -               /*
>> -                * On a dual-band AR5312, the multiband radio is only
>> -                * used as pass-through. Disable 2 GHz support in the
>> -                * driver for it
>> -                */
>> -               if (to_platform_device(ah->dev)->id == 0 &&
>> -                   (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
>> -                    (BD_WLAN1 | BD_WLAN0))
>> -                       ah->ah_capabilities.cap_needs_2GHz_ovr = true;
>> -               else
>> -                       ah->ah_capabilities.cap_needs_2GHz_ovr = false;
>> -       }
>> -
>> -       ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
>> -       if (ret != 0) {
>> -               dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
>> -               ret = -ENODEV;
>> -               goto err_free_hw;
>> -       }
>> -
>> -       platform_set_drvdata(pdev, hw);
>> -
>> -       return 0;
>> -
>> - err_free_hw:
>> -       ieee80211_free_hw(hw);
>> -       platform_set_drvdata(pdev, NULL);
>> - err_iounmap:
>> -        iounmap(mem);
>> - err_out:
>> -       return ret;
>> -}
>> -
>> -static int ath_ahb_remove(struct platform_device *pdev)
>> -{
>> -       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
>> -       struct ieee80211_hw *hw = platform_get_drvdata(pdev);
>> -       struct ath5k_hw *ah;
>> -       u32 reg;
>> -
>> -       if (!hw)
>> -               return 0;
>> -
>> -       ah = hw->priv;
>> -
>> -       if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
>> -               /* Disable WMAC AHB arbitration */
>> -               reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
>> -               reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
>> -               iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
>> -       } else {
>> -               /*Stop DMA access */
>> -               reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
>> -               if (to_platform_device(ah->dev)->id == 0)
>> -                       reg &= ~AR5K_AR5312_ENABLE_WLAN0;
>> -               else
>> -                       reg &= ~AR5K_AR5312_ENABLE_WLAN1;
>> -               iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
>> -       }
>> -
>> -       ath5k_deinit_ah(ah);
>> -       iounmap(ah->iobase);
>> -       platform_set_drvdata(pdev, NULL);
>> -       ieee80211_free_hw(hw);
>> -
>> -       return 0;
>> -}
>> -
>> -static struct platform_driver ath_ahb_driver = {
>> -       .probe      = ath_ahb_probe,
>> -       .remove     = ath_ahb_remove,
>> -       .driver         = {
>> -               .name   = "ar231x-wmac",
>> -               .owner  = THIS_MODULE,
>> -       },
>> -};
>> -
>> -module_platform_driver(ath_ahb_driver);
>> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
>> index 2d691b8..deaedb8 100644
>> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
>> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
>> @@ -1645,32 +1645,6 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
>>          return &(ath5k_hw_common(ah)->regulatory);
>>   }
>>
>> -#ifdef CONFIG_ATHEROS_AR231X
>> -#define AR5K_AR2315_PCI_BASE   ((void __iomem *)0xb0100000)
>> -
>> -static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
>> -{
>> -       /* On AR2315 and AR2317 the PCI clock domain registers
>> -        * are outside of the WMAC register space */
>> -       if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
>> -           (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
>> -               return AR5K_AR2315_PCI_BASE + reg;
>> -
>> -       return ah->iobase + reg;
>> -}
>> -
>> -static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
>> -{
>> -       return ioread32(ath5k_ahb_reg(ah, reg));
>> -}
>> -
>> -static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
>> -{
>> -       iowrite32(val, ath5k_ahb_reg(ah, reg));
>> -}
>> -
>> -#else
>> -
>>   static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
>>   {
>>          return ioread32(ah->iobase + reg);
>> @@ -1681,8 +1655,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
>>          iowrite32(val, ah->iobase + reg);
>>   }
>>
>> -#endif
>> -
>>   static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
>>   {
>>          return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
>> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
>> index 9b20d9e..654cc3d 100644
>> --- a/drivers/net/wireless/ath/ath5k/base.c
>> +++ b/drivers/net/wireless/ath/ath5k/base.c
>> @@ -97,15 +97,6 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
>>
>>   /* Known SREVs */
>>   static const struct ath5k_srev_name srev_names[] = {
>> -#ifdef CONFIG_ATHEROS_AR231X
>> -       { "5312",       AR5K_VERSION_MAC,       AR5K_SREV_AR5312_R2 },
>> -       { "5312",       AR5K_VERSION_MAC,       AR5K_SREV_AR5312_R7 },
>> -       { "2313",       AR5K_VERSION_MAC,       AR5K_SREV_AR2313_R8 },
>> -       { "2315",       AR5K_VERSION_MAC,       AR5K_SREV_AR2315_R6 },
>> -       { "2315",       AR5K_VERSION_MAC,       AR5K_SREV_AR2315_R7 },
>> -       { "2317",       AR5K_VERSION_MAC,       AR5K_SREV_AR2317_R1 },
>> -       { "2317",       AR5K_VERSION_MAC,       AR5K_SREV_AR2317_R2 },
>> -#else
>>          { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
>>          { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
>>          { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
>> @@ -124,7 +115,6 @@ static const struct ath5k_srev_name srev_names[] = {
>>          { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
>>          { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
>>          { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
>> -#endif
>>          { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
>>          { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
>>          { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
>> @@ -140,10 +130,6 @@ static const struct ath5k_srev_name srev_names[] = {
>>          { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
>>          { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
>>          { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
>> -#ifdef CONFIG_ATHEROS_AR231X
>> -       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
>> -       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
>> -#endif
>>          { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
>>   };
>>
>> diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
>> index f77ef36..dbf2483 100644
>> --- a/drivers/net/wireless/ath/ath5k/led.c
>> +++ b/drivers/net/wireless/ath/ath5k/led.c
>> @@ -162,20 +162,14 @@ int ath5k_init_leds(struct ath5k_hw *ah)
>>   {
>>          int ret = 0;
>>          struct ieee80211_hw *hw = ah->hw;
>> -#ifndef CONFIG_ATHEROS_AR231X
>>          struct pci_dev *pdev = ah->pdev;
>> -#endif
>>          char name[ATH5K_LED_MAX_NAME_LEN + 1];
>>          const struct pci_device_id *match;
>>
>>          if (!ah->pdev)
>>                  return 0;
>>
>> -#ifdef CONFIG_ATHEROS_AR231X
>> -       match = NULL;
>> -#else
>>          match = pci_match_id(&ath5k_led_devices[0], pdev);
>> -#endif
>>          if (match) {
>>                  __set_bit(ATH_STAT_LEDSOFT, ah->status);
>>                  ah->led_pin = ATH_PIN(match->driver_data);
>> --
>> 1.7.11.7
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Capturing on monitor interface at higher speeds?
From: Ben Greear @ 2013-05-13 16:00 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org



Some quick testing showed we can only capture at around 230Mbps using
tshark and writing to file (on an SSD file system).  Lots of dropped
pkts reported by tshark.

I haven't looked yet at any details, but I'm curious if anyone has
successfully captured wifi at 340Mbps+ on a moderately powerful system?

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: [PATCH] ath5k: Remove AHB bus support.
From: Oleksij Rempel @ 2013-05-13 15:20 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Jiri Slaby, Nick Kossifidis, Luis R. Rodriguez, John W. Linville,
	Bob Copeland, Wojciech Dubowik, nbd, ath5k-devel, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <1368457391.1350.67.camel@x61.thuisdomein>

Hmm... i'm working right now to make ar231x device work with upstream
sources. First think is boot loader. There are is a ar231x fork of 
redboot, but i decided to go barebox. See:
https://github.com/olerem/barebox/commits/atheros
there one more barebox dev on it, so i think we will get it.

Next step will be to check why ar231x patches are not in upstream 
kernel. After i ported ar231x-eth driver to barebox, i can assume why it 
is not included - it need some more work. Or may be there are other reasons.

Currently i do not know how AHB bus related to ATHEROS_AR231X.

Am 13.05.2013 17:03, schrieb Paul Bolle:
> AHB bus support was added in v2.6.38, through commit a0b907ee2a ("ath5k:
> Add AHB bus support."). That code can only be build if the Kconfig
> symbol ATHEROS_AR231X is set. But that symbol has never been added to
> the tree. So AHB bus support has always been dead code.
>
> Let's remove all code that depends on ATHEROS_AR231X. If that symbol
> ever gets added to the tree the AHB bus support can be re-added too.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
> ---
> 0) Compile tested (I do not think I have hardware that use the ath5k
> driver).
>
> 1) I mentioned the missing ATHEROS_AR231X symbol three times before (in
> August 2011, in July 2012 and in March 2103). Nobody stepped forward to
> tell me they were actually working on adding that symbol somehow. So
> let's see how people react when I submit a patch to remove the (dead)
> AHB bus support.
>
>   drivers/net/wireless/ath/ath5k/Kconfig  |  14 +-
>   drivers/net/wireless/ath/ath5k/Makefile |   1 -
>   drivers/net/wireless/ath/ath5k/ahb.c    | 239 --------------------------------
>   drivers/net/wireless/ath/ath5k/ath5k.h  |  28 ----
>   drivers/net/wireless/ath/ath5k/base.c   |  14 --
>   drivers/net/wireless/ath/ath5k/led.c    |   6 -
>   6 files changed, 3 insertions(+), 299 deletions(-)
>   delete mode 100644 drivers/net/wireless/ath/ath5k/ahb.c
>
> diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
> index c9f81a3..93caf8e68 100644
> --- a/drivers/net/wireless/ath/ath5k/Kconfig
> +++ b/drivers/net/wireless/ath/ath5k/Kconfig
> @@ -1,13 +1,12 @@
>   config ATH5K
>   	tristate "Atheros 5xxx wireless cards support"
> -	depends on (PCI || ATHEROS_AR231X) && MAC80211
> +	depends on PCI && MAC80211
>   	select ATH_COMMON
>   	select MAC80211_LEDS
>   	select LEDS_CLASS
>   	select NEW_LEDS
>   	select AVERAGE
> -	select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
> -	select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
> +	select ATH5K_PCI
>   	---help---
>   	  This module adds support for wireless adapters based on
>   	  Atheros 5xxx chipset.
> @@ -52,16 +51,9 @@ config ATH5K_TRACER
>
>   	  If unsure, say N.
>
> -config ATH5K_AHB
> -	bool "Atheros 5xxx AHB bus support"
> -	depends on (ATHEROS_AR231X && !PCI)
> -	---help---
> -	  This adds support for WiSoC type chipsets of the 5xxx Atheros
> -	  family.
> -
>   config ATH5K_PCI
>   	bool "Atheros 5xxx PCI bus support"
> -	depends on (!ATHEROS_AR231X && PCI)
> +	depends on PCI
>   	---help---
>   	  This adds support for PCI type chipsets of the 5xxx Atheros
>   	  family.
> diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
> index 1b3a34f..51e2d86 100644
> --- a/drivers/net/wireless/ath/ath5k/Makefile
> +++ b/drivers/net/wireless/ath/ath5k/Makefile
> @@ -17,6 +17,5 @@ ath5k-y				+= ani.o
>   ath5k-y				+= sysfs.o
>   ath5k-y				+= mac80211-ops.o
>   ath5k-$(CONFIG_ATH5K_DEBUG)	+= debug.o
> -ath5k-$(CONFIG_ATH5K_AHB)	+= ahb.o
>   ath5k-$(CONFIG_ATH5K_PCI)	+= pci.o
>   obj-$(CONFIG_ATH5K)		+= ath5k.o
> diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
> deleted file mode 100644
> index 8e8bcc7a..0000000
> --- a/drivers/net/wireless/ath/ath5k/ahb.c
> +++ /dev/null
> @@ -1,239 +0,0 @@
> -/*
> - * Copyright (c) 2008-2009 Atheros Communications Inc.
> - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
> - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
> - *
> - * Permission to use, copy, modify, and/or distribute this software for any
> - * purpose with or without fee is hereby granted, provided that the above
> - * copyright notice and this permission notice appear in all copies.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> - */
> -
> -#include <linux/nl80211.h>
> -#include <linux/platform_device.h>
> -#include <linux/etherdevice.h>
> -#include <linux/export.h>
> -#include <ar231x_platform.h>
> -#include "ath5k.h"
> -#include "debug.h"
> -#include "base.h"
> -#include "reg.h"
> -
> -/* return bus cachesize in 4B word units */
> -static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
> -{
> -	*csz = L1_CACHE_BYTES >> 2;
> -}
> -
> -static bool
> -ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
> -{
> -	struct ath5k_hw *ah = common->priv;
> -	struct platform_device *pdev = to_platform_device(ah->dev);
> -	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
> -	u16 *eeprom, *eeprom_end;
> -
> -
> -
> -	bcfg = pdev->dev.platform_data;
> -	eeprom = (u16 *) bcfg->radio;
> -	eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
> -
> -	eeprom += off;
> -	if (eeprom > eeprom_end)
> -		return false;
> -
> -	*data = *eeprom;
> -	return true;
> -}
> -
> -int ath5k_hw_read_srev(struct ath5k_hw *ah)
> -{
> -	struct platform_device *pdev = to_platform_device(ah->dev);
> -	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
> -	ah->ah_mac_srev = bcfg->devid;
> -	return 0;
> -}
> -
> -static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
> -{
> -	struct platform_device *pdev = to_platform_device(ah->dev);
> -	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
> -	u8 *cfg_mac;
> -
> -	if (to_platform_device(ah->dev)->id == 0)
> -		cfg_mac = bcfg->config->wlan0_mac;
> -	else
> -		cfg_mac = bcfg->config->wlan1_mac;
> -
> -	memcpy(mac, cfg_mac, ETH_ALEN);
> -	return 0;
> -}
> -
> -static const struct ath_bus_ops ath_ahb_bus_ops = {
> -	.ath_bus_type = ATH_AHB,
> -	.read_cachesize = ath5k_ahb_read_cachesize,
> -	.eeprom_read = ath5k_ahb_eeprom_read,
> -	.eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
> -};
> -
> -/*Initialization*/
> -static int ath_ahb_probe(struct platform_device *pdev)
> -{
> -	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
> -	struct ath5k_hw *ah;
> -	struct ieee80211_hw *hw;
> -	struct resource *res;
> -	void __iomem *mem;
> -	int irq;
> -	int ret = 0;
> -	u32 reg;
> -
> -	if (!pdev->dev.platform_data) {
> -		dev_err(&pdev->dev, "no platform data specified\n");
> -		ret = -EINVAL;
> -		goto err_out;
> -	}
> -
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "no memory resource found\n");
> -		ret = -ENXIO;
> -		goto err_out;
> -	}
> -
> -	mem = ioremap_nocache(res->start, resource_size(res));
> -	if (mem == NULL) {
> -		dev_err(&pdev->dev, "ioremap failed\n");
> -		ret = -ENOMEM;
> -		goto err_out;
> -	}
> -
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "no IRQ resource found\n");
> -		ret = -ENXIO;
> -		goto err_iounmap;
> -	}
> -
> -	irq = res->start;
> -
> -	hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
> -	if (hw == NULL) {
> -		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
> -		ret = -ENOMEM;
> -		goto err_iounmap;
> -	}
> -
> -	ah = hw->priv;
> -	ah->hw = hw;
> -	ah->dev = &pdev->dev;
> -	ah->iobase = mem;
> -	ah->irq = irq;
> -	ah->devid = bcfg->devid;
> -
> -	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
> -		/* Enable WMAC AHB arbitration */
> -		reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
> -		reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
> -		iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
> -
> -		/* Enable global WMAC swapping */
> -		reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
> -		reg |= AR5K_AR2315_BYTESWAP_WMAC;
> -		iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
> -	} else {
> -		/* Enable WMAC DMA access (assuming 5312 or 231x*/
> -		/* TODO: check other platforms */
> -		reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
> -		if (to_platform_device(ah->dev)->id == 0)
> -			reg |= AR5K_AR5312_ENABLE_WLAN0;
> -		else
> -			reg |= AR5K_AR5312_ENABLE_WLAN1;
> -		iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
> -
> -		/*
> -		 * On a dual-band AR5312, the multiband radio is only
> -		 * used as pass-through. Disable 2 GHz support in the
> -		 * driver for it
> -		 */
> -		if (to_platform_device(ah->dev)->id == 0 &&
> -		    (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
> -		     (BD_WLAN1 | BD_WLAN0))
> -			ah->ah_capabilities.cap_needs_2GHz_ovr = true;
> -		else
> -			ah->ah_capabilities.cap_needs_2GHz_ovr = false;
> -	}
> -
> -	ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
> -	if (ret != 0) {
> -		dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
> -		ret = -ENODEV;
> -		goto err_free_hw;
> -	}
> -
> -	platform_set_drvdata(pdev, hw);
> -
> -	return 0;
> -
> - err_free_hw:
> -	ieee80211_free_hw(hw);
> -	platform_set_drvdata(pdev, NULL);
> - err_iounmap:
> -        iounmap(mem);
> - err_out:
> -	return ret;
> -}
> -
> -static int ath_ahb_remove(struct platform_device *pdev)
> -{
> -	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
> -	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
> -	struct ath5k_hw *ah;
> -	u32 reg;
> -
> -	if (!hw)
> -		return 0;
> -
> -	ah = hw->priv;
> -
> -	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
> -		/* Disable WMAC AHB arbitration */
> -		reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
> -		reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
> -		iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
> -	} else {
> -		/*Stop DMA access */
> -		reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
> -		if (to_platform_device(ah->dev)->id == 0)
> -			reg &= ~AR5K_AR5312_ENABLE_WLAN0;
> -		else
> -			reg &= ~AR5K_AR5312_ENABLE_WLAN1;
> -		iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
> -	}
> -
> -	ath5k_deinit_ah(ah);
> -	iounmap(ah->iobase);
> -	platform_set_drvdata(pdev, NULL);
> -	ieee80211_free_hw(hw);
> -
> -	return 0;
> -}
> -
> -static struct platform_driver ath_ahb_driver = {
> -	.probe      = ath_ahb_probe,
> -	.remove     = ath_ahb_remove,
> -	.driver		= {
> -		.name	= "ar231x-wmac",
> -		.owner	= THIS_MODULE,
> -	},
> -};
> -
> -module_platform_driver(ath_ahb_driver);
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index 2d691b8..deaedb8 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -1645,32 +1645,6 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
>   	return &(ath5k_hw_common(ah)->regulatory);
>   }
>
> -#ifdef CONFIG_ATHEROS_AR231X
> -#define AR5K_AR2315_PCI_BASE	((void __iomem *)0xb0100000)
> -
> -static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
> -{
> -	/* On AR2315 and AR2317 the PCI clock domain registers
> -	 * are outside of the WMAC register space */
> -	if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
> -	    (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
> -		return AR5K_AR2315_PCI_BASE + reg;
> -
> -	return ah->iobase + reg;
> -}
> -
> -static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
> -{
> -	return ioread32(ath5k_ahb_reg(ah, reg));
> -}
> -
> -static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
> -{
> -	iowrite32(val, ath5k_ahb_reg(ah, reg));
> -}
> -
> -#else
> -
>   static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
>   {
>   	return ioread32(ah->iobase + reg);
> @@ -1681,8 +1655,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
>   	iowrite32(val, ah->iobase + reg);
>   }
>
> -#endif
> -
>   static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
>   {
>   	return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
> index 9b20d9e..654cc3d 100644
> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
> @@ -97,15 +97,6 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
>
>   /* Known SREVs */
>   static const struct ath5k_srev_name srev_names[] = {
> -#ifdef CONFIG_ATHEROS_AR231X
> -	{ "5312",	AR5K_VERSION_MAC,	AR5K_SREV_AR5312_R2 },
> -	{ "5312",	AR5K_VERSION_MAC,	AR5K_SREV_AR5312_R7 },
> -	{ "2313",	AR5K_VERSION_MAC,	AR5K_SREV_AR2313_R8 },
> -	{ "2315",	AR5K_VERSION_MAC,	AR5K_SREV_AR2315_R6 },
> -	{ "2315",	AR5K_VERSION_MAC,	AR5K_SREV_AR2315_R7 },
> -	{ "2317",	AR5K_VERSION_MAC,	AR5K_SREV_AR2317_R1 },
> -	{ "2317",	AR5K_VERSION_MAC,	AR5K_SREV_AR2317_R2 },
> -#else
>   	{ "5210",	AR5K_VERSION_MAC,	AR5K_SREV_AR5210 },
>   	{ "5311",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311 },
>   	{ "5311A",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311A },
> @@ -124,7 +115,6 @@ static const struct ath5k_srev_name srev_names[] = {
>   	{ "5418",	AR5K_VERSION_MAC,	AR5K_SREV_AR5418 },
>   	{ "2425",	AR5K_VERSION_MAC,	AR5K_SREV_AR2425 },
>   	{ "2417",	AR5K_VERSION_MAC,	AR5K_SREV_AR2417 },
> -#endif
>   	{ "xxxxx",	AR5K_VERSION_MAC,	AR5K_SREV_UNKNOWN },
>   	{ "5110",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5110 },
>   	{ "5111",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5111 },
> @@ -140,10 +130,6 @@ static const struct ath5k_srev_name srev_names[] = {
>   	{ "5413",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5413 },
>   	{ "5424",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5424 },
>   	{ "5133",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5133 },
> -#ifdef CONFIG_ATHEROS_AR231X
> -	{ "2316",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2316 },
> -	{ "2317",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2317 },
> -#endif
>   	{ "xxxxx",	AR5K_VERSION_RAD,	AR5K_SREV_UNKNOWN },
>   };
>
> diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
> index f77ef36..dbf2483 100644
> --- a/drivers/net/wireless/ath/ath5k/led.c
> +++ b/drivers/net/wireless/ath/ath5k/led.c
> @@ -162,20 +162,14 @@ int ath5k_init_leds(struct ath5k_hw *ah)
>   {
>   	int ret = 0;
>   	struct ieee80211_hw *hw = ah->hw;
> -#ifndef CONFIG_ATHEROS_AR231X
>   	struct pci_dev *pdev = ah->pdev;
> -#endif
>   	char name[ATH5K_LED_MAX_NAME_LEN + 1];
>   	const struct pci_device_id *match;
>
>   	if (!ah->pdev)
>   		return 0;
>
> -#ifdef CONFIG_ATHEROS_AR231X
> -	match = NULL;
> -#else
>   	match = pci_match_id(&ath5k_led_devices[0], pdev);
> -#endif
>   	if (match) {
>   		__set_bit(ATH_STAT_LEDSOFT, ah->status);
>   		ah->led_pin = ATH_PIN(match->driver_data);
>


-- 
Regards,
Oleksij

^ permalink raw reply


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