140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Copyright (C) ST-Ericsson AB 2010
340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com
440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Author:  Daniel Martensson / daniel.martensson@stericsson.com
540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin *	    Dmitry.Tarnyagin  / dmitry.tarnyagin@stericsson.com
640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * License terms: GNU General Public License (GPL) version 2
740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#ifndef CAIF_HSI_H_
1040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CAIF_HSI_H_
1140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
1240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#include <net/caif/caif_layer.h>
1340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#include <net/caif/caif_device.h>
1440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#include <linux/atomic.h>
1540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
1640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
1740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Maximum number of CAIF frames that can reside in the same HSI frame.
1840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
1940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_MAX_PKTS 15
2040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
2140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
2240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Maximum number of bytes used for the frame that can be embedded in the
2340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * HSI descriptor.
2440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
2540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_MAX_EMB_FRM_SZ 96
2640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
2740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
2840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Decides if HSI buffers should be prefilled with 0xFF pattern for easier
2940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * debugging. Both TX and RX buffers will be filled before the transfer.
3040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
3140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_DBG_PREFILL		0
3240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
3340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Structure describing a HSI packet descriptor. */
3440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#pragma pack(1) /* Byte alignment. */
3540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyaginstruct cfhsi_desc {
3640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 header;
3740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 offset;
3840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u16 cffrm_len[CFHSI_MAX_PKTS];
3940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 emb_frm[CFHSI_MAX_EMB_FRM_SZ];
4040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin};
4140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#pragma pack() /* Default alignment. */
4240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
4340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Size of the complete HSI packet descriptor. */
4440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_DESC_SZ (sizeof(struct cfhsi_desc))
4540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
4640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
4740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Size of the complete HSI packet descriptor excluding the optional embedded
4840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * CAIF frame.
4940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
5040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_DESC_SHORT_SZ (CFHSI_DESC_SZ - CFHSI_MAX_EMB_FRM_SZ)
5140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
5240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/*
5340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin * Maximum bytes transferred in one transfer.
5440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin */
555bbed92d3d8dab1f28945eec9fb15b6f50bf8669Daniel Martensson#define CFHSI_MAX_CAIF_FRAME_SZ 4096
565bbed92d3d8dab1f28945eec9fb15b6f50bf8669Daniel Martensson
575bbed92d3d8dab1f28945eec9fb15b6f50bf8669Daniel Martensson#define CFHSI_MAX_PAYLOAD_SZ (CFHSI_MAX_PKTS * CFHSI_MAX_CAIF_FRAME_SZ)
5840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
5940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Size of the complete HSI TX buffer. */
6040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_BUF_SZ_TX (CFHSI_DESC_SZ + CFHSI_MAX_PAYLOAD_SZ)
6140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
6240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Size of the complete HSI RX buffer. */
6340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_BUF_SZ_RX ((2 * CFHSI_DESC_SZ) + CFHSI_MAX_PAYLOAD_SZ)
6440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
6540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Bitmasks for the HSI descriptor. */
6640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_PIGGY_DESC		(0x01 << 7)
6740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
6840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_TX_STATE_IDLE			0
6940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_TX_STATE_XFER			1
7040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
7140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_RX_STATE_DESC			0
7240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_RX_STATE_PAYLOAD			1
7340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
7440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Bitmasks for power management. */
7540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_WAKE_UP				0
7640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_WAKE_UP_ACK			1
7740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_WAKE_DOWN_ACK			2
7840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_AWAKE				3
79687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#define CFHSI_WAKELOCK_HELD			4
80687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#define CFHSI_SHUTDOWN				5
81687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#define CFHSI_FLUSH_FIFO			6
8240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
8340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#ifndef CFHSI_INACTIVITY_TOUT
8440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#define CFHSI_INACTIVITY_TOUT			(1 * HZ)
8540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#endif /* CFHSI_INACTIVITY_TOUT */
8640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
87687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#ifndef CFHSI_WAKE_TOUT
88687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#define CFHSI_WAKE_TOUT			(3 * HZ)
89687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#endif /* CFHSI_WAKE_TOUT */
9040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
91687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#ifndef CFHSI_MAX_RX_RETRIES
92687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#define CFHSI_MAX_RX_RETRIES		(10 * HZ)
93687b13e98addc99644002703944ec89e94287cb6Daniel Martensson#endif
9440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
9540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Structure implemented by the CAIF HSI driver. */
9640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyaginstruct cfhsi_drv {
9740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	void (*tx_done_cb) (struct cfhsi_drv *drv);
9840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	void (*rx_done_cb) (struct cfhsi_drv *drv);
9940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	void (*wake_up_cb) (struct cfhsi_drv *drv);
10040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	void (*wake_down_cb) (struct cfhsi_drv *drv);
10140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin};
10240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
10340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Structure implemented by HSI device. */
10440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyaginstruct cfhsi_dev {
10540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_up) (struct cfhsi_dev *dev);
10640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_down) (struct cfhsi_dev *dev);
10740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_dev *dev);
10840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev);
10940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_wake_up) (struct cfhsi_dev *dev);
11040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_wake_down) (struct cfhsi_dev *dev);
1115ea2ef5f8b006ff9e970327e7fea78f1f5841c44Daniel Martensson	int (*cfhsi_get_peer_wake) (struct cfhsi_dev *dev, bool *status);
11240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy);
11340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev);
11440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct cfhsi_drv *drv;
11540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin};
11640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
117687b13e98addc99644002703944ec89e94287cb6Daniel Martensson/* Structure holds status of received CAIF frames processing */
118687b13e98addc99644002703944ec89e94287cb6Daniel Martenssonstruct cfhsi_rx_state {
119687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	int state;
120687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	int nfrms;
121687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	int pld_len;
122687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	int retries;
123687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	bool piggy_desc;
124687b13e98addc99644002703944ec89e94287cb6Daniel Martensson};
125687b13e98addc99644002703944ec89e94287cb6Daniel Martensson
12640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin/* Structure implemented by CAIF HSI drivers. */
12740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyaginstruct cfhsi {
12840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct caif_dev_common cfdev;
12940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct net_device *ndev;
13040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct platform_device *pdev;
13140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct sk_buff_head qhead;
13240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct cfhsi_drv drv;
13340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct cfhsi_dev *dev;
13440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int tx_state;
135687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	struct cfhsi_rx_state rx_state;
13628bd2049428202cb3bc982536ed3de3c69ae120aDmitry Tarnyagin	unsigned long inactivity_timeout;
13740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int rx_len;
13840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 *rx_ptr;
13940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 *tx_buf;
14040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u8 *rx_buf;
141332ad43f19848ed653a5e44afa8e2f4a7d34ed44sjur.brandeland@stericsson.com	u8 *rx_flip_buf;
14240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	spinlock_t lock;
14340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	int flow_off_sent;
14440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u32 q_low_mark;
14540d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	u32 q_high_mark;
14640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct list_head list;
14740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct work_struct wake_up_work;
14840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct work_struct wake_down_work;
1495bbed92d3d8dab1f28945eec9fb15b6f50bf8669Daniel Martensson	struct work_struct out_of_sync_work;
15040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct workqueue_struct *wq;
15140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	wait_queue_head_t wake_up_wait;
15240d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	wait_queue_head_t wake_down_wait;
15340d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	wait_queue_head_t flush_fifo_wait;
15440d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	struct timer_list timer;
155687b13e98addc99644002703944ec89e94287cb6Daniel Martensson	struct timer_list rx_slowpath_timer;
15640d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin	unsigned long bits;
15740d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin};
15840d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
15940d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyaginextern struct platform_driver cfhsi_driver;
16040d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin
16140d69043fce579378eb185d31445b6ff66abbd93Dmitry.Tarnyagin#endif		/* CAIF_HSI_H_ */
162