msm8916 + wcn3620 mainline support?
Andy Green
andy.green at linaro.org
Sun Jan 11 05:29:16 PST 2015
On 31 December 2014 at 17:02, Eugene Krasnikov <k.eugene.e at gmail.com> wrote:
> Do you have a prima driver working with wcn3620? If so you can check
> what does prima send through SMD and then do the same in wcn36xx.
(sorry resent for the list... gmail in Android chrome doesn't care
about plain text default setting it seems...)
I managed to find a version of prima that can work with the stock
firmware + wcnss from stock kernel + Eugene's wcn36xx-msm.c dug out
from Google over the New Year holiday. It's not simple as the
firmware has undocumented constants that must match on the exact prima
version, and the base version of prima must also match (although it
means little since there are many hugely deviated trees for prima all
claiming the same base version). It needed trial and error
uplevelling three different trees to mainline before I found out what
was breaking to start predicting to bits needed in the matching prima
(by using strings on the prima binary to identify function names only
present on certain patchlevels of prima and tracing why it crashed
during NV response processing).
The root cause of the firmware errors before was a problem in 8916
pinmux support from the uplevel to mainline, when I fixed that the
"correct enough" prima could work.
Then with that I went back to wcn36xx from mainline, wired him up
similarly to wcnss, and he started to try to do something. After some
relatively simple poking around (relative to the 700KLOC prima
monster) I made a couple of small changed to wcn36xx that let him
"kinda work" on wcn3620.
I mention the diffs here rather than send patches because he's still
not properly working and you may have comments to do it differently,
since some of this is just hacked in.
1) force 3620 detection since I dunno how to autodetect
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
b/drivers/net/wireless/ath/wcn36xx/wcn36
index f0fb81d..4b0bdb5 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -229,6 +229,7 @@ struct wcn36xx {
#define WCN36XX_CHIP_3660 0
#define WCN36XX_CHIP_3680 1
+#define WCN36XX_CHIP_3620 2
static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,
u8 major,
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c
b/drivers/net/wireless/ath/wcn36xx/main.c
index 7dd8873..bba702f 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -223,6 +223,7 @@ 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;
@@ -230,6 +231,8 @@ static void wcn36xx_detect_chip_version(struct wcn36xx *wcn)
wcn36xx_info("Chip is 3660\n");
wcn->chip_version = WCN36XX_CHIP_3660;
}
+*/
+ wcn->chip_version = WCN36XX_CHIP_3620;
}
static int wcn36xx_start(struct ieee80211_hw *hw)
2) wcn3620 follows wcn3680 dxe register map
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); \
3) The wcn3620 firmware sends (async?) response packets of a type not
yet understood by wcn36xx, we need to let it at least ignore them
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
};
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 6398693..468f597 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2107,6 +2112,8 @@ 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_AVOID_FREQ_RANGE_IND:
+ break;
case WCN36XX_HAL_OTA_TX_COMPL_IND:
wcn36xx_smd_tx_compl_ind(wcn,
hal_ind_msg->msg,
With that, he can associate to a 2.4GHz AP and pass bulk data... for a
while... and he has some complaints.
He has been able to show sub 1ms pings to the AP, but usually they are
much slower like 50ms. iwconfig wlan2 power off seemed to help but
doesn't seem to be a reliable cure.
And curiously I have never been able to telnet to his port 22 where he
has an sshd listening, there is no netfilter configured but connection
attempts time out as do pings from the outside to the QRD. Pings from
the QRD to the outside and the responses do work while it stays
associated.
1) One example session in dmesg is like this
[ 3142.021374] wcn36xx: firmware WLAN version 'WCN v2.0 RadioPhy
vUnknown with 19.2MHz XO' and CRM version 'CNSS-PR-1-4-2-c4-00025'
[ 3142.021387] wcn36xx: firmware API 1.5.1.2, 41 stations, 2 bssids
[ 3142.022775] wcn36xx: FW Cap MCC
[ 3142.022783] wcn36xx: FW Cap P2P
[ 3142.022790] wcn36xx: FW Cap SLM_SESSIONIZATION
[ 3142.022796] wcn36xx: FW Cap DOT11AC_OPMODE
[ 3142.022803] wcn36xx: FW Cap SAP32STA
[ 3142.022810] wcn36xx: FW Cap TDLS
[ 3142.022817] wcn36xx: FW Cap P2P_GO_NOA_DECOUPLE_INIT_SCAN
[ 3142.022824] wcn36xx: FW Cap WLANACTIVE_OFFLOAD
[ 3142.022831] wcn36xx: FW Cap BEACON_OFFLOAD
[ 3142.022838] wcn36xx: FW Cap SCAN_OFFLOAD
[ 3142.022844] wcn36xx: FW Cap BCN_MISS_OFFLOAD
[ 3142.022851] wcn36xx: FW Cap STA_POWERSAVE
[ 3142.022858] wcn36xx: FW Cap STA_ADVANCED_PWRSAVE
[ 3142.022865] wcn36xx: FW Cap BCN_FILTER
[ 3142.022872] wcn36xx: FW Cap RTT
[ 3142.022878] wcn36xx: FW Cap RATECTRL
[ 3142.022885] wcn36xx: FW Cap WOW
[ 3142.022892] wcn36xx: FW Cap UNKNOWN
[ 3142.022898] wcn36xx: FW Cap UNKNOWN
[ 3142.022904] wcn36xx: FW Cap UNKNOWN
[ 3142.022911] wcn36xx: FW Cap UNKNOWN
[ 3142.022917] wcn36xx: FW Cap UNKNOWN
[ 3142.022923] wcn36xx: FW Cap UNKNOWN
[ 3142.022930] wcn36xx: FW Cap UNKNOWN
[ 3142.022936] wcn36xx: FW Cap UNKNOWN
[ 3142.022942] wcn36xx: FW Cap UNKNOWN
[ 3142.022949] wcn36xx: FW Cap UNKNOWN
[ 3142.022955] wcn36xx: FW Cap UNKNOWN
[ 3142.022961] wcn36xx: FW Cap UNKNOWN
[ 3142.022968] wcn36xx: FW Cap UNKNOWN
[ 3142.022974] wcn36xx: FW Cap UNKNOWN
[ 3142.035038] IPv6: ADDRCONF(NETDEV_UP): wlan2: link is not ready
[ 3142.238278] wlan2: authenticate with 4c:e6:76:c4:e7:b8
[ 3142.276450] wlan2: send auth to 4c:e6:76:c4:e7:b8 (try 1/3)
[ 3142.279119] wlan2: authenticated
[ 3142.284709] wlan2: associate with 4c:e6:76:c4:e7:b8 (try 1/3)
[ 3142.287785] wlan2: RX AssocResp from 4c:e6:76:c4:e7:b8 (capab=0x411
status=0 aid=5)
[ 3142.319878] wlan2: associated
[ 3142.319954] IPv6: ADDRCONF(NETDEV_CHANGE): wlan2: link becomes ready
[ 3142.320088] cfg80211: Calling CRDA for country: TW
[ 3142.320208] cfg80211: Regulatory domain changed to country: TW
[ 3142.320216] cfg80211: DFS Master region: unset
[ 3142.320224] cfg80211: (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp), (dfs_cac_time)
[ 3142.320235] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz),
(N/A, 300 mBm), (N/A)
[ 3142.320246] cfg80211: (5270000 KHz - 5330000 KHz @ 40000 KHz),
(N/A, 600 mBm), (0 s)
[ 3142.320256] cfg80211: (5490000 KHz - 5730000 KHz @ 80000 KHz),
(N/A, 600 mBm), (0 s)
[ 3142.320267] cfg80211: (5735000 KHz - 5815000 KHz @ 80000 KHz),
(N/A, 600 mBm), (N/A)
[ 3142.371482] wcn36xx: ERROR hal_enter_bmps response failed err=6
[ 3142.371503] wcn36xx: ERROR Can not enter BMPS!
[ 3142.444058] wcn36xx: hal_trigger_ba response failed err=c476e64c
[ 3167.757987] wcn36xx: ERROR Not in BMPS mode, no need to exit from BMPS mode!
[ 3205.080770] wcn36xx: hal_trigger_ba response failed err=c476e64c
[ 3221.663887] wcn36xx: hal_trigger_ba response failed err=c476e64c
[ 3261.469072] wlan2: disassociated from 4c:e6:76:c4:e7:b8 (Reason: 7)
[ 3261.585760] wcn36xx: ERROR hal_remove_bsskey response failed err=16
Any advice about these kinds of error are welcome (powersave mode?) or
about the unknown capabilities might need handling.
2) He never reports a "bit rate" other than 1Mbps
wlan2 IEEE 802.11abgn ESSID:"foamy"
Mode:Managed Frequency:2.462 GHz Access Point: 4C:E6:76:C4:E7:B8
Bit Rate=1 Mb/s Tx-Power=3 dBm
Retry short limit:7 RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Link Quality=51/70 Signal level=-59 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
3) After some time (a minute?) he chokes usually like this
[ 3141.456384] wcn36xx: ERROR hal_remove_bsskey response failed err=16
At any rate he's clearly largely able to function using wcn36xx, it'd
be nice to understand what else needs to be done to support it stably.
Any advice welcome...
-Andy
> 2014-12-31 2:46 GMT+00:00 Andy Green <andy.green at linaro.org>:
>> Hi -
>>
>> I am working on an msm8916-qrd platform
>>
>> http://store.thundersoft.com/index.php?main_page=product_info&cPath=55&products_id=197
>>
>> with the goal of a mainline-tracking kernel with things like WLAN
>> (wcn3620) working. I think the current mainline driver does not
>> support this variant but I'll describe my situation and would welcome
>> any advice or opinions on the chances of adapting wcn36xx to also work
>> on wcn3620.
>>
>> I chopped down the 3.10.28-based kernel that came with the QRD to a
>> rough minimum to make it boot, including the gcc locks and rpm pieces,
>> rebased and got that working on mainline (3.19-rc2) and added eMMC
>> using mainline, serial using mainline and simple-framebuffer
>>
>> https://git.linaro.org/people/andy.green/msm8916-qrd.git/shortlog/refs/heads/mainline-basis
>>
>> (the reset of the partially ported pieces there don't work yet).
>>
>> After getting a rough self-taught education in Qualcomm-specific Three
>> Letter Abbreviations, I ported the PIL and PIL/tz specific pieces to
>> get the necessary smd channels to appear.
>>
>> The stock 3.10.28 kernel shipped with a kind of stub driver called
>> "wcnss", he is mainly there to integrate with the rest of the qualcomm
>> pm + smd stack. I ported that as well.
>>
>> So in this setup there are two distinct kinds of firmware, first what
>> seems to be TZ (?) firmware that we talk to over smd
>>
>> -rwxr-xr-x 1 root root 436 Jan 1 00:07 wcnss.b00
>> -rwxr-xr-x 1 root root 6824 Jan 1 00:07 wcnss.b01
>> -rwxr-xr-x 1 root root 12844 Jan 1 00:07 wcnss.b02
>> -rwxr-xr-x 1 root root 61440 Jan 1 00:07 wcnss.b04
>> -rwxr-xr-x 1 root root 3097028 Jan 1 00:07 wcnss.b06
>> -rwxr-xr-x 1 root root 52 Jan 1 00:07 wcnss.b09
>> -rwxr-xr-x 1 root root 655360 Jan 1 00:07 wcnss.b10
>> -rwxr-xr-x 1 root root 39048 Jan 1 00:07 wcnss.b11
>> -rwxr-xr-x 1 root root 7260 Jan 1 00:07 wcnss.mdt
>>
>> the PIL / PIL/tz stuff successfully loads this firmware
>>
>> [ 1.625972] subsys-pil-tz a21b000.qcom,pronto: wcnss: loading from
>> 0x8b600000 to 0x8bbff000
>> [ 1.629269] pil_mem_setup_trusted: MEM_SETUP_CMD id 6, PA
>> 0x8b600000, len 6287360
>> [ 1.629514] scm returned 0
>> [ 1.650582] pil_load_seg: memcpy to offset 0x0
>> [ 1.657948] pil_load_seg: memcpy to offset 0xc000
>> [ 1.709494] pil_load_seg: memcpy to offset 0x29000
>> [ 1.715522] pil_load_seg: memcpy to offset 0x550000
>> [ 1.724946] pil_load_seg: memcpy to offset 0x551000
>> [ 1.727513] pil_load_seg: memcpy to offset 0x5f1000
>> [ 1.869140] subsys-pil-tz a21b000.qcom,pronto: wcnss: Brought out of reset
>>
>> When that is accepted on the TZ side, the necessary smd channels for WLAN appear
>>
>> [ 2.131770] smd_alloc_channel() 'IPCRTR' cid=1
>> [ 2.176510] smd_alloc_channel() 'sys_mon' cid=2
>> [ 2.188739] smd_alloc_channel() 'APPS_RIVA_CTRL' cid=3
>> [ 2.188932] smd_alloc_channel() 'APPS_RIVA_DATA' cid=4
>> [ 2.267513] subsys-pil-tz a21b000.qcom,pronto: Subsystem error
>> monitoring/handling services are up
>> [ 2.267778] wcn36xx-msm a000000.qcom,wcn36xx: wcn36xx_msm_probe initialized
>> [ 2.273076] wcn36xx: mac address: 00:0a:f5:c4:31:e9
>> [ 2.284519] wcn36xx wcn36xx wlan2: renamed from wlan0
>> [ 2.354807] systemd-udevd[243]: renamed network interface wlan0 to wlan2
>> [ 2.700556] smd_alloc_channel() 'APPS_RIVA_BT_CMD' cid=5
>> [ 2.724639] smd_alloc_channel() 'APPS_RIVA_BT_ACL' cid=6
>> [ 2.724819] smd_alloc_channel() 'APPS_RIVA_ANT_CMD' cid=7
>> [ 2.724975] smd_alloc_channel() 'APPS_RIVA_ANT_DATA' cid=8
>> [ 2.725146] smd_alloc_channel() 'APPS_FM' cid=9
>> [ 2.725919] smd_alloc_channel() 'WCNSS_CTRL' cid=10
>> [ 2.726091] smd_alloc_channel() 'WLAN_CTRL' cid=11
>>
>> Now we start to get nasty, both wcn36xx from mainline and wcnss from
>> qualcomm's 2.10.28 stock kernel know how to load the second kind of
>> firmware, from /lib/firmware/wlan/prima/
>>
>> -rwxr-xr-x 1 root root 29816 Jan 1 00:00 WCNSS_qcom_wlan_nv.bin
>>
>> but they use very different smd commands to load the same firmware.
>>
>> If I let wcn36xx load the firmware, he does load it via WLAN_CTRL smd
>> channel, the blocks are accepted but at the final block the smd reply
>> gives an error 233, which is not defined in what wcn36xx understands
>> about that protocol. After that he blows an smd result 5 and we could
>> not start. So I think that is the point we can say "wcn36xx doesn't
>> support wcn3620 chipset".
>>
>> On the other hand, wcnss can successfully load the same firmware, he
>> does a very similar process using WCNSS_CTRL and different smd command
>> indexes. But then he just sits there (because he expects an OOT wlan
>> driver to deal with it, see later).
>>
>> I attempted to cross-breed the two drivers, allowing wcnss to bring up
>> the chipset and set the firmware and then let wcn36xx start up, that
>> gets me
>>
>> root at linaro-developer:~# wpa_supplicant -B -i wlan2 -c
>> /etc/wpa_supplicant/test.conf
>> Successfully initialized wpa_supplicant
>> [ 156.515916] smd_wcnss_irq_handler: #############
>> [ 156.516219] smd_wcnss_irq_handler: #############
>> [ 156.785180] Fatal error on wcnss!
>> [ 156.785209] wcnss subsystem failure reason:
>> boot_exception_c_handlers.c:108:Data Abort Exception at 0xa2887b4.
>> [ 156.787522] Kernel panic - not syncing: subsys-restart: Resetting
>> the SoC - wcnss crashed.
>>
>> (The assertion is reported from TZ it's not in the kernel).
>>
>>
>> so I think wcn36xx probably needs to be taught more about wcn3620
>> firmware protocol changes before it would do anything.
>>
>>
>> Trying to follow up wcnss in 3.10.28 is a bit ugly, in addition to
>> "wcnss" in-tree I ported, which presents 2 x /dev nodes, there is a
>> whole monster OOT kernel driver
>>
>> https://www.codeaurora.org/cgit/external/hisense/platform/vendor/qcom-opensource/wlan/prima/log/?h=8130_CS
>>
>> the stock 3.10 kernel loads that as a module, which is unfortunate
>> because that repo has not been touched in 18 months and does not
>> support msm8916, so I do not have matching sources for that I think.
>>
>> So I would very much prefer to use wcn36xx mainline driver with this
>> wcn3620 chipset rather than the OOT driver.
>>
>> Does anyone have any advice how to best proceed?
>>
>> -Andy
>
>
>
> --
> Best regards,
> Eugene
More information about the wcn36xx
mailing list