aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/usb/rmnet_usb.h
blob: b6617fd41b85c4eb9834c846f4fba1f52e6a6114 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __RMNET_USB_H
#define __RMNET_USB_H

#include <linux/mutex.h>
#include <linux/usb.h>
#include <linux/cdev.h>
#include <linux/usb/ch9.h>
#include <linux/usb/cdc.h>

#define MAX_RMNET_DEVS		4
#define MAX_RMNET_INSTS_PER_DEV	17
#define TOTAL_RMNET_DEV_COUNT	(MAX_RMNET_DEVS * MAX_RMNET_INSTS_PER_DEV)

#define CTRL_DEV_MAX_LEN	10

#define RMNET_CTRL_DEV_OPEN	0
#define RMNET_CTRL_DEV_READY	1
#define RMNET_CTRL_DEV_MUX_EN	2

/*data MUX header bit mask*/
#define MUX_PAD_SHIFT	0x2

/*big endian format ctrl MUX header bit masks*/
#define MUX_CTRL_PADLEN_MASK	0x3F
#define MUX_CTRL_MASK	0x80

/*max padding bytes for n byte alignment*/
#define MAX_PAD_BYTES(n)	(n-1)

/*
 *MUX Header big endian Format
 *BIT 0 - 5 : Pad bytes
 *BIT 6: Reserved
 *BIT 7: Mux type 0: Data, 1: control
 *BIT 8-15: Mux ID
 *BIT 16-31: PACKET_LEN_WITH_PADDING (Bytes)
 */
struct mux_hdr {
	__u8	padding_info;
	__u8	mux_id;
	__u16	pkt_len_w_padding;
} __packed;

struct rmnet_ctrl_udev {

	/*
	 * In case of non-mux ctrl channel there is a one to one mapping
	 * between rmnet_ctrl_dev and rmnet_ctrl_udev. Save the claimed
	 * device id.
	 */
	unsigned int	ctrldev_id;

	unsigned int	rdev_num;
	struct usb_interface	*intf;
	unsigned int		int_pipe;
	struct urb		*rcvurb;
	struct urb		*inturb;
	struct usb_anchor	tx_submitted;
	struct usb_anchor	rx_submitted;
	void			*rcvbuf;
	void			*intbuf;
	struct usb_ctrlrequest	*in_ctlreq;

	struct workqueue_struct *wq;
	struct work_struct	get_encap_work;

	unsigned long		status;

	/*counters*/
	unsigned int		snd_encap_cmd_cnt;
	unsigned int		get_encap_resp_cnt;
	unsigned int		resp_avail_cnt;
	unsigned int		get_encap_failure_cnt;
	unsigned int		set_ctrl_line_state_cnt;
	unsigned int		tx_ctrl_err_cnt;
	unsigned int		zlp_cnt;
	unsigned int		invalid_mux_id_cnt;
	unsigned int		ignore_encap_work;
	bool			autosuspend_disabled;
	unsigned int		autosuspend_en_cnt;
	unsigned int		autosuspend_dis_cnt;
};

struct rmnet_ctrl_dev {

	/*for debugging purpose*/
	char			name[CTRL_DEV_MAX_LEN];

	struct cdev		cdev;
	struct device		*devicep;
	unsigned		ch_id;

	struct rmnet_ctrl_udev *cudev;

	spinlock_t		rx_lock;
	struct mutex		dev_lock;
	struct list_head	rx_list;
	wait_queue_head_t	read_wait_queue;
	wait_queue_head_t	open_wait_queue;
	unsigned long		status;

	bool			claimed;
	bool			poll_err;

	unsigned int		mdm_wait_timeout;

	/*input control lines (DSR, CTS, CD, RI)*/
	unsigned int		cbits_tolocal;
	/*output control lines (DTR, RTS)*/
	unsigned int		cbits_tomdm;
};

extern struct workqueue_struct	*usbnet_wq;

extern int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_udev *);
extern int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_udev *dev);
extern int rmnet_usb_ctrl_init(int num_devs, int insts_per_dev,
		unsigned long mux_info);
extern void rmnet_usb_ctrl_exit(int num_devs, int insts_per_dev,
		unsigned long mux_info);
extern int rmnet_usb_ctrl_probe(struct usb_interface *intf,
				struct usb_host_endpoint *int_in,
				unsigned long rmnet_devnum,
				unsigned long *data);
extern void rmnet_usb_ctrl_disconnect(struct rmnet_ctrl_udev *);

#endif /* __RMNET_USB_H*/