aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinaro CI <ci_notify@linaro.org>2020-09-19 20:03:33 +0000
committerLinaro CI <ci_notify@linaro.org>2020-09-19 20:03:33 +0000
commit4267ade85ed521498eafb71a116d52308d4dc305 (patch)
treef83f79e8d2738300a2b5bf75b40bb9db19f79bad
parent9b7183128da97f372433b4c44333f51905251639 (diff)
parentcc6248da18ffbd7302dee6b6034912361482d8fc (diff)
Merge remote-tracking branch 'alimon-fixes/tracking-qcomlt-fixes-alimon' into integration-linux-qcomlt
# Conflicts: # drivers/net/wireless/ath/wcn36xx/smd.c # drivers/net/wireless/ath/wcn36xx/txrx.c
-rw-r--r--drivers/firmware/qcom_scm.c24
-rw-r--r--drivers/firmware/qcom_scm.h1
-rw-r--r--drivers/media/platform/qcom/venus/core.c4
-rw-r--r--drivers/media/platform/qcom/venus/core.h4
-rw-r--r--drivers/media/platform/qcom/venus/firmware.c18
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c118
-rw-r--r--drivers/net/wireless/ath/wcn36xx/pmc.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.c11
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h5
-rw-r--r--include/linux/qcom_scm.h8
10 files changed, 118 insertions, 77 deletions
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index e8bbf2d38ae7..5b19f1301c1d 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -863,6 +863,30 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
}
EXPORT_SYMBOL(qcom_scm_assign_mem);
+int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
+ u32 cp_nonpixel_start,
+ u32 cp_nonpixel_size)
+{
+ int ret;
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_MP,
+ .cmd = QCOM_SCM_MP_VIDEO_VAR,
+ .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+ QCOM_SCM_VAL, QCOM_SCM_VAL),
+ .args[0] = cp_start,
+ .args[1] = cp_size,
+ .args[2] = cp_nonpixel_start,
+ .args[3] = cp_nonpixel_size,
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ struct qcom_scm_res res;
+
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+ return ret ? : res.result[0];
+}
+EXPORT_SYMBOL(qcom_scm_mem_protect_video_var);
+
/**
* qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
*/
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 38ea614d29fe..95cd1ac30ab0 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -97,6 +97,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04
+#define QCOM_SCM_MP_VIDEO_VAR 0x08
#define QCOM_SCM_MP_ASSIGN 0x16
#define QCOM_SCM_SVC_OCMEM 0x0f
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 203c6538044f..5f8f7b72731c 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -527,6 +527,10 @@ static const struct venus_resources sdm845_res_v2 = {
.vmem_size = 0,
.vmem_addr = 0,
.dma_mask = 0xe0000000 - 1,
+ .cp_start = 0,
+ .cp_size = 0x70800000,
+ .cp_nonpixel_start = 0x1000000,
+ .cp_nonpixel_size = 0x24800000,
.fwname = "qcom/venus-5.2/venus.mdt",
};
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 7118612673c9..8c88516e4694 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -68,6 +68,10 @@ struct venus_resources {
unsigned int vmem_id;
u32 vmem_size;
u32 vmem_addr;
+ u32 cp_start;
+ u32 cp_size;
+ u32 cp_nonpixel_start;
+ u32 cp_nonpixel_size;
const char *fwname;
};
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 8801a6a7543d..ac906ffc608f 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -181,6 +181,7 @@ static int venus_shutdown_no_tz(struct venus_core *core)
int venus_boot(struct venus_core *core)
{
struct device *dev = core->dev;
+ const struct venus_resources *res = core->res;
phys_addr_t mem_phys;
size_t mem_size;
int ret;
@@ -200,7 +201,22 @@ int venus_boot(struct venus_core *core)
else
ret = venus_boot_no_tz(core, mem_phys, mem_size);
- return ret;
+ if (ret)
+ return ret;
+
+ if (core->use_tz && res->cp_size) {
+ ret = qcom_scm_mem_protect_video_var(res->cp_start,
+ res->cp_size,
+ res->cp_nonpixel_start,
+ res->cp_nonpixel_size);
+ if (ret) {
+ dev_err(dev, "set virtual address ranges fail (%d)\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
}
int venus_shutdown(struct venus_core *core)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 868de9d4a14a..b78919117264 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -354,8 +354,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n");
- cancel_work_sync(&wcn->scan_work);
-
mutex_lock(&wcn->scan_lock);
if (wcn->scan_req) {
struct cfg80211_scan_info scan_info = {
@@ -392,9 +390,24 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
int ch = WCN36XX_HW_CHANNEL(wcn);
wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
ch);
- list_for_each_entry(tmp, &wcn->vif_list, list) {
- vif = wcn36xx_priv_to_vif(tmp);
- wcn36xx_smd_switch_channel(wcn, vif, ch);
+
+ if (wcn->sw_scan_opchannel == ch) {
+ /* If channel is the initial operating channel, we may
+ * want to receive/transmit regular data packets, then
+ * simply stop the scan session.
+ */
+ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+ } else if (wcn->sw_scan) {
+ /* A scan is ongoing, do not change the operating
+ * channel, but start a scan session on the channel.
+ */
+ wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
+ wcn36xx_smd_start_scan(wcn, ch);
+ } else {
+ list_for_each_entry(tmp, &wcn->vif_list, list) {
+ vif = wcn36xx_priv_to_vif(tmp);
+ wcn36xx_smd_switch_channel(wcn, vif, ch);
+ }
}
}
@@ -614,55 +627,26 @@ out:
return ret;
}
-static void wcn36xx_hw_scan_worker(struct work_struct *work)
+static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_scan_request *hw_req)
{
- struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
- struct cfg80211_scan_request *req = wcn->scan_req;
- u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
- struct cfg80211_scan_info scan_info = {};
- bool aborted = false;
+ struct wcn36xx *wcn = hw->priv;
int i;
- wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
-
- for (i = 0; i < req->n_channels; i++)
- channels[i] = req->channels[i]->hw_value;
-
- wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
-
- wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
- for (i = 0; i < req->n_channels; i++) {
- mutex_lock(&wcn->scan_lock);
- aborted = wcn->scan_aborted;
- mutex_unlock(&wcn->scan_lock);
-
- if (aborted)
- break;
-
- wcn->scan_freq = req->channels[i]->center_freq;
- wcn->scan_band = req->channels[i]->band;
-
- wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
- msleep(30);
- wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
-
- wcn->scan_freq = 0;
+ if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
+ /* fallback to mac80211 software scan */
+ return 1;
}
- wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
-
- scan_info.aborted = aborted;
- ieee80211_scan_completed(wcn->hw, &scan_info);
- mutex_lock(&wcn->scan_lock);
- wcn->scan_req = NULL;
- mutex_unlock(&wcn->scan_lock);
-}
+ /* For unknown reason, the hardware offloaded scan only works with
+ * 2.4Ghz channels, fallback to software scan in other cases.
+ */
+ for (i = 0; i < hw_req->req.n_channels; i++) {
+ if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ)
+ return 1;
+ }
-static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_scan_request *hw_req)
-{
- struct wcn36xx *wcn = hw->priv;
mutex_lock(&wcn->scan_lock);
if (wcn->scan_req) {
mutex_unlock(&wcn->scan_lock);
@@ -674,12 +658,6 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
mutex_unlock(&wcn->scan_lock);
- if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
- /* legacy manual/sw scan */
- schedule_work(&wcn->scan_work);
- return 0;
- }
-
return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
}
@@ -696,16 +674,30 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
/* ieee80211_scan_completed will be called on FW scan
* indication */
wcn36xx_smd_stop_hw_scan(wcn);
- } else {
- struct cfg80211_scan_info scan_info = {
- .aborted = true,
- };
-
- cancel_work_sync(&wcn->scan_work);
- ieee80211_scan_completed(wcn->hw, &scan_info);
}
}
+static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const u8 *mac_addr)
+{
+ struct wcn36xx *wcn = hw->priv;
+
+ wcn->sw_scan = true;
+ wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn);
+}
+
+static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct wcn36xx *wcn = hw->priv;
+
+ /* ensure that any scan session is finished */
+ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+ wcn->sw_scan = false;
+ wcn->sw_scan_opchannel = 0;
+}
+
static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
enum nl80211_band band)
{
@@ -1151,6 +1143,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.set_key = wcn36xx_set_key,
.hw_scan = wcn36xx_hw_scan,
.cancel_hw_scan = wcn36xx_cancel_hw_scan,
+ .sw_scan_start = wcn36xx_sw_scan_start,
+ .sw_scan_complete = wcn36xx_sw_scan_complete,
.bss_info_changed = wcn36xx_bss_info_changed,
.set_rts_threshold = wcn36xx_set_rts_threshold,
.sta_add = wcn36xx_sta_add,
@@ -1329,8 +1323,6 @@ static int wcn36xx_probe(struct platform_device *pdev)
goto out_wq;
}
- INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
-
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
if (IS_ERR(wcn->smd_channel)) {
wcn36xx_err("failed to open WLAN_CTRL channel\n");
diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c
index 1976b80c235f..2936aaf53273 100644
--- a/drivers/net/wireless/ath/wcn36xx/pmc.c
+++ b/drivers/net/wireless/ath/wcn36xx/pmc.c
@@ -28,6 +28,7 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
if (!ret) {
wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n");
vif_priv->pw_state = WCN36XX_BMPS;
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
} else {
/*
* One of the reasons why HW will not enter BMPS is because
@@ -52,6 +53,7 @@ int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn,
}
wcn36xx_smd_exit_bmps(wcn, vif);
vif_priv->pw_state = WCN36XX_FULL_POWER;
+ vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
return 0;
}
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
index f5872e7dfb51..820505619f66 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -144,15 +144,8 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
fc = __le16_to_cpu(hdr->frame_control);
sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
- /* When scanning associate beacons to this */
- if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
- status.freq = wcn->scan_freq;
- status.band = wcn->scan_band;
- } else {
- status.freq = WCN36XX_CENTER_FREQ(wcn);
- status.band = WCN36XX_BAND(wcn);
- }
-
+ status.freq = WCN36XX_CENTER_FREQ(wcn);
+ status.band = WCN36XX_BAND(wcn);
status.mactime = 10;
status.signal = -get_rssi0(bd);
status.antenna = 1;
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 2d89849c630b..efc9383b7dc4 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -223,10 +223,9 @@ struct wcn36xx {
spinlock_t hal_ind_lock;
struct list_head hal_ind_queue;
- struct work_struct scan_work;
struct cfg80211_scan_request *scan_req;
- int scan_freq;
- int scan_band;
+ bool sw_scan;
+ u8 sw_scan_opchannel;
struct mutex scan_lock;
bool scan_aborted;
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index 2e1193a3fb5f..f455a66e4f1b 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -88,7 +88,9 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
unsigned int *src,
const struct qcom_scm_vmperm *newvm,
unsigned int dest_cnt);
-
+extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
+ u32 cp_nonpixel_start,
+ u32 cp_nonpixel_size);
extern bool qcom_scm_ocmem_lock_available(void);
extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
u32 size, u32 mode);
@@ -144,6 +146,10 @@ static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
unsigned int *src, const struct qcom_scm_vmperm *newvm,
unsigned int dest_cnt) { return -ENODEV; }
+extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
+ u32 cp_nonpixel_start,
+ u32 cp_nonpixel_size)
+ { return -ENODEV };
static inline bool qcom_scm_ocmem_lock_available(void) { return false; }
static inline int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,