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