@@ -73,6 +73,48 @@ int btintel_check_bdaddr(struct hci_dev *hdev)
73
73
}
74
74
EXPORT_SYMBOL_GPL (btintel_check_bdaddr );
75
75
76
+ int btintel_enter_mfg (struct hci_dev * hdev )
77
+ {
78
+ const u8 param [] = { 0x01 , 0x00 };
79
+ struct sk_buff * skb ;
80
+
81
+ skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_CMD_TIMEOUT );
82
+ if (IS_ERR (skb )) {
83
+ bt_dev_err (hdev , "Entering manufacturer mode failed (%ld)" ,
84
+ PTR_ERR (skb ));
85
+ return PTR_ERR (skb );
86
+ }
87
+ kfree_skb (skb );
88
+
89
+ return 0 ;
90
+ }
91
+ EXPORT_SYMBOL_GPL (btintel_enter_mfg );
92
+
93
+ int btintel_exit_mfg (struct hci_dev * hdev , bool reset , bool patched )
94
+ {
95
+ u8 param [] = { 0x00 , 0x00 };
96
+ struct sk_buff * skb ;
97
+
98
+ /* The 2nd command parameter specifies the manufacturing exit method:
99
+ * 0x00: Just disable the manufacturing mode (0x00).
100
+ * 0x01: Disable manufacturing mode and reset with patches deactivated.
101
+ * 0x02: Disable manufacturing mode and reset with patches activated.
102
+ */
103
+ if (reset )
104
+ param [1 ] |= patched ? 0x02 : 0x01 ;
105
+
106
+ skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_CMD_TIMEOUT );
107
+ if (IS_ERR (skb )) {
108
+ bt_dev_err (hdev , "Exiting manufacturer mode failed (%ld)" ,
109
+ PTR_ERR (skb ));
110
+ return PTR_ERR (skb );
111
+ }
112
+ kfree_skb (skb );
113
+
114
+ return 0 ;
115
+ }
116
+ EXPORT_SYMBOL_GPL (btintel_exit_mfg );
117
+
76
118
int btintel_set_bdaddr (struct hci_dev * hdev , const bdaddr_t * bdaddr )
77
119
{
78
120
struct sk_buff * skb ;
@@ -126,37 +168,19 @@ EXPORT_SYMBOL_GPL(btintel_set_diag);
126
168
127
169
int btintel_set_diag_mfg (struct hci_dev * hdev , bool enable )
128
170
{
129
- struct sk_buff * skb ;
130
- u8 param [2 ];
131
- int err ;
132
-
133
- param [0 ] = 0x01 ;
134
- param [1 ] = 0x00 ;
135
-
136
- skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_INIT_TIMEOUT );
137
- if (IS_ERR (skb )) {
138
- err = PTR_ERR (skb );
139
- BT_ERR ("%s: Entering Intel manufacturer mode failed (%d)" ,
140
- hdev -> name , err );
141
- return PTR_ERR (skb );
142
- }
143
- kfree_skb (skb );
171
+ int err , ret ;
144
172
145
- err = btintel_set_diag (hdev , enable );
173
+ err = btintel_enter_mfg (hdev );
174
+ if (err )
175
+ return err ;
146
176
147
- param [0 ] = 0x00 ;
148
- param [1 ] = 0x00 ;
177
+ ret = btintel_set_diag (hdev , enable );
149
178
150
- skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_INIT_TIMEOUT );
151
- if (IS_ERR (skb )) {
152
- err = PTR_ERR (skb );
153
- BT_ERR ("%s: Leaving Intel manufacturer mode failed (%d)" ,
154
- hdev -> name , err );
155
- return PTR_ERR (skb );
156
- }
157
- kfree_skb (skb );
179
+ err = btintel_exit_mfg (hdev , false, false);
180
+ if (err )
181
+ return err ;
158
182
159
- return err ;
183
+ return ret ;
160
184
}
161
185
EXPORT_SYMBOL_GPL (btintel_set_diag_mfg );
162
186
@@ -309,39 +333,46 @@ EXPORT_SYMBOL_GPL(btintel_set_event_mask);
309
333
310
334
int btintel_set_event_mask_mfg (struct hci_dev * hdev , bool debug )
311
335
{
312
- struct sk_buff * skb ;
313
- u8 param [2 ];
314
- int err ;
336
+ int err , ret ;
315
337
316
- param [0 ] = 0x01 ;
317
- param [1 ] = 0x00 ;
338
+ err = btintel_enter_mfg (hdev );
339
+ if (err )
340
+ return err ;
318
341
319
- skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_INIT_TIMEOUT );
320
- if (IS_ERR (skb )) {
321
- err = PTR_ERR (skb );
322
- BT_ERR ("%s: Entering Intel manufacturer mode failed (%d)" ,
323
- hdev -> name , err );
324
- return PTR_ERR (skb );
325
- }
326
- kfree_skb (skb );
342
+ ret = btintel_set_event_mask (hdev , debug );
327
343
328
- err = btintel_set_event_mask (hdev , debug );
344
+ err = btintel_exit_mfg (hdev , false, false);
345
+ if (err )
346
+ return err ;
329
347
330
- param [0 ] = 0x00 ;
331
- param [1 ] = 0x00 ;
348
+ return ret ;
349
+ }
350
+ EXPORT_SYMBOL_GPL (btintel_set_event_mask_mfg );
332
351
333
- skb = __hci_cmd_sync (hdev , 0xfc11 , 2 , param , HCI_INIT_TIMEOUT );
352
+ int btintel_read_version (struct hci_dev * hdev , struct intel_version * ver )
353
+ {
354
+ struct sk_buff * skb ;
355
+
356
+ skb = __hci_cmd_sync (hdev , 0xfc05 , 0 , NULL , HCI_CMD_TIMEOUT );
334
357
if (IS_ERR (skb )) {
335
- err = PTR_ERR (skb );
336
- BT_ERR ("%s: Leaving Intel manufacturer mode failed (%d)" ,
337
- hdev -> name , err );
358
+ bt_dev_err (hdev , "Reading Intel version information failed (%ld)" ,
359
+ PTR_ERR (skb ));
338
360
return PTR_ERR (skb );
339
361
}
362
+
363
+ if (skb -> len != sizeof (* ver )) {
364
+ bt_dev_err (hdev , "Intel version event size mismatch" );
365
+ kfree_skb (skb );
366
+ return - EILSEQ ;
367
+ }
368
+
369
+ memcpy (ver , skb -> data , sizeof (* ver ));
370
+
340
371
kfree_skb (skb );
341
372
342
- return err ;
373
+ return 0 ;
343
374
}
344
- EXPORT_SYMBOL_GPL (btintel_set_event_mask_mfg );
375
+ EXPORT_SYMBOL_GPL (btintel_read_version );
345
376
346
377
/* ------- REGMAP IBT SUPPORT ------- */
347
378
0 commit comments