1414
1515#define VERSION "0.1"
1616
17- int qca_read_soc_version (struct hci_dev * hdev , u32 * soc_version )
17+ int qca_read_soc_version (struct hci_dev * hdev , u32 * soc_version ,
18+ enum qca_btsoc_type soc_type )
1819{
1920 struct sk_buff * skb ;
2021 struct edl_event_hdr * edl ;
21- struct rome_version * ver ;
22+ struct qca_btsoc_version * ver ;
2223 char cmd ;
2324 int err = 0 ;
25+ u8 event_type = HCI_EV_VENDOR ;
26+ u8 rlen = sizeof (* edl ) + sizeof (* ver );
27+ u8 rtype = EDL_APP_VER_RES_EVT ;
2428
2529 bt_dev_dbg (hdev , "QCA Version Request" );
2630
31+ /* Unlike other SoC's sending version command response as payload to
32+ * VSE event. WCN3991 sends version command response as a payload to
33+ * command complete event.
34+ */
35+ if (soc_type == QCA_WCN3991 ) {
36+ event_type = 0 ;
37+ rlen += 1 ;
38+ rtype = EDL_PATCH_VER_REQ_CMD ;
39+ }
40+
2741 cmd = EDL_PATCH_VER_REQ_CMD ;
2842 skb = __hci_cmd_sync_ev (hdev , EDL_PATCH_CMD_OPCODE , EDL_PATCH_CMD_LEN ,
29- & cmd , HCI_EV_VENDOR , HCI_INIT_TIMEOUT );
43+ & cmd , event_type , HCI_INIT_TIMEOUT );
3044 if (IS_ERR (skb )) {
3145 err = PTR_ERR (skb );
3246 bt_dev_err (hdev , "Reading QCA version information failed (%d)" ,
3347 err );
3448 return err ;
3549 }
3650
37- if (skb -> len != sizeof ( * edl ) + sizeof ( * ver ) ) {
51+ if (skb -> len != rlen ) {
3852 bt_dev_err (hdev , "QCA Version size mismatch len %d" , skb -> len );
3953 err = - EILSEQ ;
4054 goto out ;
@@ -48,26 +62,29 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version)
4862 }
4963
5064 if (edl -> cresp != EDL_CMD_REQ_RES_EVT ||
51- edl -> rtype != EDL_APP_VER_RES_EVT ) {
65+ edl -> rtype != rtype ) {
5266 bt_dev_err (hdev , "QCA Wrong packet received %d %d" , edl -> cresp ,
5367 edl -> rtype );
5468 err = - EIO ;
5569 goto out ;
5670 }
5771
58- ver = (struct rome_version * )(edl -> data );
72+ if (soc_type == QCA_WCN3991 )
73+ memmove (& edl -> data , & edl -> data [1 ], sizeof (* ver ));
74+
75+ ver = (struct qca_btsoc_version * )(edl -> data );
5976
6077 BT_DBG ("%s: Product:0x%08x" , hdev -> name , le32_to_cpu (ver -> product_id ));
6178 BT_DBG ("%s: Patch :0x%08x" , hdev -> name , le16_to_cpu (ver -> patch_ver ));
62- BT_DBG ("%s: ROM :0x%08x" , hdev -> name , le16_to_cpu (ver -> rome_ver ));
79+ BT_DBG ("%s: ROM :0x%08x" , hdev -> name , le16_to_cpu (ver -> rom_ver ));
6380 BT_DBG ("%s: SOC :0x%08x" , hdev -> name , le32_to_cpu (ver -> soc_id ));
6481
6582 /* QCA chipset version can be decided by patch and SoC
6683 * version, combination with upper 2 bytes from SoC
6784 * and lower 2 bytes from patch will be used.
6885 */
6986 * soc_version = (le32_to_cpu (ver -> soc_id ) << 16 ) |
70- (le16_to_cpu (ver -> rome_ver ) & 0x0000ffff );
87+ (le16_to_cpu (ver -> rom_ver ) & 0x0000ffff );
7188 if (* soc_version == 0 )
7289 err = - EILSEQ ;
7390
@@ -121,7 +138,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
121138}
122139EXPORT_SYMBOL_GPL (qca_send_pre_shutdown_cmd );
123140
124- static void qca_tlv_check_data (struct rome_config * config ,
141+ static void qca_tlv_check_data (struct qca_fw_config * config ,
125142 const struct firmware * fw )
126143{
127144 const u8 * data ;
@@ -140,8 +157,8 @@ static void qca_tlv_check_data(struct rome_config *config,
140157 BT_DBG ("TLV Type\t\t : 0x%x" , type_len & 0x000000ff );
141158 BT_DBG ("Length\t\t : %d bytes" , length );
142159
143- config -> dnld_mode = ROME_SKIP_EVT_NONE ;
144- config -> dnld_type = ROME_SKIP_EVT_NONE ;
160+ config -> dnld_mode = QCA_SKIP_EVT_NONE ;
161+ config -> dnld_type = QCA_SKIP_EVT_NONE ;
145162
146163 switch (config -> type ) {
147164 case TLV_TYPE_PATCH :
@@ -223,31 +240,45 @@ static void qca_tlv_check_data(struct rome_config *config,
223240}
224241
225242static int qca_tlv_send_segment (struct hci_dev * hdev , int seg_size ,
226- const u8 * data , enum rome_tlv_dnld_mode mode )
243+ const u8 * data , enum qca_tlv_dnld_mode mode ,
244+ enum qca_btsoc_type soc_type )
227245{
228246 struct sk_buff * skb ;
229247 struct edl_event_hdr * edl ;
230248 struct tlv_seg_resp * tlv_resp ;
231249 u8 cmd [MAX_SIZE_PER_TLV_SEGMENT + 2 ];
232250 int err = 0 ;
251+ u8 event_type = HCI_EV_VENDOR ;
252+ u8 rlen = (sizeof (* edl ) + sizeof (* tlv_resp ));
253+ u8 rtype = EDL_TVL_DNLD_RES_EVT ;
233254
234255 cmd [0 ] = EDL_PATCH_TLV_REQ_CMD ;
235256 cmd [1 ] = seg_size ;
236257 memcpy (cmd + 2 , data , seg_size );
237258
238- if (mode == ROME_SKIP_EVT_VSE_CC || mode == ROME_SKIP_EVT_VSE )
259+ if (mode == QCA_SKIP_EVT_VSE_CC || mode == QCA_SKIP_EVT_VSE )
239260 return __hci_cmd_send (hdev , EDL_PATCH_CMD_OPCODE , seg_size + 2 ,
240261 cmd );
241262
263+ /* Unlike other SoC's sending version command response as payload to
264+ * VSE event. WCN3991 sends version command response as a payload to
265+ * command complete event.
266+ */
267+ if (soc_type == QCA_WCN3991 ) {
268+ event_type = 0 ;
269+ rlen = sizeof (* edl );
270+ rtype = EDL_PATCH_TLV_REQ_CMD ;
271+ }
272+
242273 skb = __hci_cmd_sync_ev (hdev , EDL_PATCH_CMD_OPCODE , seg_size + 2 , cmd ,
243- HCI_EV_VENDOR , HCI_INIT_TIMEOUT );
274+ event_type , HCI_INIT_TIMEOUT );
244275 if (IS_ERR (skb )) {
245276 err = PTR_ERR (skb );
246277 bt_dev_err (hdev , "QCA Failed to send TLV segment (%d)" , err );
247278 return err ;
248279 }
249280
250- if (skb -> len != sizeof ( * edl ) + sizeof ( * tlv_resp ) ) {
281+ if (skb -> len != rlen ) {
251282 bt_dev_err (hdev , "QCA TLV response size mismatch" );
252283 err = - EILSEQ ;
253284 goto out ;
@@ -260,13 +291,19 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
260291 goto out ;
261292 }
262293
263- tlv_resp = (struct tlv_seg_resp * )(edl -> data );
294+ if (edl -> cresp != EDL_CMD_REQ_RES_EVT || edl -> rtype != rtype ) {
295+ bt_dev_err (hdev , "QCA TLV with error stat 0x%x rtype 0x%x" ,
296+ edl -> cresp , edl -> rtype );
297+ err = - EIO ;
298+ }
264299
265- if (edl -> cresp != EDL_CMD_REQ_RES_EVT ||
266- edl -> rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp -> result != 0x00 ) {
300+ if (soc_type == QCA_WCN3991 )
301+ goto out ;
302+
303+ tlv_resp = (struct tlv_seg_resp * )(edl -> data );
304+ if (tlv_resp -> result ) {
267305 bt_dev_err (hdev , "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)" ,
268306 edl -> cresp , edl -> rtype , tlv_resp -> result );
269- err = - EIO ;
270307 }
271308
272309out :
@@ -301,7 +338,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
301338}
302339
303340static int qca_download_firmware (struct hci_dev * hdev ,
304- struct rome_config * config )
341+ struct qca_fw_config * config ,
342+ enum qca_btsoc_type soc_type )
305343{
306344 const struct firmware * fw ;
307345 const u8 * segment ;
@@ -328,10 +366,10 @@ static int qca_download_firmware(struct hci_dev *hdev,
328366 remain -= segsize ;
329367 /* The last segment is always acked regardless download mode */
330368 if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT )
331- config -> dnld_mode = ROME_SKIP_EVT_NONE ;
369+ config -> dnld_mode = QCA_SKIP_EVT_NONE ;
332370
333371 ret = qca_tlv_send_segment (hdev , segsize , segment ,
334- config -> dnld_mode );
372+ config -> dnld_mode , soc_type );
335373 if (ret )
336374 goto out ;
337375
@@ -344,8 +382,8 @@ static int qca_download_firmware(struct hci_dev *hdev,
344382 * decrease the BT in initialization time. Here we will inject a command
345383 * complete event to avoid a command timeout error message.
346384 */
347- if (config -> dnld_type == ROME_SKIP_EVT_VSE_CC ||
348- config -> dnld_type == ROME_SKIP_EVT_VSE )
385+ if (config -> dnld_type == QCA_SKIP_EVT_VSE_CC ||
386+ config -> dnld_type == QCA_SKIP_EVT_VSE )
349387 ret = qca_inject_cmd_complete_event (hdev );
350388
351389out :
@@ -382,7 +420,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
382420 enum qca_btsoc_type soc_type , u32 soc_ver ,
383421 const char * firmware_name )
384422{
385- struct rome_config config ;
423+ struct qca_fw_config config ;
386424 int err ;
387425 u8 rom_ver = 0 ;
388426
@@ -405,7 +443,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
405443 "qca/rampatch_%08x.bin" , soc_ver );
406444 }
407445
408- err = qca_download_firmware (hdev , & config );
446+ err = qca_download_firmware (hdev , & config , soc_type );
409447 if (err < 0 ) {
410448 bt_dev_err (hdev , "QCA Failed to download patch (%d)" , err );
411449 return err ;
@@ -426,7 +464,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
426464 snprintf (config .fwname , sizeof (config .fwname ),
427465 "qca/nvm_%08x.bin" , soc_ver );
428466
429- err = qca_download_firmware (hdev , & config );
467+ err = qca_download_firmware (hdev , & config , soc_type );
430468 if (err < 0 ) {
431469 bt_dev_err (hdev , "QCA Failed to download NVM (%d)" , err );
432470 return err ;
0 commit comments