aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYin, Fengwei <fengwei.yin@linaro.org>2015-10-23 20:57:04 +0800
committerYin, Fengwei <fengwei.yin@linaro.org>2015-10-23 20:57:04 +0800
commit385568061f26e2c1f925b2d1fd067cc45a2b50de (patch)
treef0e553e469d168ff609c2d7a8ba76af346a39a16
parent5a6018da3c4915cda70e1ccebedf28d7042a2194 (diff)
wcn36xx: enable arp offload.arp_offload
Signed-off-by: Yin, Fengwei <fengwei.yin@linaro.org>
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c14
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c84
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.h4
3 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index bbd4eca5e9f1..3caa75109710 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -587,6 +587,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{
+ int i;
struct wcn36xx *wcn = hw->priv;
struct sk_buff *skb = NULL;
u16 tim_off, tim_len;
@@ -596,6 +597,14 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n",
vif, changed);
+ pr_info("%s: mac bss info changed vif %p changed 0x%08x\n", __func__,
+ vif, changed);
+
+ pr_info("%s: arp_addr_cnt: %d\n", __func__, bss_conf->arp_addr_cnt);
+ for (i = 0; i < bss_conf->arp_addr_cnt; i++)
+ pr_info("%s: ip[%d]: 0x%x\n", __func__, i, bss_conf->arp_addr_list[i]);
+
+
if (changed & BSS_CHANGED_BEACON_INFO) {
wcn36xx_dbg(WCN36XX_DBG_MAC,
"mac bss changed dtim period %d\n",
@@ -604,6 +613,11 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
vif_priv->dtim_period = bss_conf->dtim_period;
}
+ if (changed & BSS_CHANGED_ARP_FILTER) {
+ pr_info("enable arp offload\n");
+ wcn36xx_smd_arp_offload_enable(wcn, vif, bss_conf);
+ }
+
if (changed & BSS_CHANGED_PS) {
wcn36xx_dbg(WCN36XX_DBG_MAC,
"mac bss PS set %d\n",
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index d950f286a9d5..26ecd1b18608 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -1696,6 +1696,89 @@ out:
mutex_unlock(&wcn->hal_mutex);
return ret;
}
+
+/* Notice: This function should be called after associated, or else it
+ * will be invalid
+ */
+int wcn36xx_smd_arp_offload_enable(struct wcn36xx *wcn,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct wcn36xx_hal_host_offload_req_msg msg_body;
+ struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
+ int ret = 0;
+
+ if (bss_conf->arp_addr_cnt == 0) {
+ pr_err("%s called before IP address is allocated\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&wcn->hal_mutex);
+ INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_OFFLOAD_REQ);
+
+ msg_body.host_offload_params.offload_Type =
+ WCN36XX_HAL_IPV4_ARP_REPLY_OFFLOAD;
+ msg_body.host_offload_params.enable =
+ WCN36XX_HAL_OFFLOAD_ENABLE;
+#define IPV4 msg_body.host_offload_params.u.host_ipv4_addr
+ IPV4[0] = bss_conf->arp_addr_list[0] & 0xff;
+ IPV4[1] = (bss_conf->arp_addr_list[0] >> 8) & 0xff;
+ IPV4[2] = (bss_conf->arp_addr_list[0] >> 16) & 0xff;
+ IPV4[3] = (bss_conf->arp_addr_list[0] >> 24) & 0xff;
+ pr_info("ip: %d.%d.%d.%d\n", IPV4[0], IPV4[1], IPV4[2], IPV4[3]);
+ msg_body.ns_offload_params.bss_index = vif_priv->bss_index;
+
+ PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+ ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+ if (ret) {
+ wcn36xx_err("Sending host offload req failed\n");
+ }
+
+ mutex_unlock(&wcn->hal_mutex);
+ return ret;
+}
+
+int wcn36xx_smd_arp_offload_disable(struct wcn36xx *wcn,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct wcn36xx_hal_host_offload_req_msg msg_body;
+ struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
+ int ret = 0;
+
+ if (bss_conf->arp_addr_cnt == 0) {
+ pr_err("%s called before IP address is allocated\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&wcn->hal_mutex);
+ INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_OFFLOAD_REQ);
+
+ msg_body.host_offload_params.offload_Type =
+ WCN36XX_HAL_IPV4_ARP_REPLY_OFFLOAD;
+ msg_body.host_offload_params.enable =
+ WCN36XX_HAL_OFFLOAD_DISABLE;
+#define IP msg_body.host_offload_params.u.host_ipv4_addr
+ IP[0] = bss_conf->arp_addr_list[0] & 0xff;
+ IP[1] = (bss_conf->arp_addr_list[0] >> 8) & 0xff;
+ IP[2] = (bss_conf->arp_addr_list[0] >> 16) & 0xff;
+ IP[3] = (bss_conf->arp_addr_list[0] >> 24) & 0xff;
+ msg_body.ns_offload_params.bss_index = vif_priv->bss_index;
+
+ PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+ ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+ if (ret) {
+ wcn36xx_err("Sending host offload req failed\n");
+ }
+
+ mutex_unlock(&wcn->hal_mutex);
+ return ret;
+}
+
/* Notice: This function should be called after associated, or else it
* will be invalid
*/
@@ -2143,6 +2226,7 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP:
case WCN36XX_HAL_CH_SWITCH_RSP:
case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP:
+ case WCN36XX_HAL_HOST_OFFLOAD_RSP:
memcpy(wcn->hal_buf, buf, len);
wcn->hal_rsp_len = len;
complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 8361f9e3995b..90eb9ec39927 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -136,4 +136,8 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index);
int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index);
int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value);
+
+int wcn36xx_smd_arp_offload_enable(struct wcn36xx *wcn,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf);
#endif /* _SMD_H_ */