* [PATCH 1/7] net: wireless: wcn36xx: add wcn3620 chip type definition
From: Andy Green @ 2015-01-18 5:10 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov
Cc: wcn36xx-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150118050741.31866.36490.stgit-FDDIDLfWL9/T9rR/E2HzMujRB4CPm7EUkgzjau31qRg@public.gmane.org>
Convert the list of chip types to an enum, add the default
UNKNOWN type and a type for WCN3620 chip
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index f0fb81d..a5366b6 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -93,6 +93,13 @@ struct nv_data {
u8 table;
};
+enum wcn36xx_chip_type {
+ WCN36XX_CHIP_UNKNOWN,
+ WCN36XX_CHIP_3660,
+ WCN36XX_CHIP_3680,
+ WCN36XX_CHIP_3620,
+};
+
/* Interface for platform control path
*
* @open: hook must be called when wcn36xx wants to open control channel.
@@ -179,7 +186,7 @@ struct wcn36xx {
u8 fw_minor;
u8 fw_major;
u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE];
- u32 chip_version;
+ enum wcn36xx_chip_type chip_version;
/* extra byte for the NULL termination */
u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];
@@ -227,9 +234,6 @@ struct wcn36xx {
};
-#define WCN36XX_CHIP_3660 0
-#define WCN36XX_CHIP_3680 1
^ permalink raw reply related
* [PATCH 2/7] net: wireless: wcn36xx: get chip type from platform ops
From: Andy Green @ 2015-01-18 5:10 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
Autodetecting the chip type does not work well.
Stop attempting to do it and require a platform op
that tells us what the chip is.
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/main.c | 18 +++++-------------
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
2 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 7dd8873..c4178c7 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -221,17 +221,6 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
}
}
-static void wcn36xx_detect_chip_version(struct wcn36xx *wcn)
-{
- if (get_feat_caps(wcn->fw_feat_caps, DOT11AC)) {
- wcn36xx_info("Chip is 3680\n");
- wcn->chip_version = WCN36XX_CHIP_3680;
- } else {
- wcn36xx_info("Chip is 3660\n");
- wcn->chip_version = WCN36XX_CHIP_3660;
- }
-}
-
static int wcn36xx_start(struct ieee80211_hw *hw)
{
struct wcn36xx *wcn = hw->priv;
@@ -286,8 +275,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
wcn36xx_feat_caps_info(wcn);
}
- wcn36xx_detect_chip_version(wcn);
-
/* DMA channel initialization */
ret = wcn36xx_dxe_init(wcn);
if (ret) {
@@ -1023,6 +1010,11 @@ static int wcn36xx_probe(struct platform_device *pdev)
wcn->hw = hw;
wcn->dev = &pdev->dev;
wcn->ctrl_ops = pdev->dev.platform_data;
+ if (!wcn->ctrl_ops->get_chip_type) {
+ dev_err(&pdev->dev, "Missing ops->get_chip_type\n");
+ return -EINVAL;
+ }
+ wcn->chip_version = wcn->ctrl_ops->get_chip_type();
mutex_init(&wcn->hal_mutex);
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index a5366b6..04793c6 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -110,6 +110,7 @@ struct wcn36xx_platform_ctrl_ops {
void (*close)(void);
int (*tx)(char *buf, size_t len);
int (*get_hw_mac)(u8 *addr);
+ int (*get_chip_type)(void);
int (*smsm_change_state)(u32 clear_mask, u32 set_mask);
};
^ permalink raw reply related
* [PATCH 3/7] net: wireless: wcn36xx: use 3680 dxe regs for 3620
From: Andy Green @ 2015-01-18 5:10 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
Between 3620, 3660 and 3680, only 3660 has a different dxe register
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/dxe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 73f12f1..334f265 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -46,7 +46,7 @@ static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data)
#define wcn36xx_dxe_write_register_x(wcn, reg, reg_data) \
do { \
- if (wcn->chip_version == WCN36XX_CHIP_3680) \
+ if (wcn->chip_version != WCN36XX_CHIP_3660) \
wcn36xx_dxe_write_register(wcn, reg ## _3680, reg_data); \
else \
wcn36xx_dxe_write_register(wcn, reg ## _3660, reg_data); \
^ permalink raw reply related
* [PATCH 4/7] net: wireless: wcn36xx: introduce WCN36XX_HAL_AVOID_FREQ_RANGE_IND
From: Andy Green @ 2015-01-18 5:11 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
WCN3620 firmware introduces a new async indication, we need to
add it as a known message type so we can accept it
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/hal.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index a1f1127..b947de0 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -345,6 +345,8 @@ enum wcn36xx_hal_host_msg_type {
WCN36XX_HAL_DHCP_START_IND = 189,
WCN36XX_HAL_DHCP_STOP_IND = 190,
+ WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
+
WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE
};
^ permalink raw reply related
* [PATCH 5/7] net: wireless: wcn36xx: swallow two wcn3620 IND messages
From: Andy Green @ 2015-01-18 5:11 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
WCN3620 can asynchronously send two new kinds of indication message,
since we can't handle them just accept them quietly.
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 6398693..819741c 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2061,6 +2061,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
complete(&wcn->hal_rsp_compl);
break;
+ case WCN36XX_HAL_COEX_IND:
+ case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
case WCN36XX_HAL_OTA_TX_COMPL_IND:
case WCN36XX_HAL_MISSED_BEACON_IND:
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
@@ -2107,6 +2109,10 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;
switch (msg_header->msg_type) {
+ case WCN36XX_HAL_COEX_IND:
+ break;
+ case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
+ break;
case WCN36XX_HAL_OTA_TX_COMPL_IND:
wcn36xx_smd_tx_compl_ind(wcn,
hal_ind_msg->msg,
^ permalink raw reply related
* [PATCH 6/7] net: wireless: wcn36xx: remove powersaving for wcn3620
From: Andy Green @ 2015-01-18 5:11 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
WCN3620 powersaving mode is not stable. Disable it if we're
on a wcn3620 chip type.
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index c4178c7..569d45b 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -924,6 +924,10 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_TIMING_BEACON_ONLY;
+ /* 3620 powersaving currently unstable */
+ if (wcn->chip_version == WCN36XX_CHIP_3620)
+ wcn->hw->flags &= ~IEEE80211_HW_SUPPORTS_PS;
+
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_ADHOC) |
^ permalink raw reply related
* [PATCH 7/7] net: wireless: wcn36xx: handle new trigger_ba format
From: Andy Green @ 2015-01-18 5:11 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118050741.31866.36490.stgit@114-36-241-182.dynamic.hinet.net>
wcn3620 has a new message structure for the reply to trigger_ba
We don't know what to do with the candidate list he sends back,
but we can at least accept and ignore it nicely instead of dying.
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 28 ++++++++++++++++++++++++++--
drivers/net/wireless/ath/wcn36xx/smd.h | 9 +++++++++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 819741c..dc24e1b 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -243,8 +243,31 @@ static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
rsp = (struct wcn36xx_fw_msg_status_rsp *)
(buf + sizeof(struct wcn36xx_hal_msg_header));
- if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status)
+ if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) {
+ pr_err("%s: bad status, len = %d\n", __func__, len);
+ return rsp->status;
+ }
+
+ return 0;
+}
+
+static int wcn36xx_smd_rsp_status_check_bav2(struct wcn36xx *wcn, void *buf,
+ size_t len)
+{
+ struct wcn36xx_fw_msg_status_rspv2 *rsp;
+
+ if (wcn->chip_version != WCN36XX_CHIP_3620)
+ return wcn36xx_smd_rsp_status_check(buf, len);
+
+ if (len < sizeof(struct wcn36xx_hal_msg_header) + sizeof(*rsp))
+ return -EIO;
+
+ rsp = buf + sizeof(struct wcn36xx_hal_msg_header);
+
+ if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) {
+ pr_err("%s: bad status, len = %d\n", __func__, len);
return rsp->status;
+ }
return 0;
}
@@ -1884,7 +1907,8 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
wcn36xx_err("Sending hal_trigger_ba failed\n");
goto out;
}
- ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+ ret = wcn36xx_smd_rsp_status_check_bav2(wcn, wcn->hal_buf,
+ wcn->hal_rsp_len);
if (ret) {
wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret);
goto out;
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 008d034..432d3b8 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -44,6 +44,15 @@ struct wcn36xx_fw_msg_status_rsp {
u32 status;
} __packed;
+/* wcn3620 returns this for tigger_ba */
+
+struct wcn36xx_fw_msg_status_rspv2 {
+ u8 bss_id[6];
+ u32 status __packed;
+ u16 count_following_candidates __packed;
+ /* candidate list follows */
+};
+
struct wcn36xx_hal_ind_msg {
struct list_head list;
u8 *msg;
^ permalink raw reply related
* [PATCH 0/2] net: wireless: wcn36xx: OOT platform reference patch for msm8916 / wcn36xx
From: Andy Green @ 2015-01-18 5:16 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
These patches are not intended for upstreaming. They are
included as a reference to show how to hook up wcn36xx to
msm platforms using the OOT PIL support needed.
The following series adds Eugene's OOT msm platform shim to
wcn36xx and modifies it to provide wcn36xx platform data
about chip type from Device Tree.
It's useful as an example for how to implement on msm
platforms that do not have all the necessary support
upstreamed yet.
This was tested on msm8916-QRD "phone" dev platform.
---
Andy Green (1):
net wireless wcn36xx adapt wcnss platform to select module by DT
Eugene Krasnikov (1):
net wireless wcn36xx add wcnss platform code
drivers/net/wireless/ath/wcn36xx/Makefile | 2
drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c | 360 ++++++++++++++++++++++++
2 files changed, 361 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
--
^ permalink raw reply
* [PATCH 1/2] net wireless wcn36xx add wcnss platform code
From: Andy Green @ 2015-01-18 5:16 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118051222.32019.32719.stgit@114-36-241-182.dynamic.hinet.net>
From: Eugene Krasnikov <k.eugene.e@gmail.com>
AG modified to remove regulator handling not needed on msm8916-qrd
Signed-off-by: Eugene Krasnikov <k.eugene.e@gmail.com>
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/Makefile | 2
drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c | 357 ++++++++++++++++++++++++
2 files changed, 358 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile b/drivers/net/wireless/ath/wcn36xx/Makefile
index 50c43b4..e889f2c 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_WCN36XX) := wcn36xx.o
+obj-$(CONFIG_WCN36XX) := wcn36xx.o wcn36xx-msm.o
wcn36xx-y += main.o \
dxe.o \
txrx.o \
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c b/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
new file mode 100644
index 0000000..f6f6c83
--- /dev/null
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
+ *
+ * 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/completion.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <soc/qcom/smd.h>
+#include <soc/qcom/smsm.h>
+#include "wcn36xx.h"
+
+#include <soc/qcom/subsystem_restart.h>
+#include <soc/qcom/subsystem_notif.h>
+
+#define MAC_ADDR_0 "wlan/macaddr0"
+
+static void *pil;
+
+struct wcn36xx_msm {
+ struct wcn36xx_platform_ctrl_ops ctrl_ops;
+ struct platform_device *core;
+ void *drv_priv;
+ void (*rsp_cb)(void *drv_priv, void *buf, size_t len);
+ /* SMD related */
+ struct workqueue_struct *wq;
+ struct work_struct smd_work;
+ struct completion smd_compl;
+ smd_channel_t *smd_ch;
+ struct pinctrl *pinctrl;
+} wmsm;
+
+static int wcn36xx_msm_smsm_change_state(u32 clear_mask, u32 set_mask)
+{
+ return smsm_change_state(SMSM_APPS_STATE, clear_mask, set_mask);
+}
+
+static int wcn36xx_msm_get_hw_mac(u8 *addr)
+{
+ const struct firmware *addr_file = NULL;
+ int status;
+ u8 tmp[18];
+ static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5};
+ static const char *files = {MAC_ADDR_0};
+
+ status = request_firmware(&addr_file, files, &wmsm.core->dev);
+
+ if (status < 0) {
+ /* Assign a random mac with Qualcomm oui */
+ dev_err(&wmsm.core->dev, "Failed (%d) to read macaddress file %s, using a random address instead", status,
+ files);
+ memcpy(addr, qcom_oui, 3);
+ get_random_bytes(addr + 3, 3);
+ } else {
+ memset(tmp, 0, sizeof(tmp));
+ memcpy(tmp, addr_file->data, sizeof(tmp) - 1);
+ sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ &addr[0],
+ &addr[1],
+ &addr[2],
+ &addr[3],
+ &addr[4],
+ &addr[5]);
+
+ release_firmware(addr_file);
+ }
+
+ return 0;
+}
+
+static int wcn36xx_msm_smd_send_and_wait(char *buf, size_t len)
+{
+ int avail;
+ int ret = 0;
+
+ avail = smd_write_avail(wmsm.smd_ch);
+
+ if (avail >= len) {
+ avail = smd_write(wmsm.smd_ch, buf, len);
+ if (avail != len) {
+ dev_err(&wmsm.core->dev,
+ "Cannot write to SMD channel\n");
+ ret = -EAGAIN;
+ goto out;
+ }
+ } else {
+ dev_err(&wmsm.core->dev,
+ "SMD channel can accept only %d bytes\n", avail);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void wcn36xx_msm_smd_notify(void *data, unsigned event)
+{
+ struct wcn36xx_msm *wmsm_priv = (struct wcn36xx_msm *)data;
+
+ switch (event) {
+ case SMD_EVENT_OPEN:
+ complete(&wmsm_priv->smd_compl);
+ break;
+ case SMD_EVENT_DATA:
+ queue_work(wmsm_priv->wq, &wmsm_priv->smd_work);
+ break;
+ case SMD_EVENT_CLOSE:
+ break;
+ case SMD_EVENT_STATUS:
+ break;
+ case SMD_EVENT_REOPEN_READY:
+ break;
+ default:
+ dev_err(&wmsm_priv->core->dev,
+ "%s: SMD_EVENT (%d) not supported\n", __func__, event);
+ break;
+ }
+}
+
+static void wcn36xx_msm_smd_work(struct work_struct *work)
+{
+ int avail;
+ int msg_len;
+ void *msg;
+ int ret;
+ struct wcn36xx_msm *wmsm_priv =
+ container_of(work, struct wcn36xx_msm, smd_work);
+
+ while (1) {
+ msg_len = smd_cur_packet_size(wmsm_priv->smd_ch);
+ if (0 == msg_len) {
+ return;
+ }
+ avail = smd_read_avail(wmsm_priv->smd_ch);
+ if (avail < msg_len) {
+ return;
+ }
+ msg = kmalloc(msg_len, GFP_KERNEL);
+ if (NULL == msg) {
+ return;
+ }
+
+ ret = smd_read(wmsm_priv->smd_ch, msg, msg_len);
+ if (ret != msg_len) {
+ return;
+ }
+ wmsm_priv->rsp_cb(wmsm_priv->drv_priv, msg, msg_len);
+ kfree(msg);
+ }
+}
+
+int wcn36xx_msm_smd_open(void *drv_priv, void *rsp_cb)
+{
+ int ret, left;
+ wmsm.drv_priv = drv_priv;
+ wmsm.rsp_cb = rsp_cb;
+ INIT_WORK(&wmsm.smd_work, wcn36xx_msm_smd_work);
+ init_completion(&wmsm.smd_compl);
+
+ wmsm.wq = create_workqueue("wcn36xx_msm_smd_wq");
+ if (!wmsm.wq) {
+ dev_err(&wmsm.core->dev, "failed to allocate wq");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ ret = smd_named_open_on_edge("WLAN_CTRL", SMD_APPS_WCNSS,
+ &wmsm.smd_ch, &wmsm, wcn36xx_msm_smd_notify);
+ if (ret) {
+ dev_err(&wmsm.core->dev,
+ "smd_named_open_on_edge failed: %d\n", ret);
+ return ret;
+ }
+
+ left = wait_for_completion_interruptible_timeout(&wmsm.smd_compl,
+ msecs_to_jiffies(HAL_MSG_TIMEOUT));
+ if (left <= 0) {
+ dev_err(&wmsm.core->dev,
+ "timeout waiting for smd open: %d\n", ret);
+ return left;
+ }
+
+ /* Not to receive INT until the whole buf from SMD is read */
+ smd_disable_read_intr(wmsm.smd_ch);
+
+ return 0;
+}
+
+void wcn36xx_msm_smd_close(void)
+{
+ smd_close(wmsm.smd_ch);
+ flush_workqueue(wmsm.wq);
+ destroy_workqueue(wmsm.wq);
+}
+
+int wcn36xx_msm_shutdown(const struct subsys_desc *desc, bool force_stop)
+{
+ return 0;
+}
+int wcn36xx_msm_powerup(const struct subsys_desc *desc)
+{
+ return 0;
+}
+
+static int wcn36xx_msm_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *wcnss_memory;
+ struct resource *tx_irq;
+ struct resource *rx_irq;
+ struct resource res[3];
+ struct pinctrl_state *ps;
+
+ wmsm.pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR_OR_NULL(wmsm.pinctrl))
+ return PTR_ERR(wmsm.pinctrl);
+
+ ps = pinctrl_lookup_state(wmsm.pinctrl, "wcnss_default");
+ if (IS_ERR_OR_NULL(ps))
+ return PTR_ERR(ps);
+
+ ret = pinctrl_select_state(wmsm.pinctrl, ps);
+ if (ret)
+ return ret;
+
+ if (IS_ERR_OR_NULL(pil))
+ pil = subsystem_get("wcnss");
+ if (IS_ERR_OR_NULL(pil))
+ return PTR_ERR(pil);
+
+ wmsm.core = platform_device_alloc("wcn36xx", -1);
+
+ //dev_err(&pdev->dev, "%s starting\n", __func__);
+
+ memset(res, 0x00, sizeof(res));
+ wmsm.ctrl_ops.open = wcn36xx_msm_smd_open;
+ wmsm.ctrl_ops.close = wcn36xx_msm_smd_close;
+ wmsm.ctrl_ops.tx = wcn36xx_msm_smd_send_and_wait;
+ wmsm.ctrl_ops.get_hw_mac = wcn36xx_msm_get_hw_mac;
+ wmsm.ctrl_ops.smsm_change_state = wcn36xx_msm_smsm_change_state;
+ wcnss_memory =
+ platform_get_resource_byname(pdev,
+ IORESOURCE_MEM,
+ "wcnss_mmio");
+ if (wcnss_memory == NULL) {
+ dev_err(&wmsm.core->dev,
+ "Failed to get wcnss wlan memory map.\n");
+ ret = -ENOMEM;
+ return ret;
+ }
+ memcpy(&res[0], wcnss_memory, sizeof(*wcnss_memory));
+
+ tx_irq = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ,
+ "wcnss_wlantx_irq");
+ if (tx_irq == NULL) {
+ dev_err(&wmsm.core->dev, "Failed to get wcnss tx_irq");
+ ret = -ENOMEM;
+ return ret;
+ }
+ memcpy(&res[1], tx_irq, sizeof(*tx_irq));
+
+ rx_irq = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ,
+ "wcnss_wlanrx_irq");
+ if (rx_irq == NULL) {
+ dev_err(&wmsm.core->dev, "Failed to get wcnss rx_irq");
+ ret = -ENOMEM;
+ return ret;
+ }
+ memcpy(&res[2], rx_irq, sizeof(*rx_irq));
+
+ platform_device_add_resources(wmsm.core, res, ARRAY_SIZE(res));
+
+ ret = platform_device_add_data(wmsm.core, &wmsm.ctrl_ops,
+ sizeof(wmsm.ctrl_ops));
+ if (ret) {
+ dev_err(&wmsm.core->dev, "Can't add platform data\n");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ platform_device_add(wmsm.core);
+
+ dev_info(&pdev->dev, "%s initialized\n", __func__);
+
+ return 0;
+}
+static int wcn36xx_msm_remove(struct platform_device *pdev)
+{
+ struct pinctrl_state *ps;
+
+ platform_device_del(wmsm.core);
+ platform_device_put(wmsm.core);
+
+ if (wmsm.pinctrl) {
+ ps = pinctrl_lookup_state(wmsm.pinctrl, "wcnss_sleep");
+ if (IS_ERR_OR_NULL(ps))
+ return PTR_ERR(ps);
+
+ pinctrl_select_state(wmsm.pinctrl, ps);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id wcn36xx_msm_match_table[] = {
+ { .compatible = "qcom,wcn36xx" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, wcn36xx_msm_match_table);
+
+static struct platform_driver wcn36xx_msm_driver = {
+ .probe = wcn36xx_msm_probe,
+ .remove = wcn36xx_msm_remove,
+ .driver = {
+ .name = "wcn36xx-msm",
+ .owner = THIS_MODULE,
+ .of_match_table = wcn36xx_msm_match_table,
+ },
+};
+
+static int __init wcn36xx_msm_init(void)
+{
+ return platform_driver_register(&wcn36xx_msm_driver);
+}
+module_init(wcn36xx_msm_init);
+
+static void __exit wcn36xx_msm_exit(void)
+{
+ platform_driver_unregister(&wcn36xx_msm_driver);
+ if (pil)
+ subsystem_put(pil);
+
+
+}
+module_exit(wcn36xx_msm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
+MODULE_FIRMWARE(MAC_ADDR_0);
+
^ permalink raw reply related
* [PATCH 2/2] net wireless wcn36xx adapt wcnss platform to select module by DT
From: Andy Green @ 2015-01-18 5:16 UTC (permalink / raw)
To: Kalle Valo, Eugene Krasnikov; +Cc: wcn36xx, linux-wireless, netdev
In-Reply-To: <20150118051222.32019.32719.stgit@114-36-241-182.dynamic.hinet.net>
Simplify the resource handling and use DT to indicate which chip type
we are dealing with
Signed-off-by: Andy Green <andy.green@linaro.org>
---
drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c | 101 ++++++++++++------------
1 file changed, 52 insertions(+), 49 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c b/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
index f6f6c83..c9250e0 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c
@@ -42,7 +42,10 @@ struct wcn36xx_msm {
struct completion smd_compl;
smd_channel_t *smd_ch;
struct pinctrl *pinctrl;
-} wmsm;
+ enum wcn36xx_chip_type chip_type;
+};
+
+static struct wcn36xx_msm wmsm;
static int wcn36xx_msm_smsm_change_state(u32 clear_mask, u32 set_mask)
{
@@ -217,14 +220,47 @@ int wcn36xx_msm_powerup(const struct subsys_desc *desc)
return 0;
}
+static const struct of_device_id wcn36xx_msm_match_table[] = {
+ { .compatible = "qcom,wcn3660", .data = (void *)WCN36XX_CHIP_3660 },
+ { .compatible = "qcom,wcn3680", .data = (void *)WCN36XX_CHIP_3680 },
+ { .compatible = "qcom,wcn3620", .data = (void *)WCN36XX_CHIP_3620 },
+ { }
+};
+
+static int wcn36xx_msm_get_chip_type(void)
+{
+ return wmsm.chip_type;
+}
+
+static struct wcn36xx_msm wmsm = {
+ .ctrl_ops = {
+ .open = wcn36xx_msm_smd_open,
+ .close = wcn36xx_msm_smd_close,
+ .tx = wcn36xx_msm_smd_send_and_wait,
+ .get_hw_mac = wcn36xx_msm_get_hw_mac,
+ .smsm_change_state = wcn36xx_msm_smsm_change_state,
+ .get_chip_type = wcn36xx_msm_get_chip_type,
+ },
+};
+
static int wcn36xx_msm_probe(struct platform_device *pdev)
{
int ret;
- struct resource *wcnss_memory;
- struct resource *tx_irq;
- struct resource *rx_irq;
+ const struct of_device_id *of_id;
+ struct resource *r;
struct resource res[3];
struct pinctrl_state *ps;
+ static const char const *rnames[] = {
+ "wcnss_mmio", "wcnss_wlantx_irq", "wcnss_wlanrx_irq" };
+ static const int rtype[] = {
+ IORESOURCE_MEM, IORESOURCE_IRQ, IORESOURCE_IRQ };
+ int n;
+
+ of_id = of_match_node(wcn36xx_msm_match_table, pdev->dev.of_node);
+ if (!of_id)
+ return -EINVAL;
+
+ wmsm.chip_type = (enum wcn36xx_chip_type)of_id->data;
wmsm.pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR_OR_NULL(wmsm.pinctrl))
@@ -240,52 +276,23 @@ static int wcn36xx_msm_probe(struct platform_device *pdev)
if (IS_ERR_OR_NULL(pil))
pil = subsystem_get("wcnss");
- if (IS_ERR_OR_NULL(pil))
- return PTR_ERR(pil);
+ if (IS_ERR_OR_NULL(pil))
+ return PTR_ERR(pil);
wmsm.core = platform_device_alloc("wcn36xx", -1);
- //dev_err(&pdev->dev, "%s starting\n", __func__);
-
- memset(res, 0x00, sizeof(res));
- wmsm.ctrl_ops.open = wcn36xx_msm_smd_open;
- wmsm.ctrl_ops.close = wcn36xx_msm_smd_close;
- wmsm.ctrl_ops.tx = wcn36xx_msm_smd_send_and_wait;
- wmsm.ctrl_ops.get_hw_mac = wcn36xx_msm_get_hw_mac;
- wmsm.ctrl_ops.smsm_change_state = wcn36xx_msm_smsm_change_state;
- wcnss_memory =
- platform_get_resource_byname(pdev,
- IORESOURCE_MEM,
- "wcnss_mmio");
- if (wcnss_memory == NULL) {
- dev_err(&wmsm.core->dev,
- "Failed to get wcnss wlan memory map.\n");
- ret = -ENOMEM;
- return ret;
- }
- memcpy(&res[0], wcnss_memory, sizeof(*wcnss_memory));
-
- tx_irq = platform_get_resource_byname(pdev,
- IORESOURCE_IRQ,
- "wcnss_wlantx_irq");
- if (tx_irq == NULL) {
- dev_err(&wmsm.core->dev, "Failed to get wcnss tx_irq");
- ret = -ENOMEM;
- return ret;
- }
- memcpy(&res[1], tx_irq, sizeof(*tx_irq));
-
- rx_irq = platform_get_resource_byname(pdev,
- IORESOURCE_IRQ,
- "wcnss_wlanrx_irq");
- if (rx_irq == NULL) {
- dev_err(&wmsm.core->dev, "Failed to get wcnss rx_irq");
- ret = -ENOMEM;
- return ret;
+ for (n = 0; n < ARRAY_SIZE(rnames); n++) {
+ r = platform_get_resource_byname(pdev, rtype[n], rnames[n]);
+ if (!r) {
+ dev_err(&wmsm.core->dev,
+ "Missing resource %s'\n", rnames[n]);
+ ret = -ENOMEM;
+ return ret;
+ }
+ res[n] = *r;
}
- memcpy(&res[2], rx_irq, sizeof(*rx_irq));
- platform_device_add_resources(wmsm.core, res, ARRAY_SIZE(res));
+ platform_device_add_resources(wmsm.core, res, n);
ret = platform_device_add_data(wmsm.core, &wmsm.ctrl_ops,
sizeof(wmsm.ctrl_ops));
@@ -319,10 +326,6 @@ static int wcn36xx_msm_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id wcn36xx_msm_match_table[] = {
- { .compatible = "qcom,wcn36xx" },
- { }
-};
MODULE_DEVICE_TABLE(of, wcn36xx_msm_match_table);
static struct platform_driver wcn36xx_msm_driver = {
^ permalink raw reply related
* Re: [patch net-next 1/2] switchdev: introduce switchdev notifier
From: David Miller @ 2015-01-18 5:24 UTC (permalink / raw)
To: jiri; +Cc: netdev, jhs, sfeldma, stephen, linus.luessing, tgraf
In-Reply-To: <1421362177-10719-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Thu, 15 Jan 2015 23:49:36 +0100
> This patch introduces new notifier for purposes of exposing events which happen
> on switch driver side. The consumers of the event messages are mainly involved
> masters, namely bridge and ovs.
>
> Suggested-by: Thomas Graf <tgraf@suug.ch>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Applied.
^ permalink raw reply
* Re: [patch net-next 2/2] net: replace br_fdb_external_learn_* calls with switchdev notifier events
From: David Miller @ 2015-01-18 5:24 UTC (permalink / raw)
To: jiri; +Cc: netdev, jhs, sfeldma, stephen, linus.luessing, tgraf
In-Reply-To: <1421362177-10719-2-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Thu, 15 Jan 2015 23:49:37 +0100
> This patch benefits from newly introduced switchdev notifier and uses it
> to propagate fdb learn events from rocker driver to bridge. That avoids
> direct function calls and possible use by other listeners (ovs).
>
> Suggested-by: Thomas Graf <tgraf@suug.ch>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Applied.
^ permalink raw reply
* Re: pull request: bluetooth-next 2015-01-16
From: David Miller @ 2015-01-18 5:25 UTC (permalink / raw)
To: johan.hedberg; +Cc: netdev, linux-bluetooth
In-Reply-To: <20150116113301.GA3818@t440s.lan>
From: Johan Hedberg <johan.hedberg@gmail.com>
Date: Fri, 16 Jan 2015 13:33:01 +0200
> Here are some more bluetooth & ieee802154 patches intended for 3.20:
>
> - Refactoring & cleanups of ieee802154 & 6lowpan code
> - Various fixes to the btmrvl driver
> - Fixes for Bluetooth Low Energy Privacy feature handling
> - Added build-time sanity checks for sockaddr sizes
> - Fixes for Security Manager registration on LE-only controllers
> - Refactoring of broken inquiry mode handling to a generic quirk
>
> Please let me know if there are any issues pulling. Thanks.
Pulled, thanks Johan.
^ permalink raw reply
* Re: [PATCH net-next] tipc: fix socket list regression in new nl api
From: David Miller @ 2015-01-18 5:27 UTC (permalink / raw)
To: richard.alpe; +Cc: netdev, tipc-discussion
In-Reply-To: <1421407840-30726-1-git-send-email-richard.alpe@ericsson.com>
From: <richard.alpe@ericsson.com>
Date: Fri, 16 Jan 2015 12:30:40 +0100
> From: Richard Alpe <richard.alpe@ericsson.com>
>
> Commit 07f6c4bc (tipc: convert tipc reference table to use generic
> rhashtable) introduced a problem with port listing in the new netlink
> API. It broke the resume functionality resulting in a never ending
> loop. This was caused by starting with the first hash table every time
> subsequently never returning an empty skb (terminating).
>
> This patch fixes the resume mechanism by keeping a logical reference
> to the last hash table along with a logical reference to the socket
> (port) that didn't fit in the previous message.
>
> Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
> Reviewed-by: Ying Xue <ying.xue@windriver.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2/2] Drivers: Isdn: sc: Fixed coding style & spelling mistakes.
From: David Miller @ 2015-01-18 5:28 UTC (permalink / raw)
To: akash0x53s; +Cc: isdn, netdev, linux-kernel
In-Reply-To: <1421415762-21596-1-git-send-email-akash0x53s@gmail.com>
From: Akash Shende <akash0x53s@gmail.com>
Date: Fri, 16 Jan 2015 19:12:42 +0530
> Fix some spelling mistakes, coding style and don't assign value to static var.
>
> Signed-off-by: Akash Shende <akash0x53s@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [net-next PATCH v3 1/1] atm: remove deprecated use of pci api
From: David Miller @ 2015-01-18 5:28 UTC (permalink / raw)
To: chas; +Cc: David.Laight, lambert.quentin, linux-atm-general, netdev,
linux-kernel
In-Reply-To: <20150116085721.56aa8075@thirdoffive.cmf.nrl.navy.mil>
From: chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Date: Fri, 16 Jan 2015 08:57:21 -0500
> Signed-off-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Applied, thanks Chas.
^ permalink raw reply
* Re: [PATCH] netlink: make nlmsg_end() and genlmsg_end() void
From: David Miller @ 2015-01-18 6:04 UTC (permalink / raw)
To: johannes; +Cc: netdev, johannes.berg
In-Reply-To: <1421442540-10244-1-git-send-email-johannes@sipsolutions.net>
From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 16 Jan 2015 22:09:00 +0100
...
> Remove this, and make the functions void. This removes a bunch of dead
> code as described above. The patch adds lines because I did
>
> - return nlmsg_end(...);
> + nlmsg_end(...);
> + return 0;
>
> I could have preserved all the function's return values by returning
> skb->len, but instead I've audited all the places calling the affected
> functions and found that none cared. A few places actually compared
> the return value with <= 0 in dump functionality, but that could just
> be changed to < 0 with no change in behaviour, so I opted for the more
> efficient version.
>
> One instance of the error I've made numerous times now is also present
> in net/phonet/pn_netlink.c in the route_dumpit() function - it didn't
> check for <0 or <=0 and thus broke out of the loop every single time.
> I've preserved this since it will (I think) have caused the messages to
> userspace to be formatted differently with just a single message for
> every SKB returned to userspace. It's possible that this isn't needed
> for the tools that actually use this, but I don't even know what they
> are so couldn't test that changing this behaviour would be acceptable.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
I like this, applied, thanks Johannes.
You know, I would even be willing to apply a patch adjusting that phonet
case. So feel free to submit that.
^ permalink raw reply
* Re: [patch-net-next v3 1/2] net: ethernet: cpsw: unroll IRQ request loop
From: David Miller @ 2015-01-18 6:07 UTC (permalink / raw)
To: balbi; +Cc: tony, linux-omap, mugunthanvnm, netdev
In-Reply-To: <1421424672-19323-1-git-send-email-balbi@ti.com>
From: Felipe Balbi <balbi@ti.com>
Date: Fri, 16 Jan 2015 10:11:11 -0600
> This patch is in preparation for a nicer IRQ
> handling scheme where we use different IRQ
> handlers for each IRQ line (as it should be).
>
> Later, we will also drop IRQs offset 0 and 3
> because they are always disabled in this driver.
>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
Applied.
^ permalink raw reply
* Re: [patch-net-next v3 2/2] net: ethernet: cpsw: don't requests IRQs we don't use
From: David Miller @ 2015-01-18 6:07 UTC (permalink / raw)
To: balbi; +Cc: tony, linux-omap, mugunthanvnm, netdev
In-Reply-To: <1421424672-19323-2-git-send-email-balbi@ti.com>
From: Felipe Balbi <balbi@ti.com>
Date: Fri, 16 Jan 2015 10:11:12 -0600
> CPSW never uses RX_THRESHOLD or MISC interrupts. In
> fact, they are always kept masked in their appropriate
> IRQ Enable register.
>
> Instead of allocating an IRQ that never fires, it's best
> to remove that code altogether and let future patches
> implement it if anybody needs those.
>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
Applied.
^ permalink raw reply
* RE: [net-next v2 13/15] i40e: limit WoL and link settings to partition 1
From: Yuval Mintz @ 2015-01-18 6:10 UTC (permalink / raw)
To: Jeff Kirsher, David Miller
Cc: Shannon Nelson, netdev, nhorman@redhat.com, sassmann@redhat.com,
jogreene@redhat.com
In-Reply-To: <1421179093-10932-14-git-send-email-jeffrey.t.kirsher@intel.com>
>From: Shannon Nelson <shannon.nelson@intel.com>
>When in multi-function mode, e.g. Dell's NPAR, only partition 1
>of each MAC is allowed to set WoL, speed, and flow control.
Isn't it problematic? I mean, in bnx2x we address ~same issue -
but due to symmetry we prevent ALL interfaces from changing
the link configuration.
How can user be aware of this 'private' behavior? via system logs?
documentation?
How does it interact with Physical Device Assignment of the first
partition?
Cheers,
Yuval
^ permalink raw reply
* Re: [net-next PATCH v2 04/12] net: flow_table: create a set of common headers and actions
From: Scott Feldman @ 2015-01-18 6:34 UTC (permalink / raw)
To: John Fastabend
Cc: Thomas Graf, simon.horman@netronome.com, Netdev, gerlitz.or,
Jamal Hadi Salim, Andy Gospodarek, David S. Miller
In-Reply-To: <20150113213645.13874.24934.stgit@nitbit.x32>
On Tue, Jan 13, 2015 at 1:36 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> This adds common headers and actions that drivers can use.
>
> I have not yet moved the header graphs into the common header
> because I'm not entirely convinced its re-usable. The devices
> I have been looking at have different enough header graphs that
> they wouldn't be re-usable. However possibly many 40Gbp NICs
> for example could share a common header graph. When we get
> multiple implementations we can move this into the common file
> if it makes sense.
>
> And table structures seem to be unique enough that there is
> little value in putting each devices table layout into the
> common file so its left for device specific implementation.
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> include/linux/if_flow_common.h | 257 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 257 insertions(+)
> create mode 100644 include/linux/if_flow_common.h
>
> diff --git a/include/linux/if_flow_common.h b/include/linux/if_flow_common.h
> new file mode 100644
> index 0000000..d4dd749
> --- /dev/null
> +++ b/include/linux/if_flow_common.h
> @@ -0,0 +1,257 @@
> +#ifndef _IF_FLOW_COMMON_H_
> +#define _IF_FLOW_COMMON_H_
> +
> +#include <linux/if_flow.h>
> +
> +/* Common header definition this section provides a set of common or
> + * standard headers that device driver writers may use to simplify the
> + * driver creation. We do not want vendor or driver specific headers
> + * here though. Driver authors can keep these contained to their driver
> + *
> + * Driver authors may use unique IDs greater than HEADER_MAX_UID it is
> + * guaranteed to be larger than any unique IDs used here.
> + */
> +#define HEADER_MAX_UID 100
> +
> +enum net_flow_headers {
> + HEADER_UNSPEC,
> + HEADER_ETHERNET,
> + HEADER_VLAN,
> + HEADER_IPV4,
> +};
> +
> +enum net_flow_ethernet_fields_ids {
> + HEADER_ETHERNET_UNSPEC,
> + HEADER_ETHERNET_SRC_MAC,
> + HEADER_ETHERNET_DST_MAC,
> + HEADER_ETHERNET_ETHERTYPE,
> +};
> +
> +struct net_flow_field net_flow_ethernet_fields[] = {
> + { .name = "src_mac", .uid = HEADER_ETHERNET_SRC_MAC, .bitwidth = 48},
> + { .name = "dst_mac", .uid = HEADER_ETHERNET_DST_MAC, .bitwidth = 48},
> + { .name = "ethertype",
> + .uid = HEADER_ETHERNET_ETHERTYPE,
> + .bitwidth = 16},
> +};
All of these code chunks get repeated in each module that includes
if_flow_common.h, regardless if the module needs all of them.
Maybe #define would be better?
> +struct net_flow_field net_flow_ipv4_fields[14] = {
net_flow_ipv4_fields[]. more like this...
-scott
^ permalink raw reply
* Re: [net-next PATCH v2 06/12] net: rocker: add pipeline model for rocker switch
From: Scott Feldman @ 2015-01-18 6:39 UTC (permalink / raw)
To: John Fastabend
Cc: Thomas Graf, simon.horman@netronome.com, Netdev, gerlitz.or,
Jamal Hadi Salim, Andy Gospodarek, David S. Miller
In-Reply-To: <20150113213739.13874.37091.stgit@nitbit.x32>
On Tue, Jan 13, 2015 at 1:37 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> This adds rocker support for the net_flow_get_* operations. With this
> we can interrogate rocker.
>
> Here we see that for static configurations enabling the get operations
> is simply a matter of defining a pipeline model and returning the
> structures for the core infrastructure to encapsulate into netlink
> messages.
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> drivers/net/ethernet/rocker/rocker.c | 65 ++++
> drivers/net/ethernet/rocker/rocker_pipeline.h | 451 +++++++++++++++++++++++++
> 2 files changed, 516 insertions(+)
> create mode 100644 drivers/net/ethernet/rocker/rocker_pipeline.h
>
> diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
> index 2f398fa..d2ea451 100644
> --- a/drivers/net/ethernet/rocker/rocker.c
> +++ b/drivers/net/ethernet/rocker/rocker.c
> @@ -36,6 +36,7 @@
> #include <generated/utsrelease.h>
>
> #include "rocker.h"
> +#include "rocker_pipeline.h"
>
> static const char rocker_driver_name[] = "rocker";
>
> @@ -3781,6 +3782,56 @@ static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state)
> return rocker_port_stp_update(rocker_port, state);
> }
>
> +static void rocker_destroy_flow_tables(struct rocker_port *rocker_port)
> +{
> + int i;
> +
> + for (i = 0; rocker_table_list[i]; i++)
> + net_flow_destroy_cache(rocker_table_list[i]);
> +}
> +
> +static int rocker_init_flow_tables(struct rocker_port *rocker_port)
> +{
> + int i, err;
> +
> + for (i = 0; rocker_table_list[i]; i++) {
> + err = net_flow_init_cache(rocker_table_list[i]);
> + if (err) {
> + rocker_destroy_flow_tables(rocker_port);
> + return err;
> + }
> + }
> +
> + return 0;
> +}
Can these be moved up above drivers? They don't seem driver or device
specific. Call .ndo_flow_get_tbls to get table list.
> +
> +#ifdef CONFIG_NET_FLOW_TABLES
> +static struct net_flow_tbl **rocker_get_tables(struct net_device *d)
> +{
> + return rocker_table_list;
> +}
> +
> +static struct net_flow_hdr **rocker_get_headers(struct net_device *d)
> +{
> + return rocker_header_list;
> +}
> +
> +static struct net_flow_action **rocker_get_actions(struct net_device *d)
> +{
> + return rocker_action_list;
> +}
> +
> +static struct net_flow_tbl_node **rocker_get_tgraph(struct net_device *d)
> +{
> + return rocker_table_nodes;
> +}
> +
> +static struct net_flow_hdr_node **rocker_get_hgraph(struct net_device *d)
> +{
> + return rocker_header_nodes;
> +}
> +#endif
Do these need to be functions since they all just return static pointer lists?
> static const struct net_device_ops rocker_port_netdev_ops = {
> .ndo_open = rocker_port_open,
> .ndo_stop = rocker_port_stop,
> @@ -3795,6 +3846,13 @@ static const struct net_device_ops rocker_port_netdev_ops = {
> .ndo_bridge_getlink = rocker_port_bridge_getlink,
> .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get,
> .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update,
> +#ifdef CONFIG_NET_FLOW_TABLES
> + .ndo_flow_get_tbls = rocker_get_tables,
> + .ndo_flow_get_hdrs = rocker_get_headers,
> + .ndo_flow_get_actions = rocker_get_actions,
> + .ndo_flow_get_tbl_graph = rocker_get_tgraph,
> + .ndo_flow_get_hdr_graph = rocker_get_hgraph,
Please keep the rocker_port_xxx for .ndo_xxx naming convention.
> +#endif
> };
>
> /********************
> @@ -3960,6 +4018,7 @@ static void rocker_remove_ports(struct rocker *rocker)
> rocker_port = rocker->ports[i];
> rocker_port_ig_tbl(rocker_port, ROCKER_OP_FLAG_REMOVE);
> unregister_netdev(rocker_port->dev);
> + rocker_destroy_flow_tables(rocker_port);
> }
> kfree(rocker->ports);
> }
> @@ -4023,6 +4082,12 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
> goto err_port_ig_tbl;
> }
>
> + err = rocker_init_flow_tables(rocker_port);
> + if (err) {
> + dev_err(&pdev->dev, "install flow table failed\n");
s/table/tables/
> + goto err_port_ig_tbl;
Need to rocker_port_ig_tbl(rocker_port, ROCKER_OP_FLAG_REMOVE) to clean up.
-scott
^ permalink raw reply
* Re: [PATCH] net: rocker: Add basic netdev counters - v2
From: David Miller @ 2015-01-18 6:56 UTC (permalink / raw)
To: sfeldma; +Cc: dsahern, netdev, jiri
In-Reply-To: <CAE4R7bA3QG4LDvVQywDsRuJzJYv4mBq3=OXi2L=qGDfa4a8ykw@mail.gmail.com>
From: Scott Feldman <sfeldma@gmail.com>
Date: Fri, 16 Jan 2015 15:41:41 -0800
> On Fri, Jan 16, 2015 at 1:22 PM, David Ahern <dsahern@gmail.com> wrote:
>> Add packet and byte counters for RX and TX paths.
>>
>> $ ifconfig eth1
>> eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
>> inet6 fe80::5054:ff:fe12:3501 prefixlen 64 scopeid 0x20<link>
>> ether 52:54:00:12:35:01 txqueuelen 1000 (Ethernet)
>> RX packets 63 bytes 15813 (15.4 KiB)
>> RX errors 1 dropped 0 overruns 0 frame 0
>> TX packets 79 bytes 17991 (17.5 KiB)
>> TX errors 7 dropped 0 overruns 0 carrier 0 collisions 0
>>
>> Rx / Tx errors tested by injecting faults in qemu's hardware model for Rocker.
>>
>> v2:
>> - moved counter locations to avoid potential use after free per Florian's comment
>>
>> Signed-off-by: David Ahern <dsahern@gmail.com>
>> Cc: Scott Feldman <sfeldma@gmail.com>
>> Cc: Jiri Pirko <jiri@resnulli.us>
>
> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>
> Thanks David. I think this is good enough for first pass. Longer
> term, I'd like to see this replaced by stats read from device for each
> port.
Ok, applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH v3 net-next 1/1] ip_tunnel: Create percpu gro_cell
From: David Miller @ 2015-01-18 6:57 UTC (permalink / raw)
To: kafai; +Cc: netdev, eric.dumazet, kernel-team
In-Reply-To: <1421431860-1960597-2-git-send-email-kafai@fb.com>
From: Martin KaFai Lau <kafai@fb.com>
Date: Fri, 16 Jan 2015 10:11:00 -0800
> In the ipip tunnel, the skb->queue_mapping is lost in ipip_rcv().
> All skb will be queued to the same cell->napi_skbs. The
> gro_cell_poll is pinned to one core under load. In production traffic,
> we also see severe rx_dropped in the tunl iface and it is probably due to
> this limit: skb_queue_len(&cell->napi_skbs) > netdev_max_backlog.
>
> This patch is trying to alloc_percpu(struct gro_cell) and schedule
> gro_cell_poll to process the skb in the same core.
>
> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2/7] net: wireless: wcn36xx: get chip type from platform ops
From: Pat Erley @ 2015-01-18 8:36 UTC (permalink / raw)
To: Andy Green, Kalle Valo, Eugene Krasnikov
Cc: wcn36xx-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150118051049.31866.47265.stgit-FDDIDLfWL9/T9rR/E2HzMujRB4CPm7EUkgzjau31qRg@public.gmane.org>
On 01/17/2015 11:10 PM, Andy Green wrote:
> Autodetecting the chip type does not work well.
> Stop attempting to do it and require a platform op
> that tells us what the chip is.
>
> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> drivers/net/wireless/ath/wcn36xx/main.c | 18 +++++-------------
> drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
> 2 files changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
> index 7dd8873..c4178c7 100644
> --- a/drivers/net/wireless/ath/wcn36xx/main.c
> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> @@ -221,17 +221,6 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
> }
> }
>
> -static void wcn36xx_detect_chip_version(struct wcn36xx *wcn)
> -{
> - if (get_feat_caps(wcn->fw_feat_caps, DOT11AC)) {
> - wcn36xx_info("Chip is 3680\n");
> - wcn->chip_version = WCN36XX_CHIP_3680;
> - } else {
> - wcn36xx_info("Chip is 3660\n");
> - wcn->chip_version = WCN36XX_CHIP_3660;
> - }
> -}
> -
> static int wcn36xx_start(struct ieee80211_hw *hw)
> {
> struct wcn36xx *wcn = hw->priv;
> @@ -286,8 +275,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
> wcn36xx_feat_caps_info(wcn);
> }
>
> - wcn36xx_detect_chip_version(wcn);
> -
> /* DMA channel initialization */
> ret = wcn36xx_dxe_init(wcn);
> if (ret) {
> @@ -1023,6 +1010,11 @@ static int wcn36xx_probe(struct platform_device *pdev)
> wcn->hw = hw;
> wcn->dev = &pdev->dev;
> wcn->ctrl_ops = pdev->dev.platform_data;
> + if (!wcn->ctrl_ops->get_chip_type) {
> + dev_err(&pdev->dev, "Missing ops->get_chip_type\n");
> + return -EINVAL;
> + }
> + wcn->chip_version = wcn->ctrl_ops->get_chip_type();
>
> mutex_init(&wcn->hal_mutex);
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> index a5366b6..04793c6 100644
> --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> @@ -110,6 +110,7 @@ struct wcn36xx_platform_ctrl_ops {
> void (*close)(void);
> int (*tx)(char *buf, size_t len);
> int (*get_hw_mac)(u8 *addr);
> + int (*get_chip_type)(void);
> int (*smsm_change_state)(u32 clear_mask, u32 set_mask);
> };
>
(This all assumes this driver is currently actually being used)
Doesn't this change break any current users of wcn36xx? Couldn't you
just take the old wcn36xx_detect_chip_version and either add the check
for get_chip_type to the beginning and make it use it and return, or
fall back to the old 'broken' way?
Another alternative would be to update wcn36xx_detect_chip_version to
behave like you expect get_chip_type to, and make it the default and let
platforms override it.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox