cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

softing_main.c (20765B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2008-2010
      4 *
      5 * - Kurt Van Dijck, EIA Electronics
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/interrupt.h>
     10#include <asm/io.h>
     11
     12#include "softing.h"
     13
     14#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1)
     15
     16/*
     17 * test is a specific CAN netdev
     18 * is online (ie. up 'n running, not sleeping, not busoff
     19 */
     20static inline int canif_is_active(struct net_device *netdev)
     21{
     22	struct can_priv *can = netdev_priv(netdev);
     23
     24	if (!netif_running(netdev))
     25		return 0;
     26	return (can->state <= CAN_STATE_ERROR_PASSIVE);
     27}
     28
     29/* reset DPRAM */
     30static inline void softing_set_reset_dpram(struct softing *card)
     31{
     32	if (card->pdat->generation >= 2) {
     33		spin_lock_bh(&card->spin);
     34		iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1,
     35				&card->dpram[DPRAM_V2_RESET]);
     36		spin_unlock_bh(&card->spin);
     37	}
     38}
     39
     40static inline void softing_clr_reset_dpram(struct softing *card)
     41{
     42	if (card->pdat->generation >= 2) {
     43		spin_lock_bh(&card->spin);
     44		iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1,
     45				&card->dpram[DPRAM_V2_RESET]);
     46		spin_unlock_bh(&card->spin);
     47	}
     48}
     49
     50/* trigger the tx queue-ing */
     51static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
     52		struct net_device *dev)
     53{
     54	struct softing_priv *priv = netdev_priv(dev);
     55	struct softing *card = priv->card;
     56	int ret;
     57	uint8_t *ptr;
     58	uint8_t fifo_wr, fifo_rd;
     59	struct can_frame *cf = (struct can_frame *)skb->data;
     60	uint8_t buf[DPRAM_TX_SIZE];
     61
     62	if (can_dropped_invalid_skb(dev, skb))
     63		return NETDEV_TX_OK;
     64
     65	spin_lock(&card->spin);
     66
     67	ret = NETDEV_TX_BUSY;
     68	if (!card->fw.up ||
     69			(card->tx.pending >= TXMAX) ||
     70			(priv->tx.pending >= TX_ECHO_SKB_MAX))
     71		goto xmit_done;
     72	fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]);
     73	fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]);
     74	if (fifo_wr == fifo_rd)
     75		/* fifo full */
     76		goto xmit_done;
     77	memset(buf, 0, sizeof(buf));
     78	ptr = buf;
     79	*ptr = CMD_TX;
     80	if (cf->can_id & CAN_RTR_FLAG)
     81		*ptr |= CMD_RTR;
     82	if (cf->can_id & CAN_EFF_FLAG)
     83		*ptr |= CMD_XTD;
     84	if (priv->index)
     85		*ptr |= CMD_BUS2;
     86	++ptr;
     87	*ptr++ = cf->len;
     88	*ptr++ = (cf->can_id >> 0);
     89	*ptr++ = (cf->can_id >> 8);
     90	if (cf->can_id & CAN_EFF_FLAG) {
     91		*ptr++ = (cf->can_id >> 16);
     92		*ptr++ = (cf->can_id >> 24);
     93	} else {
     94		/* increment 1, not 2 as you might think */
     95		ptr += 1;
     96	}
     97	if (!(cf->can_id & CAN_RTR_FLAG))
     98		memcpy(ptr, &cf->data[0], cf->len);
     99	memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr],
    100			buf, DPRAM_TX_SIZE);
    101	if (++fifo_wr >= DPRAM_TX_CNT)
    102		fifo_wr = 0;
    103	iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]);
    104	card->tx.last_bus = priv->index;
    105	++card->tx.pending;
    106	++priv->tx.pending;
    107	can_put_echo_skb(skb, dev, priv->tx.echo_put, 0);
    108	++priv->tx.echo_put;
    109	if (priv->tx.echo_put >= TX_ECHO_SKB_MAX)
    110		priv->tx.echo_put = 0;
    111	/* can_put_echo_skb() saves the skb, safe to return TX_OK */
    112	ret = NETDEV_TX_OK;
    113xmit_done:
    114	spin_unlock(&card->spin);
    115	if (card->tx.pending >= TXMAX) {
    116		int j;
    117		for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    118			if (card->net[j])
    119				netif_stop_queue(card->net[j]);
    120		}
    121	}
    122	if (ret != NETDEV_TX_OK)
    123		netif_stop_queue(dev);
    124
    125	return ret;
    126}
    127
    128/*
    129 * shortcut for skb delivery
    130 */
    131int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg,
    132		ktime_t ktime)
    133{
    134	struct sk_buff *skb;
    135	struct can_frame *cf;
    136
    137	skb = alloc_can_skb(netdev, &cf);
    138	if (!skb)
    139		return -ENOMEM;
    140	memcpy(cf, msg, sizeof(*msg));
    141	skb->tstamp = ktime;
    142	return netif_rx(skb);
    143}
    144
    145/*
    146 * softing_handle_1
    147 * pop 1 entry from the DPRAM queue, and process
    148 */
    149static int softing_handle_1(struct softing *card)
    150{
    151	struct net_device *netdev;
    152	struct softing_priv *priv;
    153	ktime_t ktime;
    154	struct can_frame msg;
    155	int cnt = 0, lost_msg;
    156	uint8_t fifo_rd, fifo_wr, cmd;
    157	uint8_t *ptr;
    158	uint32_t tmp_u32;
    159	uint8_t buf[DPRAM_RX_SIZE];
    160
    161	memset(&msg, 0, sizeof(msg));
    162	/* test for lost msgs */
    163	lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]);
    164	if (lost_msg) {
    165		int j;
    166		/* reset condition */
    167		iowrite8(0, &card->dpram[DPRAM_RX_LOST]);
    168		/* prepare msg */
    169		msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
    170		msg.len = CAN_ERR_DLC;
    171		msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
    172		/*
    173		 * service to all buses, we don't know which it was applicable
    174		 * but only service buses that are online
    175		 */
    176		for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    177			netdev = card->net[j];
    178			if (!netdev)
    179				continue;
    180			if (!canif_is_active(netdev))
    181				/* a dead bus has no overflows */
    182				continue;
    183			++netdev->stats.rx_over_errors;
    184			softing_netdev_rx(netdev, &msg, 0);
    185		}
    186		/* prepare for other use */
    187		memset(&msg, 0, sizeof(msg));
    188		++cnt;
    189	}
    190
    191	fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]);
    192	fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]);
    193
    194	if (++fifo_rd >= DPRAM_RX_CNT)
    195		fifo_rd = 0;
    196	if (fifo_wr == fifo_rd)
    197		return cnt;
    198
    199	memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd],
    200			DPRAM_RX_SIZE);
    201	mb();
    202	/* trigger dual port RAM */
    203	iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]);
    204
    205	ptr = buf;
    206	cmd = *ptr++;
    207	if (cmd == 0xff)
    208		/* not quite useful, probably the card has got out */
    209		return 0;
    210	netdev = card->net[0];
    211	if (cmd & CMD_BUS2)
    212		netdev = card->net[1];
    213	priv = netdev_priv(netdev);
    214
    215	if (cmd & CMD_ERR) {
    216		uint8_t can_state, state;
    217
    218		state = *ptr++;
    219
    220		msg.can_id = CAN_ERR_FLAG;
    221		msg.len = CAN_ERR_DLC;
    222
    223		if (state & SF_MASK_BUSOFF) {
    224			can_state = CAN_STATE_BUS_OFF;
    225			msg.can_id |= CAN_ERR_BUSOFF;
    226			state = STATE_BUSOFF;
    227		} else if (state & SF_MASK_EPASSIVE) {
    228			can_state = CAN_STATE_ERROR_PASSIVE;
    229			msg.can_id |= CAN_ERR_CRTL;
    230			msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE;
    231			state = STATE_EPASSIVE;
    232		} else {
    233			can_state = CAN_STATE_ERROR_ACTIVE;
    234			msg.can_id |= CAN_ERR_CRTL;
    235			state = STATE_EACTIVE;
    236		}
    237		/* update DPRAM */
    238		iowrite8(state, &card->dpram[priv->index ?
    239				DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]);
    240		/* timestamp */
    241		tmp_u32 = le32_to_cpup((void *)ptr);
    242		ktime = softing_raw2ktime(card, tmp_u32);
    243
    244		++netdev->stats.rx_errors;
    245		/* update internal status */
    246		if (can_state != priv->can.state) {
    247			priv->can.state = can_state;
    248			if (can_state == CAN_STATE_ERROR_PASSIVE)
    249				++priv->can.can_stats.error_passive;
    250			else if (can_state == CAN_STATE_BUS_OFF) {
    251				/* this calls can_close_cleanup() */
    252				++priv->can.can_stats.bus_off;
    253				can_bus_off(netdev);
    254				netif_stop_queue(netdev);
    255			}
    256			/* trigger socketcan */
    257			softing_netdev_rx(netdev, &msg, ktime);
    258		}
    259
    260	} else {
    261		if (cmd & CMD_RTR)
    262			msg.can_id |= CAN_RTR_FLAG;
    263		msg.len = can_cc_dlc2len(*ptr++);
    264		if (cmd & CMD_XTD) {
    265			msg.can_id |= CAN_EFF_FLAG;
    266			msg.can_id |= le32_to_cpup((void *)ptr);
    267			ptr += 4;
    268		} else {
    269			msg.can_id |= le16_to_cpup((void *)ptr);
    270			ptr += 2;
    271		}
    272		/* timestamp */
    273		tmp_u32 = le32_to_cpup((void *)ptr);
    274		ptr += 4;
    275		ktime = softing_raw2ktime(card, tmp_u32);
    276		if (!(msg.can_id & CAN_RTR_FLAG))
    277			memcpy(&msg.data[0], ptr, 8);
    278		/* update socket */
    279		if (cmd & CMD_ACK) {
    280			/* acknowledge, was tx msg */
    281			struct sk_buff *skb;
    282			skb = priv->can.echo_skb[priv->tx.echo_get];
    283			if (skb)
    284				skb->tstamp = ktime;
    285			++netdev->stats.tx_packets;
    286			netdev->stats.tx_bytes +=
    287				can_get_echo_skb(netdev, priv->tx.echo_get,
    288						 NULL);
    289			++priv->tx.echo_get;
    290			if (priv->tx.echo_get >= TX_ECHO_SKB_MAX)
    291				priv->tx.echo_get = 0;
    292			if (priv->tx.pending)
    293				--priv->tx.pending;
    294			if (card->tx.pending)
    295				--card->tx.pending;
    296		} else {
    297			int ret;
    298
    299			ret = softing_netdev_rx(netdev, &msg, ktime);
    300			if (ret == NET_RX_SUCCESS) {
    301				++netdev->stats.rx_packets;
    302				if (!(msg.can_id & CAN_RTR_FLAG))
    303					netdev->stats.rx_bytes += msg.len;
    304			} else {
    305				++netdev->stats.rx_dropped;
    306			}
    307		}
    308	}
    309	++cnt;
    310	return cnt;
    311}
    312
    313/*
    314 * real interrupt handler
    315 */
    316static irqreturn_t softing_irq_thread(int irq, void *dev_id)
    317{
    318	struct softing *card = (struct softing *)dev_id;
    319	struct net_device *netdev;
    320	struct softing_priv *priv;
    321	int j, offset, work_done;
    322
    323	work_done = 0;
    324	spin_lock_bh(&card->spin);
    325	while (softing_handle_1(card) > 0) {
    326		++card->irq.svc_count;
    327		++work_done;
    328	}
    329	spin_unlock_bh(&card->spin);
    330	/* resume tx queue's */
    331	offset = card->tx.last_bus;
    332	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    333		if (card->tx.pending >= TXMAX)
    334			break;
    335		netdev = card->net[(j + offset + 1) % card->pdat->nbus];
    336		if (!netdev)
    337			continue;
    338		priv = netdev_priv(netdev);
    339		if (!canif_is_active(netdev))
    340			/* it makes no sense to wake dead buses */
    341			continue;
    342		if (priv->tx.pending >= TX_ECHO_SKB_MAX)
    343			continue;
    344		++work_done;
    345		netif_wake_queue(netdev);
    346	}
    347	return work_done ? IRQ_HANDLED : IRQ_NONE;
    348}
    349
    350/*
    351 * interrupt routines:
    352 * schedule the 'real interrupt handler'
    353 */
    354static irqreturn_t softing_irq_v2(int irq, void *dev_id)
    355{
    356	struct softing *card = (struct softing *)dev_id;
    357	uint8_t ir;
    358
    359	ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]);
    360	iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
    361	return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE;
    362}
    363
    364static irqreturn_t softing_irq_v1(int irq, void *dev_id)
    365{
    366	struct softing *card = (struct softing *)dev_id;
    367	uint8_t ir;
    368
    369	ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]);
    370	iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]);
    371	return ir ? IRQ_WAKE_THREAD : IRQ_NONE;
    372}
    373
    374/*
    375 * netdev/candev interoperability
    376 */
    377static int softing_netdev_open(struct net_device *ndev)
    378{
    379	int ret;
    380
    381	/* check or determine and set bittime */
    382	ret = open_candev(ndev);
    383	if (ret)
    384		return ret;
    385
    386	ret = softing_startstop(ndev, 1);
    387	if (ret < 0)
    388		close_candev(ndev);
    389
    390	return ret;
    391}
    392
    393static int softing_netdev_stop(struct net_device *ndev)
    394{
    395	netif_stop_queue(ndev);
    396
    397	/* softing cycle does close_candev() */
    398	return softing_startstop(ndev, 0);
    399}
    400
    401static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode)
    402{
    403	int ret;
    404
    405	switch (mode) {
    406	case CAN_MODE_START:
    407		/* softing_startstop does close_candev() */
    408		ret = softing_startstop(ndev, 1);
    409		return ret;
    410	case CAN_MODE_STOP:
    411	case CAN_MODE_SLEEP:
    412		return -EOPNOTSUPP;
    413	}
    414	return 0;
    415}
    416
    417/*
    418 * Softing device management helpers
    419 */
    420int softing_enable_irq(struct softing *card, int enable)
    421{
    422	int ret;
    423
    424	if (!card->irq.nr) {
    425		return 0;
    426	} else if (card->irq.requested && !enable) {
    427		free_irq(card->irq.nr, card);
    428		card->irq.requested = 0;
    429	} else if (!card->irq.requested && enable) {
    430		ret = request_threaded_irq(card->irq.nr,
    431				(card->pdat->generation >= 2) ?
    432					softing_irq_v2 : softing_irq_v1,
    433				softing_irq_thread, IRQF_SHARED,
    434				dev_name(&card->pdev->dev), card);
    435		if (ret) {
    436			dev_alert(&card->pdev->dev,
    437					"request_threaded_irq(%u) failed\n",
    438					card->irq.nr);
    439			return ret;
    440		}
    441		card->irq.requested = 1;
    442	}
    443	return 0;
    444}
    445
    446static void softing_card_shutdown(struct softing *card)
    447{
    448	int fw_up = 0;
    449
    450	if (mutex_lock_interruptible(&card->fw.lock)) {
    451		/* return -ERESTARTSYS */;
    452	}
    453	fw_up = card->fw.up;
    454	card->fw.up = 0;
    455
    456	if (card->irq.requested && card->irq.nr) {
    457		free_irq(card->irq.nr, card);
    458		card->irq.requested = 0;
    459	}
    460	if (fw_up) {
    461		if (card->pdat->enable_irq)
    462			card->pdat->enable_irq(card->pdev, 0);
    463		softing_set_reset_dpram(card);
    464		if (card->pdat->reset)
    465			card->pdat->reset(card->pdev, 1);
    466	}
    467	mutex_unlock(&card->fw.lock);
    468}
    469
    470static int softing_card_boot(struct softing *card)
    471{
    472	int ret, j;
    473	static const uint8_t stream[] = {
    474		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, };
    475	unsigned char back[sizeof(stream)];
    476
    477	if (mutex_lock_interruptible(&card->fw.lock))
    478		return -ERESTARTSYS;
    479	if (card->fw.up) {
    480		mutex_unlock(&card->fw.lock);
    481		return 0;
    482	}
    483	/* reset board */
    484	if (card->pdat->enable_irq)
    485		card->pdat->enable_irq(card->pdev, 1);
    486	/* boot card */
    487	softing_set_reset_dpram(card);
    488	if (card->pdat->reset)
    489		card->pdat->reset(card->pdev, 1);
    490	for (j = 0; (j + sizeof(stream)) < card->dpram_size;
    491			j += sizeof(stream)) {
    492
    493		memcpy_toio(&card->dpram[j], stream, sizeof(stream));
    494		/* flush IO cache */
    495		mb();
    496		memcpy_fromio(back, &card->dpram[j], sizeof(stream));
    497
    498		if (!memcmp(back, stream, sizeof(stream)))
    499			continue;
    500		/* memory is not equal */
    501		dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j);
    502		ret = -EIO;
    503		goto failed;
    504	}
    505	wmb();
    506	/* load boot firmware */
    507	ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram,
    508				card->dpram_size,
    509				card->pdat->boot.offs - card->pdat->boot.addr);
    510	if (ret < 0)
    511		goto failed;
    512	/* load loader firmware */
    513	ret = softing_load_fw(card->pdat->load.fw, card, card->dpram,
    514				card->dpram_size,
    515				card->pdat->load.offs - card->pdat->load.addr);
    516	if (ret < 0)
    517		goto failed;
    518
    519	if (card->pdat->reset)
    520		card->pdat->reset(card->pdev, 0);
    521	softing_clr_reset_dpram(card);
    522	ret = softing_bootloader_command(card, 0, "card boot");
    523	if (ret < 0)
    524		goto failed;
    525	ret = softing_load_app_fw(card->pdat->app.fw, card);
    526	if (ret < 0)
    527		goto failed;
    528
    529	ret = softing_chip_poweron(card);
    530	if (ret < 0)
    531		goto failed;
    532
    533	card->fw.up = 1;
    534	mutex_unlock(&card->fw.lock);
    535	return 0;
    536failed:
    537	card->fw.up = 0;
    538	if (card->pdat->enable_irq)
    539		card->pdat->enable_irq(card->pdev, 0);
    540	softing_set_reset_dpram(card);
    541	if (card->pdat->reset)
    542		card->pdat->reset(card->pdev, 1);
    543	mutex_unlock(&card->fw.lock);
    544	return ret;
    545}
    546
    547/*
    548 * netdev sysfs
    549 */
    550static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
    551		char *buf)
    552{
    553	struct net_device *ndev = to_net_dev(dev);
    554	struct softing_priv *priv = netdev2softing(ndev);
    555
    556	return sprintf(buf, "%i\n", priv->chip);
    557}
    558
    559static ssize_t show_output(struct device *dev, struct device_attribute *attr,
    560		char *buf)
    561{
    562	struct net_device *ndev = to_net_dev(dev);
    563	struct softing_priv *priv = netdev2softing(ndev);
    564
    565	return sprintf(buf, "0x%02x\n", priv->output);
    566}
    567
    568static ssize_t store_output(struct device *dev, struct device_attribute *attr,
    569		const char *buf, size_t count)
    570{
    571	struct net_device *ndev = to_net_dev(dev);
    572	struct softing_priv *priv = netdev2softing(ndev);
    573	struct softing *card = priv->card;
    574	unsigned long val;
    575	int ret;
    576
    577	ret = kstrtoul(buf, 0, &val);
    578	if (ret < 0)
    579		return ret;
    580	val &= 0xFF;
    581
    582	ret = mutex_lock_interruptible(&card->fw.lock);
    583	if (ret)
    584		return -ERESTARTSYS;
    585	if (netif_running(ndev)) {
    586		mutex_unlock(&card->fw.lock);
    587		return -EBUSY;
    588	}
    589	priv->output = val;
    590	mutex_unlock(&card->fw.lock);
    591	return count;
    592}
    593
    594static const DEVICE_ATTR(chip, 0444, show_chip, NULL);
    595static const DEVICE_ATTR(output, 0644, show_output, store_output);
    596
    597static const struct attribute *const netdev_sysfs_attrs[] = {
    598	&dev_attr_chip.attr,
    599	&dev_attr_output.attr,
    600	NULL,
    601};
    602static const struct attribute_group netdev_sysfs_group = {
    603	.name = NULL,
    604	.attrs = (struct attribute **)netdev_sysfs_attrs,
    605};
    606
    607static const struct net_device_ops softing_netdev_ops = {
    608	.ndo_open = softing_netdev_open,
    609	.ndo_stop = softing_netdev_stop,
    610	.ndo_start_xmit	= softing_netdev_start_xmit,
    611	.ndo_change_mtu = can_change_mtu,
    612};
    613
    614static const struct can_bittiming_const softing_btr_const = {
    615	.name = "softing",
    616	.tseg1_min = 1,
    617	.tseg1_max = 16,
    618	.tseg2_min = 1,
    619	.tseg2_max = 8,
    620	.sjw_max = 4, /* overruled */
    621	.brp_min = 1,
    622	.brp_max = 32, /* overruled */
    623	.brp_inc = 1,
    624};
    625
    626
    627static struct net_device *softing_netdev_create(struct softing *card,
    628						uint16_t chip_id)
    629{
    630	struct net_device *netdev;
    631	struct softing_priv *priv;
    632
    633	netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
    634	if (!netdev) {
    635		dev_alert(&card->pdev->dev, "alloc_candev failed\n");
    636		return NULL;
    637	}
    638	priv = netdev_priv(netdev);
    639	priv->netdev = netdev;
    640	priv->card = card;
    641	memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const));
    642	priv->btr_const.brp_max = card->pdat->max_brp;
    643	priv->btr_const.sjw_max = card->pdat->max_sjw;
    644	priv->can.bittiming_const = &priv->btr_const;
    645	priv->can.clock.freq = 8000000;
    646	priv->chip = chip_id;
    647	priv->output = softing_default_output(netdev);
    648	SET_NETDEV_DEV(netdev, &card->pdev->dev);
    649
    650	netdev->flags |= IFF_ECHO;
    651	netdev->netdev_ops = &softing_netdev_ops;
    652	priv->can.do_set_mode = softing_candev_set_mode;
    653	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
    654
    655	return netdev;
    656}
    657
    658static int softing_netdev_register(struct net_device *netdev)
    659{
    660	int ret;
    661
    662	ret = register_candev(netdev);
    663	if (ret) {
    664		dev_alert(&netdev->dev, "register failed\n");
    665		return ret;
    666	}
    667	if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0)
    668		netdev_alert(netdev, "sysfs group failed\n");
    669
    670	return 0;
    671}
    672
    673static void softing_netdev_cleanup(struct net_device *netdev)
    674{
    675	sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group);
    676	unregister_candev(netdev);
    677	free_candev(netdev);
    678}
    679
    680/*
    681 * sysfs for Platform device
    682 */
    683#define DEV_ATTR_RO(name, member) \
    684static ssize_t show_##name(struct device *dev, \
    685		struct device_attribute *attr, char *buf) \
    686{ \
    687	struct softing *card = dev_get_drvdata(dev); \
    688	return sprintf(buf, "%u\n", card->member); \
    689} \
    690static DEVICE_ATTR(name, 0444, show_##name, NULL)
    691
    692#define DEV_ATTR_RO_STR(name, member) \
    693static ssize_t show_##name(struct device *dev, \
    694		struct device_attribute *attr, char *buf) \
    695{ \
    696	struct softing *card = dev_get_drvdata(dev); \
    697	return sprintf(buf, "%s\n", card->member); \
    698} \
    699static DEVICE_ATTR(name, 0444, show_##name, NULL)
    700
    701DEV_ATTR_RO(serial, id.serial);
    702DEV_ATTR_RO_STR(firmware, pdat->app.fw);
    703DEV_ATTR_RO(firmware_version, id.fw_version);
    704DEV_ATTR_RO_STR(hardware, pdat->name);
    705DEV_ATTR_RO(hardware_version, id.hw_version);
    706DEV_ATTR_RO(license, id.license);
    707
    708static struct attribute *softing_pdev_attrs[] = {
    709	&dev_attr_serial.attr,
    710	&dev_attr_firmware.attr,
    711	&dev_attr_firmware_version.attr,
    712	&dev_attr_hardware.attr,
    713	&dev_attr_hardware_version.attr,
    714	&dev_attr_license.attr,
    715	NULL,
    716};
    717
    718static const struct attribute_group softing_pdev_group = {
    719	.name = NULL,
    720	.attrs = softing_pdev_attrs,
    721};
    722
    723/*
    724 * platform driver
    725 */
    726static int softing_pdev_remove(struct platform_device *pdev)
    727{
    728	struct softing *card = platform_get_drvdata(pdev);
    729	int j;
    730
    731	/* first, disable card*/
    732	softing_card_shutdown(card);
    733
    734	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    735		if (!card->net[j])
    736			continue;
    737		softing_netdev_cleanup(card->net[j]);
    738		card->net[j] = NULL;
    739	}
    740	sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
    741
    742	iounmap(card->dpram);
    743	kfree(card);
    744	return 0;
    745}
    746
    747static int softing_pdev_probe(struct platform_device *pdev)
    748{
    749	const struct softing_platform_data *pdat = dev_get_platdata(&pdev->dev);
    750	struct softing *card;
    751	struct net_device *netdev;
    752	struct softing_priv *priv;
    753	struct resource *pres;
    754	int ret;
    755	int j;
    756
    757	if (!pdat) {
    758		dev_warn(&pdev->dev, "no platform data\n");
    759		return -EINVAL;
    760	}
    761	if (pdat->nbus > ARRAY_SIZE(card->net)) {
    762		dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus);
    763		return -EINVAL;
    764	}
    765
    766	card = kzalloc(sizeof(*card), GFP_KERNEL);
    767	if (!card)
    768		return -ENOMEM;
    769	card->pdat = pdat;
    770	card->pdev = pdev;
    771	platform_set_drvdata(pdev, card);
    772	mutex_init(&card->fw.lock);
    773	spin_lock_init(&card->spin);
    774
    775	ret = -EINVAL;
    776	pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    777	if (!pres)
    778		goto platform_resource_failed;
    779	card->dpram_phys = pres->start;
    780	card->dpram_size = resource_size(pres);
    781	card->dpram = ioremap(card->dpram_phys, card->dpram_size);
    782	if (!card->dpram) {
    783		dev_alert(&card->pdev->dev, "dpram ioremap failed\n");
    784		goto ioremap_failed;
    785	}
    786
    787	pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    788	if (pres)
    789		card->irq.nr = pres->start;
    790
    791	/* reset card */
    792	ret = softing_card_boot(card);
    793	if (ret < 0) {
    794		dev_alert(&pdev->dev, "failed to boot\n");
    795		goto boot_failed;
    796	}
    797
    798	/* only now, the chip's are known */
    799	card->id.freq = card->pdat->freq;
    800
    801	ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group);
    802	if (ret < 0) {
    803		dev_alert(&card->pdev->dev, "sysfs failed\n");
    804		goto sysfs_failed;
    805	}
    806
    807	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    808		card->net[j] = netdev =
    809			softing_netdev_create(card, card->id.chip[j]);
    810		if (!netdev) {
    811			dev_alert(&pdev->dev, "failed to make can[%i]", j);
    812			ret = -ENOMEM;
    813			goto netdev_failed;
    814		}
    815		netdev->dev_id = j;
    816		priv = netdev_priv(card->net[j]);
    817		priv->index = j;
    818		ret = softing_netdev_register(netdev);
    819		if (ret) {
    820			free_candev(netdev);
    821			card->net[j] = NULL;
    822			dev_alert(&card->pdev->dev,
    823					"failed to register can[%i]\n", j);
    824			goto netdev_failed;
    825		}
    826	}
    827	dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name);
    828	return 0;
    829
    830netdev_failed:
    831	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
    832		if (!card->net[j])
    833			continue;
    834		softing_netdev_cleanup(card->net[j]);
    835	}
    836	sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
    837sysfs_failed:
    838	softing_card_shutdown(card);
    839boot_failed:
    840	iounmap(card->dpram);
    841ioremap_failed:
    842platform_resource_failed:
    843	kfree(card);
    844	return ret;
    845}
    846
    847static struct platform_driver softing_driver = {
    848	.driver = {
    849		.name = "softing",
    850	},
    851	.probe = softing_pdev_probe,
    852	.remove = softing_pdev_remove,
    853};
    854
    855module_platform_driver(softing_driver);
    856
    857MODULE_ALIAS("platform:softing");
    858MODULE_DESCRIPTION("Softing DPRAM CAN driver");
    859MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>");
    860MODULE_LICENSE("GPL v2");