xref: /openbmc/linux/drivers/net/can/usb/ems_usb.c (revision 278002edb19bce2c628fafb0af936e77000f3a5b)
1935912c5SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2702171adSSebastian Haas /*
3702171adSSebastian Haas  * CAN driver for EMS Dr. Thomas Wuensche CPC-USB/ARM7
4702171adSSebastian Haas  *
5702171adSSebastian Haas  * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
6702171adSSebastian Haas  */
7409c188cSVincent Mailhol #include <linux/ethtool.h>
8702171adSSebastian Haas #include <linux/signal.h>
9702171adSSebastian Haas #include <linux/slab.h>
10702171adSSebastian Haas #include <linux/module.h>
11702171adSSebastian Haas #include <linux/netdevice.h>
12702171adSSebastian Haas #include <linux/usb.h>
13702171adSSebastian Haas 
14702171adSSebastian Haas #include <linux/can.h>
15702171adSSebastian Haas #include <linux/can/dev.h>
16702171adSSebastian Haas #include <linux/can/error.h>
17702171adSSebastian Haas 
18702171adSSebastian Haas MODULE_AUTHOR("Sebastian Haas <haas@ems-wuensche.com>");
19702171adSSebastian Haas MODULE_DESCRIPTION("CAN driver for EMS Dr. Thomas Wuensche CAN/USB interfaces");
20702171adSSebastian Haas MODULE_LICENSE("GPL v2");
21702171adSSebastian Haas 
22702171adSSebastian Haas /* Control-Values for CPC_Control() Command Subject Selection */
23702171adSSebastian Haas #define CONTR_CAN_MESSAGE 0x04
24702171adSSebastian Haas #define CONTR_CAN_STATE   0x0C
25702171adSSebastian Haas #define CONTR_BUS_ERROR   0x1C
26702171adSSebastian Haas 
27702171adSSebastian Haas /* Control Command Actions */
28702171adSSebastian Haas #define CONTR_CONT_OFF 0
29702171adSSebastian Haas #define CONTR_CONT_ON  1
30702171adSSebastian Haas #define CONTR_ONCE     2
31702171adSSebastian Haas 
32702171adSSebastian Haas /* Messages from CPC to PC */
33702171adSSebastian Haas #define CPC_MSG_TYPE_CAN_FRAME       1  /* CAN data frame */
34702171adSSebastian Haas #define CPC_MSG_TYPE_RTR_FRAME       8  /* CAN remote frame */
35702171adSSebastian Haas #define CPC_MSG_TYPE_CAN_PARAMS      12 /* Actual CAN parameters */
36702171adSSebastian Haas #define CPC_MSG_TYPE_CAN_STATE       14 /* CAN state message */
37702171adSSebastian Haas #define CPC_MSG_TYPE_EXT_CAN_FRAME   16 /* Extended CAN data frame */
38702171adSSebastian Haas #define CPC_MSG_TYPE_EXT_RTR_FRAME   17 /* Extended remote frame */
39702171adSSebastian Haas #define CPC_MSG_TYPE_CONTROL         19 /* change interface behavior */
40702171adSSebastian Haas #define CPC_MSG_TYPE_CONFIRM         20 /* command processed confirmation */
41702171adSSebastian Haas #define CPC_MSG_TYPE_OVERRUN         21 /* overrun events */
42702171adSSebastian Haas #define CPC_MSG_TYPE_CAN_FRAME_ERROR 23 /* detected bus errors */
43702171adSSebastian Haas #define CPC_MSG_TYPE_ERR_COUNTER     25 /* RX/TX error counter */
44702171adSSebastian Haas 
45702171adSSebastian Haas /* Messages from the PC to the CPC interface  */
46702171adSSebastian Haas #define CPC_CMD_TYPE_CAN_FRAME     1   /* CAN data frame */
47702171adSSebastian Haas #define CPC_CMD_TYPE_CONTROL       3   /* control of interface behavior */
48702171adSSebastian Haas #define CPC_CMD_TYPE_CAN_PARAMS    6   /* set CAN parameters */
49702171adSSebastian Haas #define CPC_CMD_TYPE_RTR_FRAME     13  /* CAN remote frame */
50702171adSSebastian Haas #define CPC_CMD_TYPE_CAN_STATE     14  /* CAN state message */
51702171adSSebastian Haas #define CPC_CMD_TYPE_EXT_CAN_FRAME 15  /* Extended CAN data frame */
52702171adSSebastian Haas #define CPC_CMD_TYPE_EXT_RTR_FRAME 16  /* Extended CAN remote frame */
53702171adSSebastian Haas #define CPC_CMD_TYPE_CAN_EXIT      200 /* exit the CAN */
54702171adSSebastian Haas 
55702171adSSebastian Haas #define CPC_CMD_TYPE_INQ_ERR_COUNTER 25 /* request the CAN error counters */
56702171adSSebastian Haas #define CPC_CMD_TYPE_CLEAR_MSG_QUEUE 8  /* clear CPC_MSG queue */
57702171adSSebastian Haas #define CPC_CMD_TYPE_CLEAR_CMD_QUEUE 28 /* clear CPC_CMD queue */
58702171adSSebastian Haas 
59702171adSSebastian Haas #define CPC_CC_TYPE_SJA1000 2 /* Philips basic CAN controller */
60702171adSSebastian Haas 
61702171adSSebastian Haas #define CPC_CAN_ECODE_ERRFRAME 0x01 /* Ecode type */
62702171adSSebastian Haas 
63702171adSSebastian Haas /* Overrun types */
64702171adSSebastian Haas #define CPC_OVR_EVENT_CAN       0x01
65702171adSSebastian Haas #define CPC_OVR_EVENT_CANSTATE  0x02
66702171adSSebastian Haas #define CPC_OVR_EVENT_BUSERROR  0x04
67702171adSSebastian Haas 
68702171adSSebastian Haas /*
69702171adSSebastian Haas  * If the CAN controller lost a message we indicate it with the highest bit
70702171adSSebastian Haas  * set in the count field.
71702171adSSebastian Haas  */
72702171adSSebastian Haas #define CPC_OVR_HW 0x80
73702171adSSebastian Haas 
74702171adSSebastian Haas /* Size of the "struct ems_cpc_msg" without the union */
75702171adSSebastian Haas #define CPC_MSG_HEADER_LEN   11
76702171adSSebastian Haas #define CPC_CAN_MSG_MIN_SIZE 5
77702171adSSebastian Haas 
78702171adSSebastian Haas /* Define these values to match your devices */
79702171adSSebastian Haas #define USB_CPCUSB_VENDOR_ID 0x12D6
80702171adSSebastian Haas 
81702171adSSebastian Haas #define USB_CPCUSB_ARM7_PRODUCT_ID 0x0444
82702171adSSebastian Haas 
83702171adSSebastian Haas /* Mode register NXP LPC2119/SJA1000 CAN Controller */
84702171adSSebastian Haas #define SJA1000_MOD_NORMAL 0x00
85702171adSSebastian Haas #define SJA1000_MOD_RM     0x01
86702171adSSebastian Haas 
87702171adSSebastian Haas /* ECC register NXP LPC2119/SJA1000 CAN Controller */
88702171adSSebastian Haas #define SJA1000_ECC_SEG   0x1F
89702171adSSebastian Haas #define SJA1000_ECC_DIR   0x20
90702171adSSebastian Haas #define SJA1000_ECC_ERR   0x06
91702171adSSebastian Haas #define SJA1000_ECC_BIT   0x00
92702171adSSebastian Haas #define SJA1000_ECC_FORM  0x40
93702171adSSebastian Haas #define SJA1000_ECC_STUFF 0x80
94702171adSSebastian Haas #define SJA1000_ECC_MASK  0xc0
95702171adSSebastian Haas 
96702171adSSebastian Haas /* Status register content */
97702171adSSebastian Haas #define SJA1000_SR_BS 0x80
98702171adSSebastian Haas #define SJA1000_SR_ES 0x40
99702171adSSebastian Haas 
100702171adSSebastian Haas #define SJA1000_DEFAULT_OUTPUT_CONTROL 0xDA
101702171adSSebastian Haas 
102702171adSSebastian Haas /*
103702171adSSebastian Haas  * The device actually uses a 16MHz clock to generate the CAN clock
104702171adSSebastian Haas  * but it expects SJA1000 bit settings based on 8MHz (is internally
105702171adSSebastian Haas  * converted).
106702171adSSebastian Haas  */
107702171adSSebastian Haas #define EMS_USB_ARM7_CLOCK 8000000
108702171adSSebastian Haas 
10990cfde46SGerhard Uttenthaler #define CPC_TX_QUEUE_TRIGGER_LOW	25
11090cfde46SGerhard Uttenthaler #define CPC_TX_QUEUE_TRIGGER_HIGH	35
11190cfde46SGerhard Uttenthaler 
112702171adSSebastian Haas /*
113702171adSSebastian Haas  * CAN-Message representation in a CPC_MSG. Message object type is
114702171adSSebastian Haas  * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
115702171adSSebastian Haas  * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME.
116702171adSSebastian Haas  */
117702171adSSebastian Haas struct cpc_can_msg {
1188a4b5b0fSGerhard Uttenthaler 	__le32 id;
119702171adSSebastian Haas 	u8 length;
120702171adSSebastian Haas 	u8 msg[8];
121702171adSSebastian Haas };
122702171adSSebastian Haas 
123702171adSSebastian Haas /* Representation of the CAN parameters for the SJA1000 controller */
124702171adSSebastian Haas struct cpc_sja1000_params {
125702171adSSebastian Haas 	u8 mode;
126702171adSSebastian Haas 	u8 acc_code0;
127702171adSSebastian Haas 	u8 acc_code1;
128702171adSSebastian Haas 	u8 acc_code2;
129702171adSSebastian Haas 	u8 acc_code3;
130702171adSSebastian Haas 	u8 acc_mask0;
131702171adSSebastian Haas 	u8 acc_mask1;
132702171adSSebastian Haas 	u8 acc_mask2;
133702171adSSebastian Haas 	u8 acc_mask3;
134702171adSSebastian Haas 	u8 btr0;
135702171adSSebastian Haas 	u8 btr1;
136702171adSSebastian Haas 	u8 outp_contr;
137702171adSSebastian Haas };
138702171adSSebastian Haas 
139702171adSSebastian Haas /* CAN params message representation */
140702171adSSebastian Haas struct cpc_can_params {
141702171adSSebastian Haas 	u8 cc_type;
142702171adSSebastian Haas 
143702171adSSebastian Haas 	/* Will support M16C CAN controller in the future */
144702171adSSebastian Haas 	union {
145702171adSSebastian Haas 		struct cpc_sja1000_params sja1000;
146702171adSSebastian Haas 	} cc_params;
147702171adSSebastian Haas };
148702171adSSebastian Haas 
149702171adSSebastian Haas /* Structure for confirmed message handling */
150702171adSSebastian Haas struct cpc_confirm {
151702171adSSebastian Haas 	u8 error; /* error code */
152702171adSSebastian Haas };
153702171adSSebastian Haas 
154702171adSSebastian Haas /* Structure for overrun conditions */
155702171adSSebastian Haas struct cpc_overrun {
156702171adSSebastian Haas 	u8 event;
157702171adSSebastian Haas 	u8 count;
158702171adSSebastian Haas };
159702171adSSebastian Haas 
160702171adSSebastian Haas /* SJA1000 CAN errors (compatible to NXP LPC2119) */
161702171adSSebastian Haas struct cpc_sja1000_can_error {
162702171adSSebastian Haas 	u8 ecc;
163702171adSSebastian Haas 	u8 rxerr;
164702171adSSebastian Haas 	u8 txerr;
165702171adSSebastian Haas };
166702171adSSebastian Haas 
167702171adSSebastian Haas /* structure for CAN error conditions */
168702171adSSebastian Haas struct cpc_can_error {
169702171adSSebastian Haas 	u8 ecode;
170702171adSSebastian Haas 
171702171adSSebastian Haas 	struct {
172702171adSSebastian Haas 		u8 cc_type;
173702171adSSebastian Haas 
174702171adSSebastian Haas 		/* Other controllers may also provide error code capture regs */
175702171adSSebastian Haas 		union {
176702171adSSebastian Haas 			struct cpc_sja1000_can_error sja1000;
177702171adSSebastian Haas 		} regs;
178702171adSSebastian Haas 	} cc;
179702171adSSebastian Haas };
180702171adSSebastian Haas 
181702171adSSebastian Haas /*
182702171adSSebastian Haas  * Structure containing RX/TX error counter. This structure is used to request
183702171adSSebastian Haas  * the values of the CAN controllers TX and RX error counter.
184702171adSSebastian Haas  */
185702171adSSebastian Haas struct cpc_can_err_counter {
186702171adSSebastian Haas 	u8 rx;
187702171adSSebastian Haas 	u8 tx;
188702171adSSebastian Haas };
189702171adSSebastian Haas 
190702171adSSebastian Haas /* Main message type used between library and application */
191ba2d3587SEric Dumazet struct __packed ems_cpc_msg {
192702171adSSebastian Haas 	u8 type;	/* type of message */
193702171adSSebastian Haas 	u8 length;	/* length of data within union 'msg' */
194702171adSSebastian Haas 	u8 msgid;	/* confirmation handle */
195a0bc163aSMarc Kleine-Budde 	__le32 ts_sec;	/* timestamp in seconds */
196a0bc163aSMarc Kleine-Budde 	__le32 ts_nsec;	/* timestamp in nano seconds */
197702171adSSebastian Haas 
198a4cb6e62SMarc Kleine-Budde 	union __packed {
199702171adSSebastian Haas 		u8 generic[64];
200702171adSSebastian Haas 		struct cpc_can_msg can_msg;
201702171adSSebastian Haas 		struct cpc_can_params can_params;
202702171adSSebastian Haas 		struct cpc_confirm confirmation;
203702171adSSebastian Haas 		struct cpc_overrun overrun;
204702171adSSebastian Haas 		struct cpc_can_error error;
205702171adSSebastian Haas 		struct cpc_can_err_counter err_counter;
206702171adSSebastian Haas 		u8 can_state;
207702171adSSebastian Haas 	} msg;
208702171adSSebastian Haas };
209702171adSSebastian Haas 
210702171adSSebastian Haas /*
211702171adSSebastian Haas  * Table of devices that work with this driver
212702171adSSebastian Haas  * NOTE: This driver supports only CPC-USB/ARM7 (LPC2119) yet.
213702171adSSebastian Haas  */
214702171adSSebastian Haas static struct usb_device_id ems_usb_table[] = {
215702171adSSebastian Haas 	{USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_ARM7_PRODUCT_ID)},
216702171adSSebastian Haas 	{} /* Terminating entry */
217702171adSSebastian Haas };
218702171adSSebastian Haas 
219702171adSSebastian Haas MODULE_DEVICE_TABLE(usb, ems_usb_table);
220702171adSSebastian Haas 
221702171adSSebastian Haas #define RX_BUFFER_SIZE      64
222702171adSSebastian Haas #define CPC_HEADER_SIZE     4
223702171adSSebastian Haas #define INTR_IN_BUFFER_SIZE 4
224702171adSSebastian Haas 
225702171adSSebastian Haas #define MAX_RX_URBS 10
226a6e4bc53SWolfgang Grandegger #define MAX_TX_URBS 10
227702171adSSebastian Haas 
228702171adSSebastian Haas struct ems_usb;
229702171adSSebastian Haas 
230702171adSSebastian Haas struct ems_tx_urb_context {
231702171adSSebastian Haas 	struct ems_usb *dev;
232702171adSSebastian Haas 
233702171adSSebastian Haas 	u32 echo_index;
234702171adSSebastian Haas };
235702171adSSebastian Haas 
236702171adSSebastian Haas struct ems_usb {
237702171adSSebastian Haas 	struct can_priv can; /* must be the first member */
238702171adSSebastian Haas 
239702171adSSebastian Haas 	struct sk_buff *echo_skb[MAX_TX_URBS];
240702171adSSebastian Haas 
241702171adSSebastian Haas 	struct usb_device *udev;
242702171adSSebastian Haas 	struct net_device *netdev;
243702171adSSebastian Haas 
244702171adSSebastian Haas 	atomic_t active_tx_urbs;
245702171adSSebastian Haas 	struct usb_anchor tx_submitted;
246702171adSSebastian Haas 	struct ems_tx_urb_context tx_contexts[MAX_TX_URBS];
247702171adSSebastian Haas 
248702171adSSebastian Haas 	struct usb_anchor rx_submitted;
249702171adSSebastian Haas 
250702171adSSebastian Haas 	struct urb *intr_urb;
251702171adSSebastian Haas 
252702171adSSebastian Haas 	u8 *tx_msg_buffer;
253702171adSSebastian Haas 
254702171adSSebastian Haas 	u8 *intr_in_buffer;
255702171adSSebastian Haas 	unsigned int free_slots; /* remember number of available slots */
256702171adSSebastian Haas 
257702171adSSebastian Haas 	struct ems_cpc_msg active_params; /* active controller parameters */
2589969e3c5SPavel Skripkin 	void *rxbuf[MAX_RX_URBS];
2599969e3c5SPavel Skripkin 	dma_addr_t rxbuf_dma[MAX_RX_URBS];
260702171adSSebastian Haas };
261702171adSSebastian Haas 
ems_usb_read_interrupt_callback(struct urb * urb)262702171adSSebastian Haas static void ems_usb_read_interrupt_callback(struct urb *urb)
263702171adSSebastian Haas {
264702171adSSebastian Haas 	struct ems_usb *dev = urb->context;
265702171adSSebastian Haas 	struct net_device *netdev = dev->netdev;
266702171adSSebastian Haas 	int err;
267702171adSSebastian Haas 
268702171adSSebastian Haas 	if (!netif_device_present(netdev))
269702171adSSebastian Haas 		return;
270702171adSSebastian Haas 
271702171adSSebastian Haas 	switch (urb->status) {
272702171adSSebastian Haas 	case 0:
273702171adSSebastian Haas 		dev->free_slots = dev->intr_in_buffer[1];
27459097ac9SMarc Kleine-Budde 		if (dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH &&
27559097ac9SMarc Kleine-Budde 		    netif_queue_stopped(netdev))
27690cfde46SGerhard Uttenthaler 			netif_wake_queue(netdev);
277702171adSSebastian Haas 		break;
278702171adSSebastian Haas 
279702171adSSebastian Haas 	case -ECONNRESET: /* unlink */
280702171adSSebastian Haas 	case -ENOENT:
281bd352e1aSMartin Kelly 	case -EPIPE:
282bd352e1aSMartin Kelly 	case -EPROTO:
283702171adSSebastian Haas 	case -ESHUTDOWN:
284702171adSSebastian Haas 		return;
285702171adSSebastian Haas 
286702171adSSebastian Haas 	default:
287aabdfd6aSWolfgang Grandegger 		netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status);
288702171adSSebastian Haas 		break;
289702171adSSebastian Haas 	}
290702171adSSebastian Haas 
291702171adSSebastian Haas 	err = usb_submit_urb(urb, GFP_ATOMIC);
292702171adSSebastian Haas 
293702171adSSebastian Haas 	if (err == -ENODEV)
294702171adSSebastian Haas 		netif_device_detach(netdev);
295702171adSSebastian Haas 	else if (err)
296aabdfd6aSWolfgang Grandegger 		netdev_err(netdev, "failed resubmitting intr urb: %d\n", err);
297702171adSSebastian Haas }
298702171adSSebastian Haas 
ems_usb_rx_can_msg(struct ems_usb * dev,struct ems_cpc_msg * msg)299702171adSSebastian Haas static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
300702171adSSebastian Haas {
301702171adSSebastian Haas 	struct can_frame *cf;
302702171adSSebastian Haas 	struct sk_buff *skb;
303702171adSSebastian Haas 	int i;
304702171adSSebastian Haas 	struct net_device_stats *stats = &dev->netdev->stats;
305702171adSSebastian Haas 
3067b6856a0SWolfgang Grandegger 	skb = alloc_can_skb(dev->netdev, &cf);
307702171adSSebastian Haas 	if (skb == NULL)
308702171adSSebastian Haas 		return;
309702171adSSebastian Haas 
3102b2072e9SSebastian Haas 	cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
311c7b74967SOliver Hartkopp 	cf->len = can_cc_dlc2len(msg->msg.can_msg.length & 0xF);
312702171adSSebastian Haas 
3138e95a202SJoe Perches 	if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME ||
3148e95a202SJoe Perches 	    msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
315702171adSSebastian Haas 		cf->can_id |= CAN_EFF_FLAG;
316702171adSSebastian Haas 
3178e95a202SJoe Perches 	if (msg->type == CPC_MSG_TYPE_RTR_FRAME ||
3188e95a202SJoe Perches 	    msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) {
319702171adSSebastian Haas 		cf->can_id |= CAN_RTR_FLAG;
320702171adSSebastian Haas 	} else {
321c7b74967SOliver Hartkopp 		for (i = 0; i < cf->len; i++)
322702171adSSebastian Haas 			cf->data[i] = msg->msg.can_msg.msg[i];
323702171adSSebastian Haas 
324c7b74967SOliver Hartkopp 		stats->rx_bytes += cf->len;
3258e674ca7SVincent Mailhol 	}
3268e674ca7SVincent Mailhol 	stats->rx_packets++;
3278e674ca7SVincent Mailhol 
32843c021e8SMarc Kleine-Budde 	netif_rx(skb);
329702171adSSebastian Haas }
330702171adSSebastian Haas 
ems_usb_rx_err(struct ems_usb * dev,struct ems_cpc_msg * msg)331702171adSSebastian Haas static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
332702171adSSebastian Haas {
333702171adSSebastian Haas 	struct can_frame *cf;
334702171adSSebastian Haas 	struct sk_buff *skb;
335702171adSSebastian Haas 	struct net_device_stats *stats = &dev->netdev->stats;
336702171adSSebastian Haas 
3377b6856a0SWolfgang Grandegger 	skb = alloc_can_err_skb(dev->netdev, &cf);
338702171adSSebastian Haas 
339702171adSSebastian Haas 	if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
340702171adSSebastian Haas 		u8 state = msg->msg.can_state;
341702171adSSebastian Haas 
342702171adSSebastian Haas 		if (state & SJA1000_SR_BS) {
343702171adSSebastian Haas 			dev->can.state = CAN_STATE_BUS_OFF;
344*c7f3a539SDario Binacchi 			if (skb)
345702171adSSebastian Haas 				cf->can_id |= CAN_ERR_BUSOFF;
346702171adSSebastian Haas 
347be38a6f9SAndri Yngvason 			dev->can.can_stats.bus_off++;
348702171adSSebastian Haas 			can_bus_off(dev->netdev);
349702171adSSebastian Haas 		} else if (state & SJA1000_SR_ES) {
350702171adSSebastian Haas 			dev->can.state = CAN_STATE_ERROR_WARNING;
351702171adSSebastian Haas 			dev->can.can_stats.error_warning++;
352702171adSSebastian Haas 		} else {
353702171adSSebastian Haas 			dev->can.state = CAN_STATE_ERROR_ACTIVE;
354702171adSSebastian Haas 			dev->can.can_stats.error_passive++;
355702171adSSebastian Haas 		}
356702171adSSebastian Haas 	} else if (msg->type == CPC_MSG_TYPE_CAN_FRAME_ERROR) {
357702171adSSebastian Haas 		u8 ecc = msg->msg.error.cc.regs.sja1000.ecc;
358702171adSSebastian Haas 		u8 txerr = msg->msg.error.cc.regs.sja1000.txerr;
359702171adSSebastian Haas 		u8 rxerr = msg->msg.error.cc.regs.sja1000.rxerr;
360702171adSSebastian Haas 
361702171adSSebastian Haas 		/* bus error interrupt */
362702171adSSebastian Haas 		dev->can.can_stats.bus_error++;
363702171adSSebastian Haas 
364*c7f3a539SDario Binacchi 		if (skb) {
365702171adSSebastian Haas 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
366702171adSSebastian Haas 
367702171adSSebastian Haas 			switch (ecc & SJA1000_ECC_MASK) {
368702171adSSebastian Haas 			case SJA1000_ECC_BIT:
369702171adSSebastian Haas 				cf->data[2] |= CAN_ERR_PROT_BIT;
370702171adSSebastian Haas 				break;
371702171adSSebastian Haas 			case SJA1000_ECC_FORM:
372702171adSSebastian Haas 				cf->data[2] |= CAN_ERR_PROT_FORM;
373702171adSSebastian Haas 				break;
374702171adSSebastian Haas 			case SJA1000_ECC_STUFF:
375702171adSSebastian Haas 				cf->data[2] |= CAN_ERR_PROT_STUFF;
376702171adSSebastian Haas 				break;
377702171adSSebastian Haas 			default:
378702171adSSebastian Haas 				cf->data[3] = ecc & SJA1000_ECC_SEG;
379702171adSSebastian Haas 				break;
380702171adSSebastian Haas 			}
381*c7f3a539SDario Binacchi 		}
382702171adSSebastian Haas 
38325985edcSLucas De Marchi 		/* Error occurred during transmission? */
384*c7f3a539SDario Binacchi 		if ((ecc & SJA1000_ECC_DIR) == 0) {
385*c7f3a539SDario Binacchi 			stats->tx_errors++;
386*c7f3a539SDario Binacchi 			if (skb)
387702171adSSebastian Haas 				cf->data[2] |= CAN_ERR_PROT_TX;
388*c7f3a539SDario Binacchi 		} else {
389*c7f3a539SDario Binacchi 			stats->rx_errors++;
390*c7f3a539SDario Binacchi 		}
391702171adSSebastian Haas 
392*c7f3a539SDario Binacchi 		if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING ||
393*c7f3a539SDario Binacchi 			    dev->can.state == CAN_STATE_ERROR_PASSIVE)) {
3946ebc5e8fSMartin Lederhilger 			cf->can_id |= CAN_ERR_CRTL;
395702171adSSebastian Haas 			cf->data[1] = (txerr > rxerr) ?
396702171adSSebastian Haas 			    CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
397702171adSSebastian Haas 		}
398702171adSSebastian Haas 	} else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
399*c7f3a539SDario Binacchi 		if (skb) {
400702171adSSebastian Haas 			cf->can_id |= CAN_ERR_CRTL;
401702171adSSebastian Haas 			cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
402*c7f3a539SDario Binacchi 		}
403702171adSSebastian Haas 
404702171adSSebastian Haas 		stats->rx_over_errors++;
405702171adSSebastian Haas 		stats->rx_errors++;
406702171adSSebastian Haas 	}
407702171adSSebastian Haas 
408*c7f3a539SDario Binacchi 	if (skb)
40943c021e8SMarc Kleine-Budde 		netif_rx(skb);
410702171adSSebastian Haas }
411702171adSSebastian Haas 
412702171adSSebastian Haas /*
413702171adSSebastian Haas  * callback for bulk IN urb
414702171adSSebastian Haas  */
ems_usb_read_bulk_callback(struct urb * urb)415702171adSSebastian Haas static void ems_usb_read_bulk_callback(struct urb *urb)
416702171adSSebastian Haas {
417702171adSSebastian Haas 	struct ems_usb *dev = urb->context;
418702171adSSebastian Haas 	struct net_device *netdev;
419702171adSSebastian Haas 	int retval;
420702171adSSebastian Haas 
421702171adSSebastian Haas 	netdev = dev->netdev;
422702171adSSebastian Haas 
423702171adSSebastian Haas 	if (!netif_device_present(netdev))
424702171adSSebastian Haas 		return;
425702171adSSebastian Haas 
426702171adSSebastian Haas 	switch (urb->status) {
427702171adSSebastian Haas 	case 0: /* success */
428702171adSSebastian Haas 		break;
429702171adSSebastian Haas 
430702171adSSebastian Haas 	case -ENOENT:
431702171adSSebastian Haas 		return;
432702171adSSebastian Haas 
433702171adSSebastian Haas 	default:
434aabdfd6aSWolfgang Grandegger 		netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status);
435702171adSSebastian Haas 		goto resubmit_urb;
436702171adSSebastian Haas 	}
437702171adSSebastian Haas 
438702171adSSebastian Haas 	if (urb->actual_length > CPC_HEADER_SIZE) {
439702171adSSebastian Haas 		struct ems_cpc_msg *msg;
440702171adSSebastian Haas 		u8 *ibuf = urb->transfer_buffer;
4414e2061b1SSudip Mukherjee 		u8 msg_count, start;
442702171adSSebastian Haas 
443702171adSSebastian Haas 		msg_count = ibuf[0] & ~0x80;
444702171adSSebastian Haas 
445702171adSSebastian Haas 		start = CPC_HEADER_SIZE;
446702171adSSebastian Haas 
447702171adSSebastian Haas 		while (msg_count) {
448702171adSSebastian Haas 			msg = (struct ems_cpc_msg *)&ibuf[start];
449702171adSSebastian Haas 
450702171adSSebastian Haas 			switch (msg->type) {
451702171adSSebastian Haas 			case CPC_MSG_TYPE_CAN_STATE:
452702171adSSebastian Haas 				/* Process CAN state changes */
453702171adSSebastian Haas 				ems_usb_rx_err(dev, msg);
454702171adSSebastian Haas 				break;
455702171adSSebastian Haas 
456702171adSSebastian Haas 			case CPC_MSG_TYPE_CAN_FRAME:
457702171adSSebastian Haas 			case CPC_MSG_TYPE_EXT_CAN_FRAME:
458702171adSSebastian Haas 			case CPC_MSG_TYPE_RTR_FRAME:
459702171adSSebastian Haas 			case CPC_MSG_TYPE_EXT_RTR_FRAME:
460702171adSSebastian Haas 				ems_usb_rx_can_msg(dev, msg);
461702171adSSebastian Haas 				break;
462702171adSSebastian Haas 
463702171adSSebastian Haas 			case CPC_MSG_TYPE_CAN_FRAME_ERROR:
464702171adSSebastian Haas 				/* Process errorframe */
465702171adSSebastian Haas 				ems_usb_rx_err(dev, msg);
466702171adSSebastian Haas 				break;
467702171adSSebastian Haas 
468702171adSSebastian Haas 			case CPC_MSG_TYPE_OVERRUN:
469702171adSSebastian Haas 				/* Message lost while receiving */
470702171adSSebastian Haas 				ems_usb_rx_err(dev, msg);
471702171adSSebastian Haas 				break;
472702171adSSebastian Haas 			}
473702171adSSebastian Haas 
474702171adSSebastian Haas 			start += CPC_MSG_HEADER_LEN + msg->length;
475702171adSSebastian Haas 			msg_count--;
476702171adSSebastian Haas 
477702171adSSebastian Haas 			if (start > urb->transfer_buffer_length) {
478aabdfd6aSWolfgang Grandegger 				netdev_err(netdev, "format error\n");
479702171adSSebastian Haas 				break;
480702171adSSebastian Haas 			}
481702171adSSebastian Haas 		}
482702171adSSebastian Haas 	}
483702171adSSebastian Haas 
484702171adSSebastian Haas resubmit_urb:
485702171adSSebastian Haas 	usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
486702171adSSebastian Haas 			  urb->transfer_buffer, RX_BUFFER_SIZE,
487702171adSSebastian Haas 			  ems_usb_read_bulk_callback, dev);
488702171adSSebastian Haas 
489702171adSSebastian Haas 	retval = usb_submit_urb(urb, GFP_ATOMIC);
490702171adSSebastian Haas 
491702171adSSebastian Haas 	if (retval == -ENODEV)
492702171adSSebastian Haas 		netif_device_detach(netdev);
493702171adSSebastian Haas 	else if (retval)
494aabdfd6aSWolfgang Grandegger 		netdev_err(netdev,
495702171adSSebastian Haas 			   "failed resubmitting read bulk urb: %d\n", retval);
496702171adSSebastian Haas }
497702171adSSebastian Haas 
498702171adSSebastian Haas /*
499702171adSSebastian Haas  * callback for bulk IN urb
500702171adSSebastian Haas  */
ems_usb_write_bulk_callback(struct urb * urb)501702171adSSebastian Haas static void ems_usb_write_bulk_callback(struct urb *urb)
502702171adSSebastian Haas {
503702171adSSebastian Haas 	struct ems_tx_urb_context *context = urb->context;
504702171adSSebastian Haas 	struct ems_usb *dev;
505702171adSSebastian Haas 	struct net_device *netdev;
506702171adSSebastian Haas 
507702171adSSebastian Haas 	BUG_ON(!context);
508702171adSSebastian Haas 
509702171adSSebastian Haas 	dev = context->dev;
510702171adSSebastian Haas 	netdev = dev->netdev;
511702171adSSebastian Haas 
512702171adSSebastian Haas 	/* free up our allocated buffer */
513997ea58eSDaniel Mack 	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
514702171adSSebastian Haas 			  urb->transfer_buffer, urb->transfer_dma);
515702171adSSebastian Haas 
516702171adSSebastian Haas 	atomic_dec(&dev->active_tx_urbs);
517702171adSSebastian Haas 
518702171adSSebastian Haas 	if (!netif_device_present(netdev))
519702171adSSebastian Haas 		return;
520702171adSSebastian Haas 
521702171adSSebastian Haas 	if (urb->status)
522aabdfd6aSWolfgang Grandegger 		netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
523702171adSSebastian Haas 
524860e9538SFlorian Westphal 	netif_trans_update(netdev);
525702171adSSebastian Haas 
526702171adSSebastian Haas 	/* transmission complete interrupt */
527702171adSSebastian Haas 	netdev->stats.tx_packets++;
528cc4b08c3SVincent Mailhol 	netdev->stats.tx_bytes += can_get_echo_skb(netdev, context->echo_index,
529cc4b08c3SVincent Mailhol 						   NULL);
530702171adSSebastian Haas 
531702171adSSebastian Haas 	/* Release context */
532702171adSSebastian Haas 	context->echo_index = MAX_TX_URBS;
533702171adSSebastian Haas 
534702171adSSebastian Haas }
535702171adSSebastian Haas 
536702171adSSebastian Haas /*
537702171adSSebastian Haas  * Send the given CPC command synchronously
538702171adSSebastian Haas  */
ems_usb_command_msg(struct ems_usb * dev,struct ems_cpc_msg * msg)539702171adSSebastian Haas static int ems_usb_command_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
540702171adSSebastian Haas {
541702171adSSebastian Haas 	int actual_length;
542702171adSSebastian Haas 
543702171adSSebastian Haas 	/* Copy payload */
544702171adSSebastian Haas 	memcpy(&dev->tx_msg_buffer[CPC_HEADER_SIZE], msg,
545702171adSSebastian Haas 	       msg->length + CPC_MSG_HEADER_LEN);
546702171adSSebastian Haas 
547702171adSSebastian Haas 	/* Clear header */
548702171adSSebastian Haas 	memset(&dev->tx_msg_buffer[0], 0, CPC_HEADER_SIZE);
549702171adSSebastian Haas 
550702171adSSebastian Haas 	return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
551702171adSSebastian Haas 			    &dev->tx_msg_buffer[0],
552702171adSSebastian Haas 			    msg->length + CPC_MSG_HEADER_LEN + CPC_HEADER_SIZE,
553702171adSSebastian Haas 			    &actual_length, 1000);
554702171adSSebastian Haas }
555702171adSSebastian Haas 
556702171adSSebastian Haas /*
557702171adSSebastian Haas  * Change CAN controllers' mode register
558702171adSSebastian Haas  */
ems_usb_write_mode(struct ems_usb * dev,u8 mode)559702171adSSebastian Haas static int ems_usb_write_mode(struct ems_usb *dev, u8 mode)
560702171adSSebastian Haas {
561702171adSSebastian Haas 	dev->active_params.msg.can_params.cc_params.sja1000.mode = mode;
562702171adSSebastian Haas 
563702171adSSebastian Haas 	return ems_usb_command_msg(dev, &dev->active_params);
564702171adSSebastian Haas }
565702171adSSebastian Haas 
566702171adSSebastian Haas /*
567702171adSSebastian Haas  * Send a CPC_Control command to change behaviour when interface receives a CAN
568702171adSSebastian Haas  * message, bus error or CAN state changed notifications.
569702171adSSebastian Haas  */
ems_usb_control_cmd(struct ems_usb * dev,u8 val)570702171adSSebastian Haas static int ems_usb_control_cmd(struct ems_usb *dev, u8 val)
571702171adSSebastian Haas {
572702171adSSebastian Haas 	struct ems_cpc_msg cmd;
573702171adSSebastian Haas 
574702171adSSebastian Haas 	cmd.type = CPC_CMD_TYPE_CONTROL;
575702171adSSebastian Haas 	cmd.length = CPC_MSG_HEADER_LEN + 1;
576702171adSSebastian Haas 
577702171adSSebastian Haas 	cmd.msgid = 0;
578702171adSSebastian Haas 
579702171adSSebastian Haas 	cmd.msg.generic[0] = val;
580702171adSSebastian Haas 
581702171adSSebastian Haas 	return ems_usb_command_msg(dev, &cmd);
582702171adSSebastian Haas }
583702171adSSebastian Haas 
584702171adSSebastian Haas /*
585702171adSSebastian Haas  * Start interface
586702171adSSebastian Haas  */
ems_usb_start(struct ems_usb * dev)587702171adSSebastian Haas static int ems_usb_start(struct ems_usb *dev)
588702171adSSebastian Haas {
589702171adSSebastian Haas 	struct net_device *netdev = dev->netdev;
590702171adSSebastian Haas 	int err, i;
591702171adSSebastian Haas 
592702171adSSebastian Haas 	dev->intr_in_buffer[0] = 0;
59390cfde46SGerhard Uttenthaler 	dev->free_slots = 50; /* initial size */
594702171adSSebastian Haas 
595702171adSSebastian Haas 	for (i = 0; i < MAX_RX_URBS; i++) {
596702171adSSebastian Haas 		struct urb *urb = NULL;
597702171adSSebastian Haas 		u8 *buf = NULL;
5989969e3c5SPavel Skripkin 		dma_addr_t buf_dma;
599702171adSSebastian Haas 
600702171adSSebastian Haas 		/* create a URB, and a buffer for it */
601702171adSSebastian Haas 		urb = usb_alloc_urb(0, GFP_KERNEL);
602702171adSSebastian Haas 		if (!urb) {
6032ee6850cSSebastian Haas 			err = -ENOMEM;
6042ee6850cSSebastian Haas 			break;
605702171adSSebastian Haas 		}
606702171adSSebastian Haas 
607997ea58eSDaniel Mack 		buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
6089969e3c5SPavel Skripkin 					 &buf_dma);
609702171adSSebastian Haas 		if (!buf) {
610aabdfd6aSWolfgang Grandegger 			netdev_err(netdev, "No memory left for USB buffer\n");
611702171adSSebastian Haas 			usb_free_urb(urb);
6122ee6850cSSebastian Haas 			err = -ENOMEM;
6132ee6850cSSebastian Haas 			break;
614702171adSSebastian Haas 		}
615702171adSSebastian Haas 
6169969e3c5SPavel Skripkin 		urb->transfer_dma = buf_dma;
6179969e3c5SPavel Skripkin 
618702171adSSebastian Haas 		usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
619702171adSSebastian Haas 				  buf, RX_BUFFER_SIZE,
620702171adSSebastian Haas 				  ems_usb_read_bulk_callback, dev);
621702171adSSebastian Haas 		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
622702171adSSebastian Haas 		usb_anchor_urb(urb, &dev->rx_submitted);
623702171adSSebastian Haas 
624702171adSSebastian Haas 		err = usb_submit_urb(urb, GFP_KERNEL);
625702171adSSebastian Haas 		if (err) {
626702171adSSebastian Haas 			usb_unanchor_urb(urb);
627997ea58eSDaniel Mack 			usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
628702171adSSebastian Haas 					  urb->transfer_dma);
629a1c31f1dSAlexey Khoroshilov 			usb_free_urb(urb);
630702171adSSebastian Haas 			break;
631702171adSSebastian Haas 		}
632702171adSSebastian Haas 
6339969e3c5SPavel Skripkin 		dev->rxbuf[i] = buf;
6349969e3c5SPavel Skripkin 		dev->rxbuf_dma[i] = buf_dma;
6359969e3c5SPavel Skripkin 
636702171adSSebastian Haas 		/* Drop reference, USB core will take care of freeing it */
637702171adSSebastian Haas 		usb_free_urb(urb);
638702171adSSebastian Haas 	}
639702171adSSebastian Haas 
640702171adSSebastian Haas 	/* Did we submit any URBs */
641702171adSSebastian Haas 	if (i == 0) {
642aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "couldn't setup read URBs\n");
643702171adSSebastian Haas 		return err;
644702171adSSebastian Haas 	}
645702171adSSebastian Haas 
646702171adSSebastian Haas 	/* Warn if we've couldn't transmit all the URBs */
647702171adSSebastian Haas 	if (i < MAX_RX_URBS)
648aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "rx performance may be slow\n");
649702171adSSebastian Haas 
650702171adSSebastian Haas 	/* Setup and start interrupt URB */
651702171adSSebastian Haas 	usb_fill_int_urb(dev->intr_urb, dev->udev,
652702171adSSebastian Haas 			 usb_rcvintpipe(dev->udev, 1),
653702171adSSebastian Haas 			 dev->intr_in_buffer,
654702171adSSebastian Haas 			 INTR_IN_BUFFER_SIZE,
655702171adSSebastian Haas 			 ems_usb_read_interrupt_callback, dev, 1);
656702171adSSebastian Haas 
657702171adSSebastian Haas 	err = usb_submit_urb(dev->intr_urb, GFP_KERNEL);
658702171adSSebastian Haas 	if (err) {
659aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "intr URB submit failed: %d\n", err);
660702171adSSebastian Haas 
661702171adSSebastian Haas 		return err;
662702171adSSebastian Haas 	}
663702171adSSebastian Haas 
664702171adSSebastian Haas 	/* CPC-USB will transfer received message to host */
665702171adSSebastian Haas 	err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON);
666702171adSSebastian Haas 	if (err)
667702171adSSebastian Haas 		goto failed;
668702171adSSebastian Haas 
669702171adSSebastian Haas 	/* CPC-USB will transfer CAN state changes to host */
670702171adSSebastian Haas 	err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON);
671702171adSSebastian Haas 	if (err)
672702171adSSebastian Haas 		goto failed;
673702171adSSebastian Haas 
674702171adSSebastian Haas 	/* CPC-USB will transfer bus errors to host */
675702171adSSebastian Haas 	err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON);
676702171adSSebastian Haas 	if (err)
677702171adSSebastian Haas 		goto failed;
678702171adSSebastian Haas 
679702171adSSebastian Haas 	err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL);
680702171adSSebastian Haas 	if (err)
681702171adSSebastian Haas 		goto failed;
682702171adSSebastian Haas 
683702171adSSebastian Haas 	dev->can.state = CAN_STATE_ERROR_ACTIVE;
684702171adSSebastian Haas 
685702171adSSebastian Haas 	return 0;
686702171adSSebastian Haas 
687702171adSSebastian Haas failed:
688aabdfd6aSWolfgang Grandegger 	netdev_warn(netdev, "couldn't submit control: %d\n", err);
689702171adSSebastian Haas 
690702171adSSebastian Haas 	return err;
691702171adSSebastian Haas }
692702171adSSebastian Haas 
unlink_all_urbs(struct ems_usb * dev)693702171adSSebastian Haas static void unlink_all_urbs(struct ems_usb *dev)
694702171adSSebastian Haas {
695702171adSSebastian Haas 	int i;
696702171adSSebastian Haas 
697702171adSSebastian Haas 	usb_unlink_urb(dev->intr_urb);
698702171adSSebastian Haas 
699702171adSSebastian Haas 	usb_kill_anchored_urbs(&dev->rx_submitted);
700702171adSSebastian Haas 
7019969e3c5SPavel Skripkin 	for (i = 0; i < MAX_RX_URBS; ++i)
7029969e3c5SPavel Skripkin 		usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
7039969e3c5SPavel Skripkin 				  dev->rxbuf[i], dev->rxbuf_dma[i]);
7049969e3c5SPavel Skripkin 
705702171adSSebastian Haas 	usb_kill_anchored_urbs(&dev->tx_submitted);
706702171adSSebastian Haas 	atomic_set(&dev->active_tx_urbs, 0);
707702171adSSebastian Haas 
708702171adSSebastian Haas 	for (i = 0; i < MAX_TX_URBS; i++)
709702171adSSebastian Haas 		dev->tx_contexts[i].echo_index = MAX_TX_URBS;
710702171adSSebastian Haas }
711702171adSSebastian Haas 
ems_usb_open(struct net_device * netdev)712702171adSSebastian Haas static int ems_usb_open(struct net_device *netdev)
713702171adSSebastian Haas {
714702171adSSebastian Haas 	struct ems_usb *dev = netdev_priv(netdev);
715702171adSSebastian Haas 	int err;
716702171adSSebastian Haas 
717702171adSSebastian Haas 	err = ems_usb_write_mode(dev, SJA1000_MOD_RM);
718702171adSSebastian Haas 	if (err)
719702171adSSebastian Haas 		return err;
720702171adSSebastian Haas 
721702171adSSebastian Haas 	/* common open */
722702171adSSebastian Haas 	err = open_candev(netdev);
723702171adSSebastian Haas 	if (err)
724702171adSSebastian Haas 		return err;
725702171adSSebastian Haas 
726702171adSSebastian Haas 	/* finally start device */
727702171adSSebastian Haas 	err = ems_usb_start(dev);
728702171adSSebastian Haas 	if (err) {
729702171adSSebastian Haas 		if (err == -ENODEV)
730702171adSSebastian Haas 			netif_device_detach(dev->netdev);
731702171adSSebastian Haas 
732aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "couldn't start device: %d\n", err);
733702171adSSebastian Haas 
734702171adSSebastian Haas 		close_candev(netdev);
735702171adSSebastian Haas 
736702171adSSebastian Haas 		return err;
737702171adSSebastian Haas 	}
738702171adSSebastian Haas 
739702171adSSebastian Haas 
740702171adSSebastian Haas 	netif_start_queue(netdev);
741702171adSSebastian Haas 
742702171adSSebastian Haas 	return 0;
743702171adSSebastian Haas }
744702171adSSebastian Haas 
ems_usb_start_xmit(struct sk_buff * skb,struct net_device * netdev)745702171adSSebastian Haas static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev)
746702171adSSebastian Haas {
747702171adSSebastian Haas 	struct ems_usb *dev = netdev_priv(netdev);
748702171adSSebastian Haas 	struct ems_tx_urb_context *context = NULL;
749702171adSSebastian Haas 	struct net_device_stats *stats = &netdev->stats;
750702171adSSebastian Haas 	struct can_frame *cf = (struct can_frame *)skb->data;
751702171adSSebastian Haas 	struct ems_cpc_msg *msg;
752702171adSSebastian Haas 	struct urb *urb;
753702171adSSebastian Haas 	u8 *buf;
754702171adSSebastian Haas 	int i, err;
755702171adSSebastian Haas 	size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
756702171adSSebastian Haas 			+ sizeof(struct cpc_can_msg);
757702171adSSebastian Haas 
758ae64438bSOliver Hartkopp 	if (can_dev_dropped_skb(netdev, skb))
7593ccd4c61SOliver Hartkopp 		return NETDEV_TX_OK;
7603ccd4c61SOliver Hartkopp 
761702171adSSebastian Haas 	/* create a URB, and a buffer for it, and copy the data to the URB */
762702171adSSebastian Haas 	urb = usb_alloc_urb(0, GFP_ATOMIC);
76387ced2f9SWolfram Sang 	if (!urb)
764702171adSSebastian Haas 		goto nomem;
765702171adSSebastian Haas 
766997ea58eSDaniel Mack 	buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
767702171adSSebastian Haas 	if (!buf) {
768aabdfd6aSWolfgang Grandegger 		netdev_err(netdev, "No memory left for USB buffer\n");
769702171adSSebastian Haas 		usb_free_urb(urb);
770702171adSSebastian Haas 		goto nomem;
771702171adSSebastian Haas 	}
772702171adSSebastian Haas 
773702171adSSebastian Haas 	msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
774702171adSSebastian Haas 
7758a4b5b0fSGerhard Uttenthaler 	msg->msg.can_msg.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
776c7b74967SOliver Hartkopp 	msg->msg.can_msg.length = cf->len;
777702171adSSebastian Haas 
778702171adSSebastian Haas 	if (cf->can_id & CAN_RTR_FLAG) {
779702171adSSebastian Haas 		msg->type = cf->can_id & CAN_EFF_FLAG ?
780702171adSSebastian Haas 			CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME;
781702171adSSebastian Haas 
782702171adSSebastian Haas 		msg->length = CPC_CAN_MSG_MIN_SIZE;
783702171adSSebastian Haas 	} else {
784702171adSSebastian Haas 		msg->type = cf->can_id & CAN_EFF_FLAG ?
785702171adSSebastian Haas 			CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME;
786702171adSSebastian Haas 
787c7b74967SOliver Hartkopp 		for (i = 0; i < cf->len; i++)
788702171adSSebastian Haas 			msg->msg.can_msg.msg[i] = cf->data[i];
789702171adSSebastian Haas 
790c7b74967SOliver Hartkopp 		msg->length = CPC_CAN_MSG_MIN_SIZE + cf->len;
791702171adSSebastian Haas 	}
792702171adSSebastian Haas 
793702171adSSebastian Haas 	for (i = 0; i < MAX_TX_URBS; i++) {
794702171adSSebastian Haas 		if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
795702171adSSebastian Haas 			context = &dev->tx_contexts[i];
796702171adSSebastian Haas 			break;
797702171adSSebastian Haas 		}
798702171adSSebastian Haas 	}
799702171adSSebastian Haas 
800702171adSSebastian Haas 	/*
801702171adSSebastian Haas 	 * May never happen! When this happens we'd more URBs in flight as
802702171adSSebastian Haas 	 * allowed (MAX_TX_URBS).
803702171adSSebastian Haas 	 */
804702171adSSebastian Haas 	if (!context) {
805997ea58eSDaniel Mack 		usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
806a1c31f1dSAlexey Khoroshilov 		usb_free_urb(urb);
807702171adSSebastian Haas 
808aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "couldn't find free context\n");
809702171adSSebastian Haas 
810702171adSSebastian Haas 		return NETDEV_TX_BUSY;
811702171adSSebastian Haas 	}
812702171adSSebastian Haas 
813702171adSSebastian Haas 	context->dev = dev;
814702171adSSebastian Haas 	context->echo_index = i;
815702171adSSebastian Haas 
816702171adSSebastian Haas 	usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
817702171adSSebastian Haas 			  size, ems_usb_write_bulk_callback, context);
818702171adSSebastian Haas 	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
819702171adSSebastian Haas 	usb_anchor_urb(urb, &dev->tx_submitted);
820702171adSSebastian Haas 
8211dcb6e57SVincent Mailhol 	can_put_echo_skb(skb, netdev, context->echo_index, 0);
822702171adSSebastian Haas 
823702171adSSebastian Haas 	atomic_inc(&dev->active_tx_urbs);
824702171adSSebastian Haas 
825702171adSSebastian Haas 	err = usb_submit_urb(urb, GFP_ATOMIC);
826702171adSSebastian Haas 	if (unlikely(err)) {
827f318482aSMarc Kleine-Budde 		can_free_echo_skb(netdev, context->echo_index, NULL);
828702171adSSebastian Haas 
829702171adSSebastian Haas 		usb_unanchor_urb(urb);
830997ea58eSDaniel Mack 		usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
831702171adSSebastian Haas 
832702171adSSebastian Haas 		atomic_dec(&dev->active_tx_urbs);
833702171adSSebastian Haas 
834702171adSSebastian Haas 		if (err == -ENODEV) {
835702171adSSebastian Haas 			netif_device_detach(netdev);
836702171adSSebastian Haas 		} else {
837aabdfd6aSWolfgang Grandegger 			netdev_warn(netdev, "failed tx_urb %d\n", err);
838702171adSSebastian Haas 
839702171adSSebastian Haas 			stats->tx_dropped++;
840702171adSSebastian Haas 		}
841702171adSSebastian Haas 	} else {
842860e9538SFlorian Westphal 		netif_trans_update(netdev);
843702171adSSebastian Haas 
844702171adSSebastian Haas 		/* Slow down tx path */
845702171adSSebastian Haas 		if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
84690cfde46SGerhard Uttenthaler 		    dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
847702171adSSebastian Haas 			netif_stop_queue(netdev);
848702171adSSebastian Haas 		}
849702171adSSebastian Haas 	}
850702171adSSebastian Haas 
851702171adSSebastian Haas 	/*
852702171adSSebastian Haas 	 * Release our reference to this URB, the USB core will eventually free
853702171adSSebastian Haas 	 * it entirely.
854702171adSSebastian Haas 	 */
855702171adSSebastian Haas 	usb_free_urb(urb);
856702171adSSebastian Haas 
857702171adSSebastian Haas 	return NETDEV_TX_OK;
858702171adSSebastian Haas 
859702171adSSebastian Haas nomem:
860702171adSSebastian Haas 	dev_kfree_skb(skb);
861702171adSSebastian Haas 	stats->tx_dropped++;
862702171adSSebastian Haas 
863702171adSSebastian Haas 	return NETDEV_TX_OK;
864702171adSSebastian Haas }
865702171adSSebastian Haas 
ems_usb_close(struct net_device * netdev)866702171adSSebastian Haas static int ems_usb_close(struct net_device *netdev)
867702171adSSebastian Haas {
868702171adSSebastian Haas 	struct ems_usb *dev = netdev_priv(netdev);
869702171adSSebastian Haas 
870702171adSSebastian Haas 	/* Stop polling */
871702171adSSebastian Haas 	unlink_all_urbs(dev);
872702171adSSebastian Haas 
873702171adSSebastian Haas 	netif_stop_queue(netdev);
874702171adSSebastian Haas 
875702171adSSebastian Haas 	/* Set CAN controller to reset mode */
876702171adSSebastian Haas 	if (ems_usb_write_mode(dev, SJA1000_MOD_RM))
877aabdfd6aSWolfgang Grandegger 		netdev_warn(netdev, "couldn't stop device");
878702171adSSebastian Haas 
879702171adSSebastian Haas 	close_candev(netdev);
880702171adSSebastian Haas 
881702171adSSebastian Haas 	return 0;
882702171adSSebastian Haas }
883702171adSSebastian Haas 
884702171adSSebastian Haas static const struct net_device_ops ems_usb_netdev_ops = {
885702171adSSebastian Haas 	.ndo_open = ems_usb_open,
886702171adSSebastian Haas 	.ndo_stop = ems_usb_close,
887702171adSSebastian Haas 	.ndo_start_xmit = ems_usb_start_xmit,
888c971fa2aSOliver Hartkopp 	.ndo_change_mtu = can_change_mtu,
889702171adSSebastian Haas };
890702171adSSebastian Haas 
891409c188cSVincent Mailhol static const struct ethtool_ops ems_usb_ethtool_ops = {
892409c188cSVincent Mailhol 	.get_ts_info = ethtool_op_get_ts_info,
893409c188cSVincent Mailhol };
894409c188cSVincent Mailhol 
895194b9a4cSMarc Kleine-Budde static const struct can_bittiming_const ems_usb_bittiming_const = {
896f60df831SVincent Mailhol 	.name = KBUILD_MODNAME,
897702171adSSebastian Haas 	.tseg1_min = 1,
898702171adSSebastian Haas 	.tseg1_max = 16,
899702171adSSebastian Haas 	.tseg2_min = 1,
900702171adSSebastian Haas 	.tseg2_max = 8,
901702171adSSebastian Haas 	.sjw_max = 4,
902702171adSSebastian Haas 	.brp_min = 1,
903702171adSSebastian Haas 	.brp_max = 64,
904702171adSSebastian Haas 	.brp_inc = 1,
905702171adSSebastian Haas };
906702171adSSebastian Haas 
ems_usb_set_mode(struct net_device * netdev,enum can_mode mode)907702171adSSebastian Haas static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode)
908702171adSSebastian Haas {
909702171adSSebastian Haas 	struct ems_usb *dev = netdev_priv(netdev);
910702171adSSebastian Haas 
911702171adSSebastian Haas 	switch (mode) {
912702171adSSebastian Haas 	case CAN_MODE_START:
913702171adSSebastian Haas 		if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL))
914aabdfd6aSWolfgang Grandegger 			netdev_warn(netdev, "couldn't start device");
915702171adSSebastian Haas 
916702171adSSebastian Haas 		if (netif_queue_stopped(netdev))
917702171adSSebastian Haas 			netif_wake_queue(netdev);
918702171adSSebastian Haas 		break;
919702171adSSebastian Haas 
920702171adSSebastian Haas 	default:
921702171adSSebastian Haas 		return -EOPNOTSUPP;
922702171adSSebastian Haas 	}
923702171adSSebastian Haas 
924702171adSSebastian Haas 	return 0;
925702171adSSebastian Haas }
926702171adSSebastian Haas 
ems_usb_set_bittiming(struct net_device * netdev)927702171adSSebastian Haas static int ems_usb_set_bittiming(struct net_device *netdev)
928702171adSSebastian Haas {
929702171adSSebastian Haas 	struct ems_usb *dev = netdev_priv(netdev);
930702171adSSebastian Haas 	struct can_bittiming *bt = &dev->can.bittiming;
931702171adSSebastian Haas 	u8 btr0, btr1;
932702171adSSebastian Haas 
933702171adSSebastian Haas 	btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
934702171adSSebastian Haas 	btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
935702171adSSebastian Haas 		(((bt->phase_seg2 - 1) & 0x7) << 4);
936702171adSSebastian Haas 	if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
937702171adSSebastian Haas 		btr1 |= 0x80;
938702171adSSebastian Haas 
939aabdfd6aSWolfgang Grandegger 	netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
940702171adSSebastian Haas 
941702171adSSebastian Haas 	dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0;
942702171adSSebastian Haas 	dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1;
943702171adSSebastian Haas 
944702171adSSebastian Haas 	return ems_usb_command_msg(dev, &dev->active_params);
945702171adSSebastian Haas }
946702171adSSebastian Haas 
init_params_sja1000(struct ems_cpc_msg * msg)947702171adSSebastian Haas static void init_params_sja1000(struct ems_cpc_msg *msg)
948702171adSSebastian Haas {
949702171adSSebastian Haas 	struct cpc_sja1000_params *sja1000 =
950702171adSSebastian Haas 		&msg->msg.can_params.cc_params.sja1000;
951702171adSSebastian Haas 
952702171adSSebastian Haas 	msg->type = CPC_CMD_TYPE_CAN_PARAMS;
953702171adSSebastian Haas 	msg->length = sizeof(struct cpc_can_params);
954702171adSSebastian Haas 	msg->msgid = 0;
955702171adSSebastian Haas 
956702171adSSebastian Haas 	msg->msg.can_params.cc_type = CPC_CC_TYPE_SJA1000;
957702171adSSebastian Haas 
958702171adSSebastian Haas 	/* Acceptance filter open */
959702171adSSebastian Haas 	sja1000->acc_code0 = 0x00;
960702171adSSebastian Haas 	sja1000->acc_code1 = 0x00;
961702171adSSebastian Haas 	sja1000->acc_code2 = 0x00;
962702171adSSebastian Haas 	sja1000->acc_code3 = 0x00;
963702171adSSebastian Haas 
964702171adSSebastian Haas 	/* Acceptance filter open */
965702171adSSebastian Haas 	sja1000->acc_mask0 = 0xFF;
966702171adSSebastian Haas 	sja1000->acc_mask1 = 0xFF;
967702171adSSebastian Haas 	sja1000->acc_mask2 = 0xFF;
968702171adSSebastian Haas 	sja1000->acc_mask3 = 0xFF;
969702171adSSebastian Haas 
970702171adSSebastian Haas 	sja1000->btr0 = 0;
971702171adSSebastian Haas 	sja1000->btr1 = 0;
972702171adSSebastian Haas 
973702171adSSebastian Haas 	sja1000->outp_contr = SJA1000_DEFAULT_OUTPUT_CONTROL;
974702171adSSebastian Haas 	sja1000->mode = SJA1000_MOD_RM;
975702171adSSebastian Haas }
976702171adSSebastian Haas 
977702171adSSebastian Haas /*
978702171adSSebastian Haas  * probe function for new CPC-USB devices
979702171adSSebastian Haas  */
ems_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)980702171adSSebastian Haas static int ems_usb_probe(struct usb_interface *intf,
981702171adSSebastian Haas 			 const struct usb_device_id *id)
982702171adSSebastian Haas {
983702171adSSebastian Haas 	struct net_device *netdev;
984702171adSSebastian Haas 	struct ems_usb *dev;
985702171adSSebastian Haas 	int i, err = -ENOMEM;
986702171adSSebastian Haas 
987a6e4bc53SWolfgang Grandegger 	netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
988702171adSSebastian Haas 	if (!netdev) {
9891c0b28b1SHans J. Koch 		dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
990702171adSSebastian Haas 		return -ENOMEM;
991702171adSSebastian Haas 	}
992702171adSSebastian Haas 
993702171adSSebastian Haas 	dev = netdev_priv(netdev);
994702171adSSebastian Haas 
995702171adSSebastian Haas 	dev->udev = interface_to_usbdev(intf);
996702171adSSebastian Haas 	dev->netdev = netdev;
997702171adSSebastian Haas 
998702171adSSebastian Haas 	dev->can.state = CAN_STATE_STOPPED;
999702171adSSebastian Haas 	dev->can.clock.freq = EMS_USB_ARM7_CLOCK;
1000702171adSSebastian Haas 	dev->can.bittiming_const = &ems_usb_bittiming_const;
1001702171adSSebastian Haas 	dev->can.do_set_bittiming = ems_usb_set_bittiming;
1002702171adSSebastian Haas 	dev->can.do_set_mode = ems_usb_set_mode;
1003ad72c347SChristian Pellegrin 	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
1004702171adSSebastian Haas 
1005702171adSSebastian Haas 	netdev->netdev_ops = &ems_usb_netdev_ops;
1006409c188cSVincent Mailhol 	netdev->ethtool_ops = &ems_usb_ethtool_ops;
1007702171adSSebastian Haas 
1008702171adSSebastian Haas 	netdev->flags |= IFF_ECHO; /* we support local echo */
1009702171adSSebastian Haas 
1010702171adSSebastian Haas 	init_usb_anchor(&dev->rx_submitted);
1011702171adSSebastian Haas 
1012702171adSSebastian Haas 	init_usb_anchor(&dev->tx_submitted);
1013702171adSSebastian Haas 	atomic_set(&dev->active_tx_urbs, 0);
1014702171adSSebastian Haas 
1015702171adSSebastian Haas 	for (i = 0; i < MAX_TX_URBS; i++)
1016702171adSSebastian Haas 		dev->tx_contexts[i].echo_index = MAX_TX_URBS;
1017702171adSSebastian Haas 
1018702171adSSebastian Haas 	dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
101987ced2f9SWolfram Sang 	if (!dev->intr_urb)
1020702171adSSebastian Haas 		goto cleanup_candev;
1021702171adSSebastian Haas 
1022702171adSSebastian Haas 	dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
102309da6c5fSJoe Perches 	if (!dev->intr_in_buffer)
1024702171adSSebastian Haas 		goto cleanup_intr_urb;
1025702171adSSebastian Haas 
1026702171adSSebastian Haas 	dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
1027702171adSSebastian Haas 				     sizeof(struct ems_cpc_msg), GFP_KERNEL);
102814f8dc49SJoe Perches 	if (!dev->tx_msg_buffer)
1029702171adSSebastian Haas 		goto cleanup_intr_in_buffer;
1030702171adSSebastian Haas 
1031702171adSSebastian Haas 	usb_set_intfdata(intf, dev);
1032702171adSSebastian Haas 
1033702171adSSebastian Haas 	SET_NETDEV_DEV(netdev, &intf->dev);
1034702171adSSebastian Haas 
1035702171adSSebastian Haas 	init_params_sja1000(&dev->active_params);
1036702171adSSebastian Haas 
1037702171adSSebastian Haas 	err = ems_usb_command_msg(dev, &dev->active_params);
1038702171adSSebastian Haas 	if (err) {
1039aabdfd6aSWolfgang Grandegger 		netdev_err(netdev, "couldn't initialize controller: %d\n", err);
1040702171adSSebastian Haas 		goto cleanup_tx_msg_buffer;
1041702171adSSebastian Haas 	}
1042702171adSSebastian Haas 
1043702171adSSebastian Haas 	err = register_candev(netdev);
1044702171adSSebastian Haas 	if (err) {
1045aabdfd6aSWolfgang Grandegger 		netdev_err(netdev, "couldn't register CAN device: %d\n", err);
1046702171adSSebastian Haas 		goto cleanup_tx_msg_buffer;
1047702171adSSebastian Haas 	}
1048702171adSSebastian Haas 
1049702171adSSebastian Haas 	return 0;
1050702171adSSebastian Haas 
1051702171adSSebastian Haas cleanup_tx_msg_buffer:
1052702171adSSebastian Haas 	kfree(dev->tx_msg_buffer);
1053702171adSSebastian Haas 
1054702171adSSebastian Haas cleanup_intr_in_buffer:
1055702171adSSebastian Haas 	kfree(dev->intr_in_buffer);
1056702171adSSebastian Haas 
1057702171adSSebastian Haas cleanup_intr_urb:
1058702171adSSebastian Haas 	usb_free_urb(dev->intr_urb);
1059702171adSSebastian Haas 
1060702171adSSebastian Haas cleanup_candev:
1061702171adSSebastian Haas 	free_candev(netdev);
1062702171adSSebastian Haas 
1063702171adSSebastian Haas 	return err;
1064702171adSSebastian Haas }
1065702171adSSebastian Haas 
1066702171adSSebastian Haas /*
1067702171adSSebastian Haas  * called by the usb core when the device is removed from the system
1068702171adSSebastian Haas  */
ems_usb_disconnect(struct usb_interface * intf)1069702171adSSebastian Haas static void ems_usb_disconnect(struct usb_interface *intf)
1070702171adSSebastian Haas {
1071702171adSSebastian Haas 	struct ems_usb *dev = usb_get_intfdata(intf);
1072702171adSSebastian Haas 
1073702171adSSebastian Haas 	usb_set_intfdata(intf, NULL);
1074702171adSSebastian Haas 
1075702171adSSebastian Haas 	if (dev) {
1076702171adSSebastian Haas 		unregister_netdev(dev->netdev);
1077702171adSSebastian Haas 
1078702171adSSebastian Haas 		unlink_all_urbs(dev);
1079702171adSSebastian Haas 
1080702171adSSebastian Haas 		usb_free_urb(dev->intr_urb);
1081702171adSSebastian Haas 
1082702171adSSebastian Haas 		kfree(dev->intr_in_buffer);
108372c05f32SAnton Vasilyev 		kfree(dev->tx_msg_buffer);
1084ab4a0b8fSPavel Skripkin 
1085ab4a0b8fSPavel Skripkin 		free_candev(dev->netdev);
1086702171adSSebastian Haas 	}
1087702171adSSebastian Haas }
1088702171adSSebastian Haas 
1089702171adSSebastian Haas /* usb specific object needed to register this driver with the usb subsystem */
1090702171adSSebastian Haas static struct usb_driver ems_usb_driver = {
1091f60df831SVincent Mailhol 	.name = KBUILD_MODNAME,
1092702171adSSebastian Haas 	.probe = ems_usb_probe,
1093702171adSSebastian Haas 	.disconnect = ems_usb_disconnect,
1094702171adSSebastian Haas 	.id_table = ems_usb_table,
1095702171adSSebastian Haas };
1096702171adSSebastian Haas 
1097d632eb1bSGreg Kroah-Hartman module_usb_driver(ems_usb_driver);
1098