1702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 2702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CAN driver for EMS Dr. Thomas Wuensche CPC-USB/ARM7 3702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 4702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche 5702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 6702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * This program is free software; you can redistribute it and/or modify it 7702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * under the terms of the GNU General Public License as published 8702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * by the Free Software Foundation; version 2 of the License. 9702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 10702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * This program is distributed in the hope that it will be useful, but 11702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * WITHOUT ANY WARRANTY; without even the implied warranty of 12702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * General Public License for more details. 14702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 15702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * You should have received a copy of the GNU General Public License along 16702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * with this program; if not, write to the Free Software Foundation, Inc., 17702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 19702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/init.h> 20702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/signal.h> 21702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/slab.h> 22702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/module.h> 23702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/netdevice.h> 24702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/usb.h> 25702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 26702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can.h> 27702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can/dev.h> 28702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can/error.h> 29702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 30702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_AUTHOR("Sebastian Haas <haas@ems-wuensche.com>"); 31702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_DESCRIPTION("CAN driver for EMS Dr. Thomas Wuensche CAN/USB interfaces"); 32702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_LICENSE("GPL v2"); 33702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 34702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Control-Values for CPC_Control() Command Subject Selection */ 35702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CAN_MESSAGE 0x04 36702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CAN_STATE 0x0C 37702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_BUS_ERROR 0x1C 38702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 39702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Control Command Actions */ 40702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CONT_OFF 0 41702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CONT_ON 1 42702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_ONCE 2 43702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 44702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Messages from CPC to PC */ 45702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_FRAME 1 /* CAN data frame */ 46702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_RTR_FRAME 8 /* CAN remote frame */ 47702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_PARAMS 12 /* Actual CAN parameters */ 48702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_STATE 14 /* CAN state message */ 49702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_EXT_CAN_FRAME 16 /* Extended CAN data frame */ 50702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_EXT_RTR_FRAME 17 /* Extended remote frame */ 51702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CONTROL 19 /* change interface behavior */ 52702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CONFIRM 20 /* command processed confirmation */ 53702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_OVERRUN 21 /* overrun events */ 54702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_FRAME_ERROR 23 /* detected bus errors */ 55702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_ERR_COUNTER 25 /* RX/TX error counter */ 56702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 57702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Messages from the PC to the CPC interface */ 58702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_FRAME 1 /* CAN data frame */ 59702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CONTROL 3 /* control of interface behavior */ 60702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_PARAMS 6 /* set CAN parameters */ 61702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_RTR_FRAME 13 /* CAN remote frame */ 62702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_STATE 14 /* CAN state message */ 63702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_EXT_CAN_FRAME 15 /* Extended CAN data frame */ 64702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_EXT_RTR_FRAME 16 /* Extended CAN remote frame */ 65702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_EXIT 200 /* exit the CAN */ 66702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 67702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_INQ_ERR_COUNTER 25 /* request the CAN error counters */ 68702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CLEAR_MSG_QUEUE 8 /* clear CPC_MSG queue */ 69702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CLEAR_CMD_QUEUE 28 /* clear CPC_CMD queue */ 70702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 71702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CC_TYPE_SJA1000 2 /* Philips basic CAN controller */ 72702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 73702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CAN_ECODE_ERRFRAME 0x01 /* Ecode type */ 74702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 75702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Overrun types */ 76702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_CAN 0x01 77702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_CANSTATE 0x02 78702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_BUSERROR 0x04 79702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 80702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 81702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * If the CAN controller lost a message we indicate it with the highest bit 82702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * set in the count field. 83702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 84702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_HW 0x80 85702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 86702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Size of the "struct ems_cpc_msg" without the union */ 87702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_HEADER_LEN 11 88702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CAN_MSG_MIN_SIZE 5 89702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 90702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Define these values to match your devices */ 91702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define USB_CPCUSB_VENDOR_ID 0x12D6 92702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 93702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define USB_CPCUSB_ARM7_PRODUCT_ID 0x0444 94702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 95702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Mode register NXP LPC2119/SJA1000 CAN Controller */ 96702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_MOD_NORMAL 0x00 97702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_MOD_RM 0x01 98702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 99702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* ECC register NXP LPC2119/SJA1000 CAN Controller */ 100702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_SEG 0x1F 101702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_DIR 0x20 102702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_ERR 0x06 103702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_BIT 0x00 104702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_FORM 0x40 105702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_STUFF 0x80 106702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_MASK 0xc0 107702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 108702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Status register content */ 109702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_SR_BS 0x80 110702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_SR_ES 0x40 111702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 112702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_DEFAULT_OUTPUT_CONTROL 0xDA 113702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 114702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 115702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * The device actually uses a 16MHz clock to generate the CAN clock 116702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * but it expects SJA1000 bit settings based on 8MHz (is internally 117702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * converted). 118702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 119702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define EMS_USB_ARM7_CLOCK 8000000 120702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 121702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 122702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CAN-Message representation in a CPC_MSG. Message object type is 123702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or 124702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME. 125702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 126702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_msg { 127702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 id; 128702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 length; 129702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msg[8]; 130702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 131702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 132702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Representation of the CAN parameters for the SJA1000 controller */ 133702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_sja1000_params { 134702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 mode; 135702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code0; 136702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code1; 137702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code2; 138702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code3; 139702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask0; 140702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask1; 141702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask2; 142702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask3; 143702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr0; 144702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr1; 145702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 outp_contr; 146702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 147702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 148702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* CAN params message representation */ 149702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_params { 150702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 cc_type; 151702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 152702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Will support M16C CAN controller in the future */ 153702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 154702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_params sja1000; 155702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } cc_params; 156702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 157702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 158702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Structure for confirmed message handling */ 159702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_confirm { 160702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 error; /* error code */ 161702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 162702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 163702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Structure for overrun conditions */ 164702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_overrun { 165702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 event; 166702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 count; 167702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 168702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 169702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* SJA1000 CAN errors (compatible to NXP LPC2119) */ 170702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_sja1000_can_error { 171702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecc; 172702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rxerr; 173702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 txerr; 174702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 175702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 176702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* structure for CAN error conditions */ 177702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_error { 178702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecode; 179702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 180702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct { 181702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 cc_type; 182702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 183702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Other controllers may also provide error code capture regs */ 184702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 185702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_can_error sja1000; 186702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } regs; 187702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } cc; 188702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 189702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 190702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 191702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Structure containing RX/TX error counter. This structure is used to request 192702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * the values of the CAN controllers TX and RX error counter. 193702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 194702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_err_counter { 195702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rx; 196702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 tx; 197702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 198702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 199702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Main message type used between library and application */ 200ba2d3587912f82d1ab4367975b1df460db60fb1eEric Dumazetstruct __packed ems_cpc_msg { 201702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 type; /* type of message */ 202702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 length; /* length of data within union 'msg' */ 203702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msgid; /* confirmation handle */ 204702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 ts_sec; /* timestamp in seconds */ 205702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 ts_nsec; /* timestamp in nano seconds */ 206702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 207702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 208702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 generic[64]; 209702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_msg can_msg; 210702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_params can_params; 211702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_confirm confirmation; 212702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_overrun overrun; 213702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_error error; 214702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_err_counter err_counter; 215702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 can_state; 216702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } msg; 217702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 218702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 219702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 220702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Table of devices that work with this driver 221702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * NOTE: This driver supports only CPC-USB/ARM7 (LPC2119) yet. 222702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 223702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct usb_device_id ems_usb_table[] = { 224702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas {USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_ARM7_PRODUCT_ID)}, 225702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas {} /* Terminating entry */ 226702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 227702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 228702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_DEVICE_TABLE(usb, ems_usb_table); 229702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 230702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define RX_BUFFER_SIZE 64 231702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_HEADER_SIZE 4 232702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define INTR_IN_BUFFER_SIZE 4 233702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 234702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define MAX_RX_URBS 10 235a6e4bc5304033e434fabccabb230b8e9ff55d76fWolfgang Grandegger#define MAX_TX_URBS 10 236702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 237702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_usb; 238702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 239702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_tx_urb_context { 240702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 241702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 242702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 echo_index; 243702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 dlc; 244702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 245702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 246702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_usb { 247702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_priv can; /* must be the first member */ 248702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int open_time; 249702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 250702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *echo_skb[MAX_TX_URBS]; 251702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 252702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_device *udev; 253702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 254702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 255702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_t active_tx_urbs; 256702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_anchor tx_submitted; 257702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context tx_contexts[MAX_TX_URBS]; 258702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 259702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_anchor rx_submitted; 260702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 261702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *intr_urb; 262702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 263702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *tx_msg_buffer; 264702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 265702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *intr_in_buffer; 266702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unsigned int free_slots; /* remember number of available slots */ 267702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 268702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg active_params; /* active controller parameters */ 269702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 270702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 271702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_read_interrupt_callback(struct urb *urb) 272702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 273702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = urb->context; 274702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev = dev->netdev; 275702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err; 276702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 277702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 278702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 279702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 280702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (urb->status) { 281702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case 0: 282702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots = dev->intr_in_buffer[1]; 283702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 284702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 285702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ECONNRESET: /* unlink */ 286702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ENOENT: 287702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ESHUTDOWN: 288702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 289702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 290702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 291702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n", 292702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 293702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 294702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 295702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 296702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_ATOMIC); 297702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 298702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 299702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 300702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas else if (err) 301702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 302702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "failed resubmitting intr urb: %d\n", err); 303702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 304702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 305702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) 306702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 307702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf; 308702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *skb; 309702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i; 310702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &dev->netdev->stats; 311702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3127b6856a0296a8f187bb88ba31fa83a08abba7966Wolfgang Grandegger skb = alloc_can_skb(dev->netdev, &cf); 313702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (skb == NULL) 314702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 315702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3162b2072e902848a63168570f500a5726744b3873aSebastian Haas cf->can_id = le32_to_cpu(msg->msg.can_msg.id); 317c7cd606f60e7679c7f9eee7010f02a6f000209c1Oliver Hartkopp cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF); 318702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3198e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME || 3208e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) 321702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_EFF_FLAG; 322702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3238e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (msg->type == CPC_MSG_TYPE_RTR_FRAME || 3248e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) { 325702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_RTR_FLAG; 326702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 327702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < cf->can_dlc; i++) 328702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[i] = msg->msg.can_msg.msg[i]; 329702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 330702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 331702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_rx(skb); 332702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 333702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_packets++; 334702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_bytes += cf->can_dlc; 335702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 336702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 337702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) 338702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 339702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf; 340702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *skb; 341702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &dev->netdev->stats; 342702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3437b6856a0296a8f187bb88ba31fa83a08abba7966Wolfgang Grandegger skb = alloc_can_err_skb(dev->netdev, &cf); 344702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (skb == NULL) 345702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 346702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 347702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (msg->type == CPC_MSG_TYPE_CAN_STATE) { 348702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 state = msg->msg.can_state; 349702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 350702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (state & SJA1000_SR_BS) { 351702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_BUS_OFF; 352702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_BUSOFF; 353702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 354702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_bus_off(dev->netdev); 355702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (state & SJA1000_SR_ES) { 356702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_WARNING; 357702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.error_warning++; 358702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 359702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_ACTIVE; 360702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.error_passive++; 361702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 362702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (msg->type == CPC_MSG_TYPE_CAN_FRAME_ERROR) { 363702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecc = msg->msg.error.cc.regs.sja1000.ecc; 364702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 txerr = msg->msg.error.cc.regs.sja1000.txerr; 365702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rxerr = msg->msg.error.cc.regs.sja1000.rxerr; 366702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 367702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* bus error interrupt */ 368702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.bus_error++; 369702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_errors++; 370702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 371702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; 372702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 373702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (ecc & SJA1000_ECC_MASK) { 374702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_BIT: 375702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_BIT; 376702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 377702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_FORM: 378702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_FORM; 379702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 380702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_STUFF: 381702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_STUFF; 382702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 383702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 384702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_UNSPEC; 385702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[3] = ecc & SJA1000_ECC_SEG; 386702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 387702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 388702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 38925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* Error occurred during transmission? */ 390702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if ((ecc & SJA1000_ECC_DIR) == 0) 391702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_TX; 392702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 393702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->can.state == CAN_STATE_ERROR_WARNING || 394702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state == CAN_STATE_ERROR_PASSIVE) { 395702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[1] = (txerr > rxerr) ? 396702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; 397702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 398702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (msg->type == CPC_MSG_TYPE_OVERRUN) { 399702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_CRTL; 400702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 401702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 402702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_over_errors++; 403702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_errors++; 404702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 405702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 406702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_rx(skb); 407702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 408702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_packets++; 409702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_bytes += cf->can_dlc; 410702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 411702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 412702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 413702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * callback for bulk IN urb 414702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 415702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_read_bulk_callback(struct urb *urb) 416702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 417702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = urb->context; 418702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 419702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int retval; 420702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 421702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev = dev->netdev; 422702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 423702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 424702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 425702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 426702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (urb->status) { 427702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case 0: /* success */ 428702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 429702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 430702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ENOENT: 431702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 432702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 433702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 434702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n", 435702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 436702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto resubmit_urb; 437702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 438702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 439702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (urb->actual_length > CPC_HEADER_SIZE) { 440702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg *msg; 441702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *ibuf = urb->transfer_buffer; 442702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msg_count, again, start; 443702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 444702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg_count = ibuf[0] & ~0x80; 445702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas again = ibuf[0] & 0x80; 446702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 447702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas start = CPC_HEADER_SIZE; 448702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 449702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas while (msg_count) { 450702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg = (struct ems_cpc_msg *)&ibuf[start]; 451702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 452702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (msg->type) { 453702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_STATE: 454702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Process CAN state changes */ 455702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 456702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 457702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 458702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_FRAME: 459702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_EXT_CAN_FRAME: 460702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_RTR_FRAME: 461702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_EXT_RTR_FRAME: 462702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_can_msg(dev, msg); 463702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 464702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 465702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_FRAME_ERROR: 466702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Process errorframe */ 467702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 468702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 469702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 470702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_OVERRUN: 471702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Message lost while receiving */ 472702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 473702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 474702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 475702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 476702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas start += CPC_MSG_HEADER_LEN + msg->length; 477702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg_count--; 478702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 479702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (start > urb->transfer_buffer_length) { 480702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "format error\n"); 481702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 482702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 483702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 484702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 485702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 486702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasresubmit_urb: 487702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), 488702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_buffer, RX_BUFFER_SIZE, 489702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_bulk_callback, dev); 490702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 491702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas retval = usb_submit_urb(urb, GFP_ATOMIC); 492702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 493702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (retval == -ENODEV) 494702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 495702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas else if (retval) 496702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 497702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "failed resubmitting read bulk urb: %d\n", retval); 498702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 499702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 500702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 501702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * callback for bulk IN urb 502702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 503702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_write_bulk_callback(struct urb *urb) 504702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 505702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context *context = urb->context; 506702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 507702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 508702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 509702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas BUG_ON(!context); 510702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 511702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev = context->dev; 512702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev = dev->netdev; 513702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 514702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* free up our allocated buffer */ 515997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(urb->dev, urb->transfer_buffer_length, 516997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack urb->transfer_buffer, urb->transfer_dma); 517702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 518702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_dec(&dev->active_tx_urbs); 519702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 520702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 521702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 522702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 523702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (urb->status) 524702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", 525702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 526702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 527702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->trans_start = jiffies; 528702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 529702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* transmission complete interrupt */ 530702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->stats.tx_packets++; 531702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->stats.tx_bytes += context->dlc; 532702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 533702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_get_echo_skb(netdev, context->echo_index); 534702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 535702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Release context */ 536702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->echo_index = MAX_TX_URBS; 537702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 538702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (netif_queue_stopped(netdev)) 539702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_wake_queue(netdev); 540702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 541702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 542702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 543702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Send the given CPC command synchronously 544702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 545702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_command_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) 546702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 547702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int actual_length; 548702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 549702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Copy payload */ 550702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas memcpy(&dev->tx_msg_buffer[CPC_HEADER_SIZE], msg, 551702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length + CPC_MSG_HEADER_LEN); 552702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 553702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Clear header */ 554702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas memset(&dev->tx_msg_buffer[0], 0, CPC_HEADER_SIZE); 555702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 556702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 557702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &dev->tx_msg_buffer[0], 558702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length + CPC_MSG_HEADER_LEN + CPC_HEADER_SIZE, 559702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &actual_length, 1000); 560702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 561702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 562702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 563702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Change CAN controllers' mode register 564702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 565702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_write_mode(struct ems_usb *dev, u8 mode) 566702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 567702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.mode = mode; 568702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 569702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &dev->active_params); 570702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 571702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 572702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 573702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Send a CPC_Control command to change behaviour when interface receives a CAN 574702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * message, bus error or CAN state changed notifications. 575702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 576702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_control_cmd(struct ems_usb *dev, u8 val) 577702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 578702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg cmd; 579702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 580702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.type = CPC_CMD_TYPE_CONTROL; 581702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.length = CPC_MSG_HEADER_LEN + 1; 582702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 583702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.msgid = 0; 584702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 585702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.msg.generic[0] = val; 586702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 587702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &cmd); 588702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 589702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 590702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 591702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Start interface 592702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 593702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_start(struct ems_usb *dev) 594702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 595702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev = dev->netdev; 596702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err, i; 597702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 598702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer[0] = 0; 599702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots = 15; /* initial size */ 600702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 601702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_RX_URBS; i++) { 602702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *urb = NULL; 603702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *buf = NULL; 604702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 605702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* create a URB, and a buffer for it */ 606702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb = usb_alloc_urb(0, GFP_KERNEL); 607702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!urb) { 608702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 609702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "No memory left for URBs\n"); 610702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 611702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 612702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 613997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, 614997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack &urb->transfer_dma); 615702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!buf) { 616702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 617702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "No memory left for USB buffer\n"); 618702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 619702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 620702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 621702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 622702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), 623702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas buf, RX_BUFFER_SIZE, 624702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_bulk_callback, dev); 625702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 626702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_anchor_urb(urb, &dev->rx_submitted); 627702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 628702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_KERNEL); 629702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 630702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 631997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, 632997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack urb->transfer_dma); 633702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 634702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 635702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 636702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Drop reference, USB core will take care of freeing it */ 637702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 638702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 639702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 640702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Did we submit any URBs */ 641702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (i == 0) { 642702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't setup read URBs\n"); 643702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 644702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 645702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 646702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Warn if we've couldn't transmit all the URBs */ 647702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (i < MAX_RX_URBS) 648702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "rx performance may be slow\n"); 649702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 650702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Setup and start interrupt URB */ 651702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_int_urb(dev->intr_urb, dev->udev, 652702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_rcvintpipe(dev->udev, 1), 653702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer, 654702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas INTR_IN_BUFFER_SIZE, 655702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_interrupt_callback, dev, 1); 656702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 657702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); 658702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 659702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", 660702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err); 661702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 662702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 663702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 664702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 665702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer received message to host */ 666702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON); 667702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 668702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 669702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 670702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer CAN state changes to host */ 671702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON); 672702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 673702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 674702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 675702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer bus errors to host */ 676702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON); 677702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 678702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 679702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 680702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL); 681702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 682702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 683702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 684702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_ACTIVE; 685702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 686702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 687702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 688702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasfailed: 689702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); 690702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 691702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 692702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 693702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 694702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void unlink_all_urbs(struct ems_usb *dev) 695702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 696702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i; 697702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 698702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unlink_urb(dev->intr_urb); 699702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 700702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_kill_anchored_urbs(&dev->rx_submitted); 701702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 702702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_kill_anchored_urbs(&dev->tx_submitted); 703702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_set(&dev->active_tx_urbs, 0); 704702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 705702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) 706702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_contexts[i].echo_index = MAX_TX_URBS; 707702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 708702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 709702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_open(struct net_device *netdev) 710702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 711702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 712702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err; 713702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 714702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_write_mode(dev, SJA1000_MOD_RM); 715702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 716702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 717702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 718702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* common open */ 719702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = open_candev(netdev); 720702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 721702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 722702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 723702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* finally start device */ 724702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_start(dev); 725702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 726702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 727702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(dev->netdev); 728702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 729702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't start device: %d\n", 730702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err); 731702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 732702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas close_candev(netdev); 733702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 734702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 735702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 736702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 737702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->open_time = jiffies; 738702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 739702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_start_queue(netdev); 740702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 741702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 742702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 743702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 744702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) 745702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 746702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 747702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context *context = NULL; 748702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &netdev->stats; 749702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf = (struct can_frame *)skb->data; 750702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg *msg; 751702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *urb; 752702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *buf; 753702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i, err; 754702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN 755702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas + sizeof(struct cpc_can_msg); 756702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 7573ccd4c6167d3b39d52631767ebbf8b5677c5855dOliver Hartkopp if (can_dropped_invalid_skb(netdev, skb)) 7583ccd4c6167d3b39d52631767ebbf8b5677c5855dOliver Hartkopp return NETDEV_TX_OK; 7593ccd4c6167d3b39d52631767ebbf8b5677c5855dOliver Hartkopp 760702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* create a URB, and a buffer for it, and copy the data to the URB */ 761702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb = usb_alloc_urb(0, GFP_ATOMIC); 762702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!urb) { 763702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "No memory left for URBs\n"); 764702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto nomem; 765702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 766702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 767997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); 768702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!buf) { 769702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); 770702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 771702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto nomem; 772702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 773702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 774702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE]; 775702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 776702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK; 777702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.length = cf->can_dlc; 778702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 779702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (cf->can_id & CAN_RTR_FLAG) { 780702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = cf->can_id & CAN_EFF_FLAG ? 781702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME; 782702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 783702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = CPC_CAN_MSG_MIN_SIZE; 784702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 785702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = cf->can_id & CAN_EFF_FLAG ? 786702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME; 787702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 788702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < cf->can_dlc; i++) 789702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.msg[i] = cf->data[i]; 790702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 791702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; 792702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 793702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 7942b2072e902848a63168570f500a5726744b3873aSebastian Haas /* Respect byte order */ 7952b2072e902848a63168570f500a5726744b3873aSebastian Haas msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); 7962b2072e902848a63168570f500a5726744b3873aSebastian Haas 797702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) { 798702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { 799702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context = &dev->tx_contexts[i]; 800702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 801702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 802702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 803702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 804702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* 805702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * May never happen! When this happens we'd more URBs in flight as 806702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * allowed (MAX_TX_URBS). 807702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 808702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!context) { 809702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 810997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); 811702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 812702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't find free context\n"); 813702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 814702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_BUSY; 815702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 816702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 817702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->dev = dev; 818702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->echo_index = i; 819702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->dlc = cf->can_dlc; 820702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 821702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, 822702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas size, ems_usb_write_bulk_callback, context); 823702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 824702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_anchor_urb(urb, &dev->tx_submitted); 825702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 826702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_put_echo_skb(skb, netdev, context->echo_index); 827702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 828702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_inc(&dev->active_tx_urbs); 829702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 830702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_ATOMIC); 831702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (unlikely(err)) { 832702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_free_echo_skb(netdev, context->echo_index); 833702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 834702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 835997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); 836702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_kfree_skb(skb); 837702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 838702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_dec(&dev->active_tx_urbs); 839702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 840702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) { 841702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 842702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 843702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); 844702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 845702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->tx_dropped++; 846702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 847702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 848702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->trans_start = jiffies; 849702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 850702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Slow down tx path */ 851702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS || 852702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots < 5) { 853702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_stop_queue(netdev); 854702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 855702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 856702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 857702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* 858702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Release our reference to this URB, the USB core will eventually free 859702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * it entirely. 860702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 861702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 862702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 863702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_OK; 864702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 865702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasnomem: 866ea3fb371b2a391958670f2a65e1203f7dba61671Dan Carpenter dev_kfree_skb(skb); 867702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->tx_dropped++; 868702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 869702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_OK; 870702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 871702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 872702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_close(struct net_device *netdev) 873702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 874702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 875702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 876702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Stop polling */ 877702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unlink_all_urbs(dev); 878702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 879702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_stop_queue(netdev); 880702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 881702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Set CAN controller to reset mode */ 882702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (ems_usb_write_mode(dev, SJA1000_MOD_RM)) 883702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't stop device"); 884702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 885702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas close_candev(netdev); 886702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 887702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->open_time = 0; 888702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 889702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 890702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 891702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 892702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic const struct net_device_ops ems_usb_netdev_ops = { 893702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_open = ems_usb_open, 894702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_stop = ems_usb_close, 895702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_start_xmit = ems_usb_start_xmit, 896702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 897702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 898702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct can_bittiming_const ems_usb_bittiming_const = { 899702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .name = "ems_usb", 900702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg1_min = 1, 901702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg1_max = 16, 902702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg2_min = 1, 903702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg2_max = 8, 904702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .sjw_max = 4, 905702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_min = 1, 906702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_max = 64, 907702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_inc = 1, 908702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 909702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 910702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) 911702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 912702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 913702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 914702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->open_time) 915702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -EINVAL; 916702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 917702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (mode) { 918702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CAN_MODE_START: 919702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) 920702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't start device"); 921702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 922702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (netif_queue_stopped(netdev)) 923702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_wake_queue(netdev); 924702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 925702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 926702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 927702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -EOPNOTSUPP; 928702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 929702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 930702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 931702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 932702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 933702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_set_bittiming(struct net_device *netdev) 934702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 935702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 936702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_bittiming *bt = &dev->can.bittiming; 937702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr0, btr1; 938702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 939702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); 940702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | 941702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas (((bt->phase_seg2 - 1) & 0x7) << 4); 942702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 943702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr1 |= 0x80; 944702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 945702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", 946702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr0, btr1); 947702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 948702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0; 949702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1; 950702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 951702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &dev->active_params); 952702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 953702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 954702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void init_params_sja1000(struct ems_cpc_msg *msg) 955702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 956702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_params *sja1000 = 957702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &msg->msg.can_params.cc_params.sja1000; 958702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 959702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = CPC_CMD_TYPE_CAN_PARAMS; 960702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = sizeof(struct cpc_can_params); 961702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msgid = 0; 962702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 963702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_params.cc_type = CPC_CC_TYPE_SJA1000; 964702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 965702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Acceptance filter open */ 966702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code0 = 0x00; 967702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code1 = 0x00; 968702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code2 = 0x00; 969702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code3 = 0x00; 970702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 971702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Acceptance filter open */ 972702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask0 = 0xFF; 973702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask1 = 0xFF; 974702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask2 = 0xFF; 975702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask3 = 0xFF; 976702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 977702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->btr0 = 0; 978702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->btr1 = 0; 979702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 980702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->outp_contr = SJA1000_DEFAULT_OUTPUT_CONTROL; 981702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->mode = SJA1000_MOD_RM; 982702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 983702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 984702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 985702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * probe function for new CPC-USB devices 986702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 987702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_probe(struct usb_interface *intf, 988702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas const struct usb_device_id *id) 989702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 990702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 991702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 992702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i, err = -ENOMEM; 993702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 994a6e4bc5304033e434fabccabb230b8e9ff55d76fWolfgang Grandegger netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS); 995702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netdev) { 9961c0b28b1ee90261a0a27194e6684dd2837785064Hans J. Koch dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n"); 997702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 998702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 999702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1000702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev = netdev_priv(netdev); 1001702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1002702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->udev = interface_to_usbdev(intf); 1003702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->netdev = netdev; 1004702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1005702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_STOPPED; 1006702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.clock.freq = EMS_USB_ARM7_CLOCK; 1007702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.bittiming_const = &ems_usb_bittiming_const; 1008702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.do_set_bittiming = ems_usb_set_bittiming; 1009702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.do_set_mode = ems_usb_set_mode; 1010ad72c347e56bf3a0231b9d686e17764157d2961cChristian Pellegrin dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; 1011702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1012702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->netdev_ops = &ems_usb_netdev_ops; 1013702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1014702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->flags |= IFF_ECHO; /* we support local echo */ 1015702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1016702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_usb_anchor(&dev->rx_submitted); 1017702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1018702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_usb_anchor(&dev->tx_submitted); 1019702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_set(&dev->active_tx_urbs, 0); 1020702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1021702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) 1022702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_contexts[i].echo_index = MAX_TX_URBS; 1023702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1024702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); 1025702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->intr_urb) { 10261c0b28b1ee90261a0a27194e6684dd2837785064Hans J. Koch dev_err(&intf->dev, "Couldn't alloc intr URB\n"); 1027702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_candev; 1028702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1029702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1030702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL); 1031702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->intr_in_buffer) { 10321c0b28b1ee90261a0a27194e6684dd2837785064Hans J. Koch dev_err(&intf->dev, "Couldn't alloc Intr buffer\n"); 1033702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_intr_urb; 1034702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1035702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1036702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE + 1037702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sizeof(struct ems_cpc_msg), GFP_KERNEL); 1038702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->tx_msg_buffer) { 10391c0b28b1ee90261a0a27194e6684dd2837785064Hans J. Koch dev_err(&intf->dev, "Couldn't alloc Tx buffer\n"); 1040702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_intr_in_buffer; 1041702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1042702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1043702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_set_intfdata(intf, dev); 1044702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1045702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas SET_NETDEV_DEV(netdev, &intf->dev); 1046702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1047702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_params_sja1000(&dev->active_params); 1048702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1049702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_command_msg(dev, &dev->active_params); 1050702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 1051702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 1052702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "couldn't initialize controller: %d\n", err); 1053702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_tx_msg_buffer; 1054702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1055702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1056702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = register_candev(netdev); 1057702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 1058702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 1059702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "couldn't register CAN device: %d\n", err); 1060702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_tx_msg_buffer; 1061702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1062702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1063702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 1064702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1065702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_tx_msg_buffer: 1066702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->tx_msg_buffer); 1067702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1068702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_intr_in_buffer: 1069702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->intr_in_buffer); 1070702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1071702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_intr_urb: 1072702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(dev->intr_urb); 1073702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1074702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_candev: 1075702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas free_candev(netdev); 1076702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1077702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 1078702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1079702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1080702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 1081702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * called by the usb core when the device is removed from the system 1082702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 1083702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_disconnect(struct usb_interface *intf) 1084702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 1085702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = usb_get_intfdata(intf); 1086702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1087702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_set_intfdata(intf, NULL); 1088702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1089702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev) { 1090702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unregister_netdev(dev->netdev); 1091702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas free_candev(dev->netdev); 1092702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1093702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unlink_all_urbs(dev); 1094702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1095702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(dev->intr_urb); 1096702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1097702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->intr_in_buffer); 1098702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1099702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1100702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1101702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* usb specific object needed to register this driver with the usb subsystem */ 1102702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct usb_driver ems_usb_driver = { 1103702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .name = "ems_usb", 1104702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .probe = ems_usb_probe, 1105702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .disconnect = ems_usb_disconnect, 1106702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .id_table = ems_usb_table, 1107702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 1108702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1109d632eb1bf22e11def74e4e53cc47d790fbdba105Greg Kroah-Hartmanmodule_usb_driver(ems_usb_driver); 1110