1 /*===========================================================================
2 FILE:
3 Structs.h
4
5 DESCRIPTION:
6 Declaration of structures used by the Qualcomm Linux USB Network driver
7
8 FUNCTIONS:
9 none
10
11 Copyright (c) 2011, Code Aurora Forum. All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20 * Neither the name of Code Aurora Forum nor
21 the names of its contributors may be used to endorse or promote
22 products derived from this software without specific prior written
23 permission.
24
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
37 ===========================================================================*/
38
39 //---------------------------------------------------------------------------
40 // Pragmas
41 //---------------------------------------------------------------------------
42 #pragma once
43
44 //---------------------------------------------------------------------------
45 // Include Files
46 //---------------------------------------------------------------------------
47 #include <linux/etherdevice.h>
48 #include <linux/ethtool.h>
49 #include <linux/mii.h>
50 #include <linux/usb.h>
51 #include <linux/version.h>
52 #include <linux/cdev.h>
53 #include <linux/kthread.h>
54 #include <linux/poll.h>
55 #include <linux/completion.h>
56 #include <linux/hrtimer.h>
57 #include <linux/interrupt.h>
58
59 #define QUECTEL_WWAN_QMAP 4 //MAX is 7
60 #ifdef QUECTEL_WWAN_QMAP
61 #define QUECTEL_QMAP_MUX_ID 0x81
62 #endif
63
64 //#define QUECTEL_QMI_MERGE
65
66 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
67 #define QUECTEL_BRIDGE_MODE
68 #endif
69
70 #if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,21 ))
skb_reset_mac_header(struct sk_buff * skb)71 static inline void skb_reset_mac_header(struct sk_buff *skb)
72 {
73 skb->mac.raw = skb->data;
74 }
75 #endif
76
77 #if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,22 ))
78 #define bool u8
79 #ifndef URB_FREE_BUFFER
80 #define URB_FREE_BUFFER_BY_SELF //usb_free_urb will not free, should free by self
81 #define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
82 #endif
83
84 /**
85 * usb_endpoint_type - get the endpoint's transfer type
86 * @epd: endpoint to be checked
87 *
88 * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
89 * to @epd's transfer type.
90 */
usb_endpoint_type(const struct usb_endpoint_descriptor * epd)91 static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
92 {
93 return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
94 }
95 #endif
96
97 #if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,18 ))
98 /**
99 * usb_endpoint_dir_in - check if the endpoint has IN direction
100 * @epd: endpoint to be checked
101 *
102 * Returns true if the endpoint is of type IN, otherwise it returns false.
103 */
usb_endpoint_dir_in(const struct usb_endpoint_descriptor * epd)104 static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
105 {
106 return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
107 }
108
109 /**
110 * usb_endpoint_dir_out - check if the endpoint has OUT direction
111 * @epd: endpoint to be checked
112 *
113 * Returns true if the endpoint is of type OUT, otherwise it returns false.
114 */
usb_endpoint_dir_out(const struct usb_endpoint_descriptor * epd)115 static inline int usb_endpoint_dir_out(
116 const struct usb_endpoint_descriptor *epd)
117 {
118 return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
119 }
120
121 /**
122 * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
123 * @epd: endpoint to be checked
124 *
125 * Returns true if the endpoint is of type interrupt, otherwise it returns
126 * false.
127 */
usb_endpoint_xfer_int(const struct usb_endpoint_descriptor * epd)128 static inline int usb_endpoint_xfer_int(
129 const struct usb_endpoint_descriptor *epd)
130 {
131 return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
132 USB_ENDPOINT_XFER_INT);
133 }
134
usb_autopm_set_interface(struct usb_interface * intf)135 static inline int usb_autopm_set_interface(struct usb_interface *intf)
136 { return 0; }
137
usb_autopm_get_interface(struct usb_interface * intf)138 static inline int usb_autopm_get_interface(struct usb_interface *intf)
139 { return 0; }
140
usb_autopm_get_interface_async(struct usb_interface * intf)141 static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
142 { return 0; }
143
usb_autopm_put_interface(struct usb_interface * intf)144 static inline void usb_autopm_put_interface(struct usb_interface *intf)
145 { }
usb_autopm_put_interface_async(struct usb_interface * intf)146 static inline void usb_autopm_put_interface_async(struct usb_interface *intf)
147 { }
usb_autopm_enable(struct usb_interface * intf)148 static inline void usb_autopm_enable(struct usb_interface *intf)
149 { }
usb_autopm_disable(struct usb_interface * intf)150 static inline void usb_autopm_disable(struct usb_interface *intf)
151 { }
usb_mark_last_busy(struct usb_device * udev)152 static inline void usb_mark_last_busy(struct usb_device *udev)
153 { }
154 #endif
155
156 #if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,24 ))
157 #include "usbnet.h"
158 #else
159 #include <linux/usb/usbnet.h>
160 #endif
161
162 #if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,25 ))
163 #include <linux/fdtable.h>
164 #else
165 #include <linux/file.h>
166 #endif
167
168 // Used in recursion, defined later below
169 struct sGobiUSBNet;
170
171
172 #if defined(QUECTEL_WWAN_QMAP)
173 #define QUECTEL_UL_DATA_AGG 1
174
175 #if defined(QUECTEL_UL_DATA_AGG)
176 struct ul_agg_ctx {
177 /* QMIWDS_ADMIN_SET_DATA_FORMAT_RESP TLV_0x17 and TLV_0x18 */
178 uint ul_data_aggregation_max_datagrams; //UplinkDataAggregationMaxDatagramsTlv
179 uint ul_data_aggregation_max_size; //UplinkDataAggregationMaxSizeTlv
180 uint dl_minimum_padding;
181 };
182 #endif
183 #endif
184
185 /*=========================================================================*/
186 // Struct sReadMemList
187 //
188 // Structure that defines an entry in a Read Memory linked list
189 /*=========================================================================*/
190 typedef struct sReadMemList
191 {
192 /* Data buffer */
193 void * mpData;
194
195 /* Transaction ID */
196 u16 mTransactionID;
197
198 /* Size of data buffer */
199 u16 mDataSize;
200
201 /* Next entry in linked list */
202 struct sReadMemList * mpNext;
203
204 } sReadMemList;
205
206 /*=========================================================================*/
207 // Struct sNotifyList
208 //
209 // Structure that defines an entry in a Notification linked list
210 /*=========================================================================*/
211 typedef struct sNotifyList
212 {
213 /* Function to be run when data becomes available */
214 void (* mpNotifyFunct)(struct sGobiUSBNet *, u16, void *);
215
216 /* Transaction ID */
217 u16 mTransactionID;
218
219 /* Data to provide as parameter to mpNotifyFunct */
220 void * mpData;
221
222 /* Next entry in linked list */
223 struct sNotifyList * mpNext;
224
225 } sNotifyList;
226
227 /*=========================================================================*/
228 // Struct sURBList
229 //
230 // Structure that defines an entry in a URB linked list
231 /*=========================================================================*/
232 typedef struct sURBList
233 {
234 /* The current URB */
235 struct urb * mpURB;
236
237 /* Next entry in linked list */
238 struct sURBList * mpNext;
239
240 } sURBList;
241
242 /*=========================================================================*/
243 // Struct sClientMemList
244 //
245 // Structure that defines an entry in a Client Memory linked list
246 // Stores data specific to a Service Type and Client ID
247 /*=========================================================================*/
248 typedef struct sClientMemList
249 {
250 /* Client ID for this Client */
251 u16 mClientID;
252
253 /* Linked list of Read entries */
254 /* Stores data read from device before sending to client */
255 sReadMemList * mpList;
256
257 /* Linked list of Notification entries */
258 /* Stores notification functions to be run as data becomes
259 available or the device is removed */
260 sNotifyList * mpReadNotifyList;
261
262 /* Linked list of URB entries */
263 /* Stores pointers to outstanding URBs which need canceled
264 when the client is deregistered or the device is removed */
265 sURBList * mpURBList;
266
267 /* Next entry in linked list */
268 struct sClientMemList * mpNext;
269
270 /* Wait queue object for poll() */
271 wait_queue_head_t mWaitQueue;
272
273 } sClientMemList;
274
275 /*=========================================================================*/
276 // Struct sURBSetupPacket
277 //
278 // Structure that defines a USB Setup packet for Control URBs
279 // Taken from USB CDC specifications
280 /*=========================================================================*/
281 typedef struct sURBSetupPacket
282 {
283 /* Request type */
284 u8 mRequestType;
285
286 /* Request code */
287 u8 mRequestCode;
288
289 /* Value */
290 u16 mValue;
291
292 /* Index */
293 u16 mIndex;
294
295 /* Length of Control URB */
296 u16 mLength;
297
298 } sURBSetupPacket;
299
300 // Common value for sURBSetupPacket.mLength
301 #define DEFAULT_READ_URB_LENGTH 0x1000
302
303 #ifdef QUECTEL_QMI_MERGE
304 #define MERGE_PACKET_IDENTITY 0x2c7c
305 #define MERGE_PACKET_VERSION 0x0001
306 #define MERGE_PACKET_MAX_PAYLOAD_SIZE 56
307 typedef struct sQMIMsgHeader {
308 u16 idenity;
309 u16 version;
310 u16 cur_len;
311 u16 total_len;
312 } sQMIMsgHeader;
313
314 typedef struct sQMIMsgPacket {
315 sQMIMsgHeader header;
316 u16 len;
317 char buf[DEFAULT_READ_URB_LENGTH];
318 } sQMIMsgPacket;
319 #endif
320
321 #ifdef CONFIG_PM
322 #if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
323 /*=========================================================================*/
324 // Struct sAutoPM
325 //
326 // Structure used to manage AutoPM thread which determines whether the
327 // device is in use or may enter autosuspend. Also submits net
328 // transmissions asynchronously.
329 /*=========================================================================*/
330 typedef struct sAutoPM
331 {
332 /* Thread for atomic autopm function */
333 struct task_struct * mpThread;
334
335 /* Signal for completion when it's time for the thread to work */
336 struct completion mThreadDoWork;
337
338 /* Time to exit? */
339 bool mbExit;
340
341 /* List of URB's queued to be sent to the device */
342 sURBList * mpURBList;
343
344 /* URB list lock (for adding and removing elements) */
345 spinlock_t mURBListLock;
346
347 /* Length of the URB list */
348 atomic_t mURBListLen;
349
350 /* Active URB */
351 struct urb * mpActiveURB;
352
353 /* Active URB lock (for adding and removing elements) */
354 spinlock_t mActiveURBLock;
355
356 /* Duplicate pointer to USB device interface */
357 struct usb_interface * mpIntf;
358
359 } sAutoPM;
360 #endif
361 #endif /* CONFIG_PM */
362
363 /*=========================================================================*/
364 // Struct sQMIDev
365 //
366 // Structure that defines the data for the QMI device
367 /*=========================================================================*/
368 typedef struct sQMIDev
369 {
370 /* Device number */
371 dev_t mDevNum;
372
373 /* Device class */
374 struct class * mpDevClass;
375
376 /* cdev struct */
377 struct cdev mCdev;
378
379 /* is mCdev initialized? */
380 bool mbCdevIsInitialized;
381
382 /* Pointer to read URB */
383 struct urb * mpReadURB;
384
385 //#define READ_QMI_URB_ERROR
386 #ifdef READ_QMI_URB_ERROR
387 struct timer_list mReadUrbTimer;
388 #endif
389
390 #ifdef QUECTEL_QMI_MERGE
391 sQMIMsgPacket * mpQmiMsgPacket;
392 #endif
393
394 /* Read setup packet */
395 sURBSetupPacket * mpReadSetupPacket;
396
397 /* Read buffer attached to current read URB */
398 void * mpReadBuffer;
399
400 /* Inturrupt URB */
401 /* Used to asynchronously notify when read data is available */
402 struct urb * mpIntURB;
403
404 /* Buffer used by Inturrupt URB */
405 void * mpIntBuffer;
406
407 /* Pointer to memory linked list for all clients */
408 sClientMemList * mpClientMemList;
409
410 /* Spinlock for client Memory entries */
411 spinlock_t mClientMemLock;
412
413 /* Transaction ID associated with QMICTL "client" */
414 atomic_t mQMICTLTransactionID;
415
416 } sQMIDev;
417
418 typedef struct {
419 u32 qmap_enabled;
420 u32 dl_data_aggregation_max_datagrams;
421 u32 dl_data_aggregation_max_size ;
422 u32 ul_data_aggregation_max_datagrams;
423 u32 ul_data_aggregation_max_size;
424 u32 dl_minimum_padding;
425 } QMAP_SETTING;
426
427 /*=========================================================================*/
428 // Struct sGobiUSBNet
429 //
430 // Structure that defines the data associated with the Qualcomm USB device
431 /*=========================================================================*/
432 typedef struct sGobiUSBNet
433 {
434 atomic_t refcount;
435
436 /* Net device structure */
437 struct usbnet * mpNetDev;
438 #ifdef QUECTEL_WWAN_QMAP
439 unsigned link_state;
440 int qmap_mode;
441 int qmap_size;
442 int qmap_version;
443 struct net_device *mpQmapNetDev[QUECTEL_WWAN_QMAP];
444 struct tasklet_struct txq;
445
446 QMAP_SETTING qmap_settings;
447 #if defined(QUECTEL_UL_DATA_AGG)
448 struct ul_agg_ctx agg_ctx;
449 #endif
450
451 #ifdef QUECTEL_BRIDGE_MODE
452 int m_qmap_bridge_mode[QUECTEL_WWAN_QMAP];
453 #endif
454 #endif
455
456 #if 1 //def DATA_MODE_RP
457 bool mbMdm9x07;
458 bool mbMdm9x06; //for BG96
459 /* QMI "device" work in IP Mode or ETH Mode */
460 bool mbRawIPMode;
461 #ifdef QUECTEL_BRIDGE_MODE
462 int m_bridge_mode;
463 uint m_bridge_ipv4;
464 unsigned char mHostMAC[6];
465 #endif
466 int m_qcrmcall_mode;
467 #endif
468
469 struct completion mQMIReadyCompletion;
470 bool mbQMIReady;
471 bool mbProbeDone;
472 bool mbQMISyncIng;
473
474 /* Usb device interface */
475 struct usb_interface * mpIntf;
476
477 /* Pointers to usbnet_open and usbnet_stop functions */
478 int (* mpUSBNetOpen)(struct net_device *);
479 int (* mpUSBNetStop)(struct net_device *);
480
481 /* Reason(s) why interface is down */
482 /* Used by Gobi*DownReason */
483 unsigned long mDownReason;
484 #define NO_NDIS_CONNECTION 0
485 #define CDC_CONNECTION_SPEED 1
486 #define DRIVER_SUSPENDED 2
487 #define NET_IFACE_STOPPED 3
488
489 /* QMI "device" status */
490 bool mbQMIValid;
491
492 bool mbDeregisterQMIDevice;
493
494 /* QMI "device" memory */
495 sQMIDev mQMIDev;
496
497 /* Device MEID */
498 char mMEID[14];
499 struct hrtimer timer;
500 struct tasklet_struct bh;
501 unsigned long
502 pending_num : 8,
503 pending_size : 16;
504 struct sk_buff *pending_pool[16];
505
506 #ifdef CONFIG_PM
507 #if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
508 /* AutoPM thread */
509 sAutoPM mAutoPM;
510 #endif
511 #endif /* CONFIG_PM */
512 } sGobiUSBNet;
513
514 /*=========================================================================*/
515 // Struct sQMIFilpStorage
516 //
517 // Structure that defines the storage each file handle contains
518 // Relates the file handle to a client
519 /*=========================================================================*/
520 typedef struct sQMIFilpStorage
521 {
522 /* Client ID */
523 u16 mClientID;
524
525 /* Device pointer */
526 sGobiUSBNet * mpDev;
527
528 } sQMIFilpStorage;
529
530