1*03fd3cf5SKurt Van Dijck /* 2*03fd3cf5SKurt Van Dijck * softing common interfaces 3*03fd3cf5SKurt Van Dijck * 4*03fd3cf5SKurt Van Dijck * by Kurt Van Dijck, 2008-2010 5*03fd3cf5SKurt Van Dijck */ 6*03fd3cf5SKurt Van Dijck 7*03fd3cf5SKurt Van Dijck #include <linux/atomic.h> 8*03fd3cf5SKurt Van Dijck #include <linux/netdevice.h> 9*03fd3cf5SKurt Van Dijck #include <linux/ktime.h> 10*03fd3cf5SKurt Van Dijck #include <linux/mutex.h> 11*03fd3cf5SKurt Van Dijck #include <linux/spinlock.h> 12*03fd3cf5SKurt Van Dijck #include <linux/can.h> 13*03fd3cf5SKurt Van Dijck #include <linux/can/dev.h> 14*03fd3cf5SKurt Van Dijck 15*03fd3cf5SKurt Van Dijck #include "softing_platform.h" 16*03fd3cf5SKurt Van Dijck 17*03fd3cf5SKurt Van Dijck struct softing; 18*03fd3cf5SKurt Van Dijck 19*03fd3cf5SKurt Van Dijck struct softing_priv { 20*03fd3cf5SKurt Van Dijck struct can_priv can; /* must be the first member! */ 21*03fd3cf5SKurt Van Dijck struct net_device *netdev; 22*03fd3cf5SKurt Van Dijck struct softing *card; 23*03fd3cf5SKurt Van Dijck struct { 24*03fd3cf5SKurt Van Dijck int pending; 25*03fd3cf5SKurt Van Dijck /* variables wich hold the circular buffer */ 26*03fd3cf5SKurt Van Dijck int echo_put; 27*03fd3cf5SKurt Van Dijck int echo_get; 28*03fd3cf5SKurt Van Dijck } tx; 29*03fd3cf5SKurt Van Dijck struct can_bittiming_const btr_const; 30*03fd3cf5SKurt Van Dijck int index; 31*03fd3cf5SKurt Van Dijck uint8_t output; 32*03fd3cf5SKurt Van Dijck uint16_t chip; 33*03fd3cf5SKurt Van Dijck }; 34*03fd3cf5SKurt Van Dijck #define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) 35*03fd3cf5SKurt Van Dijck 36*03fd3cf5SKurt Van Dijck struct softing { 37*03fd3cf5SKurt Van Dijck const struct softing_platform_data *pdat; 38*03fd3cf5SKurt Van Dijck struct platform_device *pdev; 39*03fd3cf5SKurt Van Dijck struct net_device *net[2]; 40*03fd3cf5SKurt Van Dijck spinlock_t spin; /* protect this structure & DPRAM access */ 41*03fd3cf5SKurt Van Dijck ktime_t ts_ref; 42*03fd3cf5SKurt Van Dijck ktime_t ts_overflow; /* timestamp overflow value, in ktime */ 43*03fd3cf5SKurt Van Dijck 44*03fd3cf5SKurt Van Dijck struct { 45*03fd3cf5SKurt Van Dijck /* indication of firmware status */ 46*03fd3cf5SKurt Van Dijck int up; 47*03fd3cf5SKurt Van Dijck /* protection of the 'up' variable */ 48*03fd3cf5SKurt Van Dijck struct mutex lock; 49*03fd3cf5SKurt Van Dijck } fw; 50*03fd3cf5SKurt Van Dijck struct { 51*03fd3cf5SKurt Van Dijck int nr; 52*03fd3cf5SKurt Van Dijck int requested; 53*03fd3cf5SKurt Van Dijck int svc_count; 54*03fd3cf5SKurt Van Dijck unsigned int dpram_position; 55*03fd3cf5SKurt Van Dijck } irq; 56*03fd3cf5SKurt Van Dijck struct { 57*03fd3cf5SKurt Van Dijck int pending; 58*03fd3cf5SKurt Van Dijck int last_bus; 59*03fd3cf5SKurt Van Dijck /* 60*03fd3cf5SKurt Van Dijck * keep the bus that last tx'd a message, 61*03fd3cf5SKurt Van Dijck * in order to let every netdev queue resume 62*03fd3cf5SKurt Van Dijck */ 63*03fd3cf5SKurt Van Dijck } tx; 64*03fd3cf5SKurt Van Dijck __iomem uint8_t *dpram; 65*03fd3cf5SKurt Van Dijck unsigned long dpram_phys; 66*03fd3cf5SKurt Van Dijck unsigned long dpram_size; 67*03fd3cf5SKurt Van Dijck struct { 68*03fd3cf5SKurt Van Dijck uint16_t fw_version, hw_version, license, serial; 69*03fd3cf5SKurt Van Dijck uint16_t chip[2]; 70*03fd3cf5SKurt Van Dijck unsigned int freq; /* remote cpu's operating frequency */ 71*03fd3cf5SKurt Van Dijck } id; 72*03fd3cf5SKurt Van Dijck }; 73*03fd3cf5SKurt Van Dijck 74*03fd3cf5SKurt Van Dijck extern int softing_default_output(struct net_device *netdev); 75*03fd3cf5SKurt Van Dijck 76*03fd3cf5SKurt Van Dijck extern ktime_t softing_raw2ktime(struct softing *card, u32 raw); 77*03fd3cf5SKurt Van Dijck 78*03fd3cf5SKurt Van Dijck extern int softing_chip_poweron(struct softing *card); 79*03fd3cf5SKurt Van Dijck 80*03fd3cf5SKurt Van Dijck extern int softing_bootloader_command(struct softing *card, int16_t cmd, 81*03fd3cf5SKurt Van Dijck const char *msg); 82*03fd3cf5SKurt Van Dijck 83*03fd3cf5SKurt Van Dijck /* Load firmware after reset */ 84*03fd3cf5SKurt Van Dijck extern int softing_load_fw(const char *file, struct softing *card, 85*03fd3cf5SKurt Van Dijck __iomem uint8_t *virt, unsigned int size, int offset); 86*03fd3cf5SKurt Van Dijck 87*03fd3cf5SKurt Van Dijck /* Load final application firmware after bootloader */ 88*03fd3cf5SKurt Van Dijck extern int softing_load_app_fw(const char *file, struct softing *card); 89*03fd3cf5SKurt Van Dijck 90*03fd3cf5SKurt Van Dijck /* 91*03fd3cf5SKurt Van Dijck * enable or disable irq 92*03fd3cf5SKurt Van Dijck * only called with fw.lock locked 93*03fd3cf5SKurt Van Dijck */ 94*03fd3cf5SKurt Van Dijck extern int softing_enable_irq(struct softing *card, int enable); 95*03fd3cf5SKurt Van Dijck 96*03fd3cf5SKurt Van Dijck /* start/stop 1 bus on card */ 97*03fd3cf5SKurt Van Dijck extern int softing_startstop(struct net_device *netdev, int up); 98*03fd3cf5SKurt Van Dijck 99*03fd3cf5SKurt Van Dijck /* netif_rx() */ 100*03fd3cf5SKurt Van Dijck extern int softing_netdev_rx(struct net_device *netdev, 101*03fd3cf5SKurt Van Dijck const struct can_frame *msg, ktime_t ktime); 102*03fd3cf5SKurt Van Dijck 103*03fd3cf5SKurt Van Dijck /* SOFTING DPRAM mappings */ 104*03fd3cf5SKurt Van Dijck #define DPRAM_RX 0x0000 105*03fd3cf5SKurt Van Dijck #define DPRAM_RX_SIZE 32 106*03fd3cf5SKurt Van Dijck #define DPRAM_RX_CNT 16 107*03fd3cf5SKurt Van Dijck #define DPRAM_RX_RD 0x0201 /* uint8_t */ 108*03fd3cf5SKurt Van Dijck #define DPRAM_RX_WR 0x0205 /* uint8_t */ 109*03fd3cf5SKurt Van Dijck #define DPRAM_RX_LOST 0x0207 /* uint8_t */ 110*03fd3cf5SKurt Van Dijck 111*03fd3cf5SKurt Van Dijck #define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ 112*03fd3cf5SKurt Van Dijck #define DPRAM_FCT_RESULT 0x0328 /* int16_t */ 113*03fd3cf5SKurt Van Dijck #define DPRAM_FCT_HOST 0x032b /* uint16_t */ 114*03fd3cf5SKurt Van Dijck 115*03fd3cf5SKurt Van Dijck #define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ 116*03fd3cf5SKurt Van Dijck #define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ 117*03fd3cf5SKurt Van Dijck #define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ 118*03fd3cf5SKurt Van Dijck #define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ 119*03fd3cf5SKurt Van Dijck #define DPRAM_RESET 0x0341 /* uint16_t */ 120*03fd3cf5SKurt Van Dijck #define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ 121*03fd3cf5SKurt Van Dijck #define DPRAM_RESET_TIME 0x034d /* uint16_t */ 122*03fd3cf5SKurt Van Dijck #define DPRAM_TIME 0x0350 /* uint64_t */ 123*03fd3cf5SKurt Van Dijck #define DPRAM_WR_START 0x0358 /* uint8_t */ 124*03fd3cf5SKurt Van Dijck #define DPRAM_WR_END 0x0359 /* uint8_t */ 125*03fd3cf5SKurt Van Dijck #define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ 126*03fd3cf5SKurt Van Dijck #define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ 127*03fd3cf5SKurt Van Dijck #define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ 128*03fd3cf5SKurt Van Dijck #define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ 129*03fd3cf5SKurt Van Dijck #define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ 130*03fd3cf5SKurt Van Dijck 131*03fd3cf5SKurt Van Dijck #define DPRAM_TX 0x0400 /* uint16_t */ 132*03fd3cf5SKurt Van Dijck #define DPRAM_TX_SIZE 16 133*03fd3cf5SKurt Van Dijck #define DPRAM_TX_CNT 32 134*03fd3cf5SKurt Van Dijck #define DPRAM_TX_RD 0x0601 /* uint8_t */ 135*03fd3cf5SKurt Van Dijck #define DPRAM_TX_WR 0x0605 /* uint8_t */ 136*03fd3cf5SKurt Van Dijck 137*03fd3cf5SKurt Van Dijck #define DPRAM_COMMAND 0x07e0 /* uint16_t */ 138*03fd3cf5SKurt Van Dijck #define DPRAM_RECEIPT 0x07f0 /* uint16_t */ 139*03fd3cf5SKurt Van Dijck #define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ 140*03fd3cf5SKurt Van Dijck #define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ 141*03fd3cf5SKurt Van Dijck 142*03fd3cf5SKurt Van Dijck #define DPRAM_V2_RESET 0x0e00 /* uint8_t */ 143*03fd3cf5SKurt Van Dijck #define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ 144*03fd3cf5SKurt Van Dijck 145*03fd3cf5SKurt Van Dijck #define TXMAX (DPRAM_TX_CNT - 1) 146*03fd3cf5SKurt Van Dijck 147*03fd3cf5SKurt Van Dijck /* DPRAM return codes */ 148*03fd3cf5SKurt Van Dijck #define RES_NONE 0 149*03fd3cf5SKurt Van Dijck #define RES_OK 1 150*03fd3cf5SKurt Van Dijck #define RES_NOK 2 151*03fd3cf5SKurt Van Dijck #define RES_UNKNOWN 3 152*03fd3cf5SKurt Van Dijck /* DPRAM flags */ 153*03fd3cf5SKurt Van Dijck #define CMD_TX 0x01 154*03fd3cf5SKurt Van Dijck #define CMD_ACK 0x02 155*03fd3cf5SKurt Van Dijck #define CMD_XTD 0x04 156*03fd3cf5SKurt Van Dijck #define CMD_RTR 0x08 157*03fd3cf5SKurt Van Dijck #define CMD_ERR 0x10 158*03fd3cf5SKurt Van Dijck #define CMD_BUS2 0x80 159*03fd3cf5SKurt Van Dijck 160*03fd3cf5SKurt Van Dijck /* returned fifo entry bus state masks */ 161*03fd3cf5SKurt Van Dijck #define SF_MASK_BUSOFF 0x80 162*03fd3cf5SKurt Van Dijck #define SF_MASK_EPASSIVE 0x60 163*03fd3cf5SKurt Van Dijck 164*03fd3cf5SKurt Van Dijck /* bus states */ 165*03fd3cf5SKurt Van Dijck #define STATE_BUSOFF 2 166*03fd3cf5SKurt Van Dijck #define STATE_EPASSIVE 1 167*03fd3cf5SKurt Van Dijck #define STATE_EACTIVE 0 168