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

dtl1_cs.c (12684B)


      1/*
      2 *
      3 *  A driver for Nokia Connectivity Card DTL-1 devices
      4 *
      5 *  Copyright (C) 2001-2002  Marcel Holtmann <marcel@holtmann.org>
      6 *
      7 *
      8 *  This program is free software; you can redistribute it and/or modify
      9 *  it under the terms of the GNU General Public License version 2 as
     10 *  published by the Free Software Foundation;
     11 *
     12 *  Software distributed under the License is distributed on an "AS
     13 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
     14 *  implied. See the License for the specific language governing
     15 *  rights and limitations under the License.
     16 *
     17 *  The initial developer of the original code is David A. Hinds
     18 *  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     19 *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
     20 *
     21 */
     22
     23#include <linux/module.h>
     24
     25#include <linux/kernel.h>
     26#include <linux/init.h>
     27#include <linux/slab.h>
     28#include <linux/types.h>
     29#include <linux/delay.h>
     30#include <linux/errno.h>
     31#include <linux/ptrace.h>
     32#include <linux/ioport.h>
     33#include <linux/spinlock.h>
     34#include <linux/moduleparam.h>
     35
     36#include <linux/skbuff.h>
     37#include <linux/string.h>
     38#include <linux/serial.h>
     39#include <linux/serial_reg.h>
     40#include <linux/bitops.h>
     41#include <asm/io.h>
     42
     43#include <pcmcia/cistpl.h>
     44#include <pcmcia/ciscode.h>
     45#include <pcmcia/ds.h>
     46#include <pcmcia/cisreg.h>
     47
     48#include <net/bluetooth/bluetooth.h>
     49#include <net/bluetooth/hci_core.h>
     50
     51
     52
     53/* ======================== Module parameters ======================== */
     54
     55
     56MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
     57MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
     58MODULE_LICENSE("GPL");
     59
     60
     61
     62/* ======================== Local structures ======================== */
     63
     64
     65struct dtl1_info {
     66	struct pcmcia_device *p_dev;
     67
     68	struct hci_dev *hdev;
     69
     70	spinlock_t lock;		/* For serializing operations */
     71
     72	unsigned long flowmask;		/* HCI flow mask */
     73	int ri_latch;
     74
     75	struct sk_buff_head txq;
     76	unsigned long tx_state;
     77
     78	unsigned long rx_state;
     79	unsigned long rx_count;
     80	struct sk_buff *rx_skb;
     81};
     82
     83
     84static int dtl1_config(struct pcmcia_device *link);
     85
     86
     87/* Transmit states  */
     88#define XMIT_SENDING  1
     89#define XMIT_WAKEUP   2
     90#define XMIT_WAITING  8
     91
     92/* Receiver States */
     93#define RECV_WAIT_NSH   0
     94#define RECV_WAIT_DATA  1
     95
     96
     97struct nsh {
     98	u8 type;
     99	u8 zero;
    100	u16 len;
    101} __packed;	/* Nokia Specific Header */
    102
    103#define NSHL  4				/* Nokia Specific Header Length */
    104
    105
    106
    107/* ======================== Interrupt handling ======================== */
    108
    109
    110static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
    111{
    112	int actual = 0;
    113
    114	/* Tx FIFO should be empty */
    115	if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
    116		return 0;
    117
    118	/* Fill FIFO with current frame */
    119	while ((fifo_size-- > 0) && (actual < len)) {
    120		/* Transmit next byte */
    121		outb(buf[actual], iobase + UART_TX);
    122		actual++;
    123	}
    124
    125	return actual;
    126}
    127
    128
    129static void dtl1_write_wakeup(struct dtl1_info *info)
    130{
    131	if (!info) {
    132		BT_ERR("Unknown device");
    133		return;
    134	}
    135
    136	if (test_bit(XMIT_WAITING, &(info->tx_state))) {
    137		set_bit(XMIT_WAKEUP, &(info->tx_state));
    138		return;
    139	}
    140
    141	if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
    142		set_bit(XMIT_WAKEUP, &(info->tx_state));
    143		return;
    144	}
    145
    146	do {
    147		unsigned int iobase = info->p_dev->resource[0]->start;
    148		register struct sk_buff *skb;
    149		int len;
    150
    151		clear_bit(XMIT_WAKEUP, &(info->tx_state));
    152
    153		if (!pcmcia_dev_present(info->p_dev))
    154			return;
    155
    156		skb = skb_dequeue(&(info->txq));
    157		if (!skb)
    158			break;
    159
    160		/* Send frame */
    161		len = dtl1_write(iobase, 32, skb->data, skb->len);
    162
    163		if (len == skb->len) {
    164			set_bit(XMIT_WAITING, &(info->tx_state));
    165			kfree_skb(skb);
    166		} else {
    167			skb_pull(skb, len);
    168			skb_queue_head(&(info->txq), skb);
    169		}
    170
    171		info->hdev->stat.byte_tx += len;
    172
    173	} while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
    174
    175	clear_bit(XMIT_SENDING, &(info->tx_state));
    176}
    177
    178
    179static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb)
    180{
    181	u8 flowmask = *(u8 *)skb->data;
    182	int i;
    183
    184	printk(KERN_INFO "Bluetooth: Nokia control data =");
    185	for (i = 0; i < skb->len; i++)
    186		printk(" %02x", skb->data[i]);
    187
    188	printk("\n");
    189
    190	/* transition to active state */
    191	if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
    192		clear_bit(XMIT_WAITING, &(info->tx_state));
    193		dtl1_write_wakeup(info);
    194	}
    195
    196	info->flowmask = flowmask;
    197
    198	kfree_skb(skb);
    199}
    200
    201
    202static void dtl1_receive(struct dtl1_info *info)
    203{
    204	unsigned int iobase;
    205	struct nsh *nsh;
    206	int boguscount = 0;
    207
    208	if (!info) {
    209		BT_ERR("Unknown device");
    210		return;
    211	}
    212
    213	iobase = info->p_dev->resource[0]->start;
    214
    215	do {
    216		info->hdev->stat.byte_rx++;
    217
    218		/* Allocate packet */
    219		if (info->rx_skb == NULL) {
    220			info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
    221			if (!info->rx_skb) {
    222				BT_ERR("Can't allocate mem for new packet");
    223				info->rx_state = RECV_WAIT_NSH;
    224				info->rx_count = NSHL;
    225				return;
    226			}
    227		}
    228
    229		skb_put_u8(info->rx_skb, inb(iobase + UART_RX));
    230		nsh = (struct nsh *)info->rx_skb->data;
    231
    232		info->rx_count--;
    233
    234		if (info->rx_count == 0) {
    235
    236			switch (info->rx_state) {
    237			case RECV_WAIT_NSH:
    238				info->rx_state = RECV_WAIT_DATA;
    239				info->rx_count = nsh->len + (nsh->len & 0x0001);
    240				break;
    241			case RECV_WAIT_DATA:
    242				hci_skb_pkt_type(info->rx_skb) = nsh->type;
    243
    244				/* remove PAD byte if it exists */
    245				if (nsh->len & 0x0001) {
    246					info->rx_skb->tail--;
    247					info->rx_skb->len--;
    248				}
    249
    250				/* remove NSH */
    251				skb_pull(info->rx_skb, NSHL);
    252
    253				switch (hci_skb_pkt_type(info->rx_skb)) {
    254				case 0x80:
    255					/* control data for the Nokia Card */
    256					dtl1_control(info, info->rx_skb);
    257					break;
    258				case 0x82:
    259				case 0x83:
    260				case 0x84:
    261					/* send frame to the HCI layer */
    262					hci_skb_pkt_type(info->rx_skb) &= 0x0f;
    263					hci_recv_frame(info->hdev, info->rx_skb);
    264					break;
    265				default:
    266					/* unknown packet */
    267					BT_ERR("Unknown HCI packet with type 0x%02x received",
    268					       hci_skb_pkt_type(info->rx_skb));
    269					kfree_skb(info->rx_skb);
    270					break;
    271				}
    272
    273				info->rx_state = RECV_WAIT_NSH;
    274				info->rx_count = NSHL;
    275				info->rx_skb = NULL;
    276				break;
    277			}
    278
    279		}
    280
    281		/* Make sure we don't stay here too long */
    282		if (boguscount++ > 32)
    283			break;
    284
    285	} while (inb(iobase + UART_LSR) & UART_LSR_DR);
    286}
    287
    288
    289static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
    290{
    291	struct dtl1_info *info = dev_inst;
    292	unsigned int iobase;
    293	unsigned char msr;
    294	int boguscount = 0;
    295	int iir, lsr;
    296	irqreturn_t r = IRQ_NONE;
    297
    298	if (!info || !info->hdev)
    299		/* our irq handler is shared */
    300		return IRQ_NONE;
    301
    302	iobase = info->p_dev->resource[0]->start;
    303
    304	spin_lock(&(info->lock));
    305
    306	iir = inb(iobase + UART_IIR) & UART_IIR_ID;
    307	while (iir) {
    308
    309		r = IRQ_HANDLED;
    310		/* Clear interrupt */
    311		lsr = inb(iobase + UART_LSR);
    312
    313		switch (iir) {
    314		case UART_IIR_RLSI:
    315			BT_ERR("RLSI");
    316			break;
    317		case UART_IIR_RDI:
    318			/* Receive interrupt */
    319			dtl1_receive(info);
    320			break;
    321		case UART_IIR_THRI:
    322			if (lsr & UART_LSR_THRE) {
    323				/* Transmitter ready for data */
    324				dtl1_write_wakeup(info);
    325			}
    326			break;
    327		default:
    328			BT_ERR("Unhandled IIR=%#x", iir);
    329			break;
    330		}
    331
    332		/* Make sure we don't stay here too long */
    333		if (boguscount++ > 100)
    334			break;
    335
    336		iir = inb(iobase + UART_IIR) & UART_IIR_ID;
    337
    338	}
    339
    340	msr = inb(iobase + UART_MSR);
    341
    342	if (info->ri_latch ^ (msr & UART_MSR_RI)) {
    343		info->ri_latch = msr & UART_MSR_RI;
    344		clear_bit(XMIT_WAITING, &(info->tx_state));
    345		dtl1_write_wakeup(info);
    346		r = IRQ_HANDLED;
    347	}
    348
    349	spin_unlock(&(info->lock));
    350
    351	return r;
    352}
    353
    354
    355
    356/* ======================== HCI interface ======================== */
    357
    358
    359static int dtl1_hci_open(struct hci_dev *hdev)
    360{
    361	return 0;
    362}
    363
    364
    365static int dtl1_hci_flush(struct hci_dev *hdev)
    366{
    367	struct dtl1_info *info = hci_get_drvdata(hdev);
    368
    369	/* Drop TX queue */
    370	skb_queue_purge(&(info->txq));
    371
    372	return 0;
    373}
    374
    375
    376static int dtl1_hci_close(struct hci_dev *hdev)
    377{
    378	dtl1_hci_flush(hdev);
    379
    380	return 0;
    381}
    382
    383
    384static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
    385{
    386	struct dtl1_info *info = hci_get_drvdata(hdev);
    387	struct sk_buff *s;
    388	struct nsh nsh;
    389
    390	switch (hci_skb_pkt_type(skb)) {
    391	case HCI_COMMAND_PKT:
    392		hdev->stat.cmd_tx++;
    393		nsh.type = 0x81;
    394		break;
    395	case HCI_ACLDATA_PKT:
    396		hdev->stat.acl_tx++;
    397		nsh.type = 0x82;
    398		break;
    399	case HCI_SCODATA_PKT:
    400		hdev->stat.sco_tx++;
    401		nsh.type = 0x83;
    402		break;
    403	default:
    404		return -EILSEQ;
    405	}
    406
    407	nsh.zero = 0;
    408	nsh.len = skb->len;
    409
    410	s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
    411	if (!s)
    412		return -ENOMEM;
    413
    414	skb_reserve(s, NSHL);
    415	skb_copy_from_linear_data(skb, skb_put(s, skb->len), skb->len);
    416	if (skb->len & 0x0001)
    417		skb_put_u8(s, 0);	/* PAD */
    418
    419	/* Prepend skb with Nokia frame header and queue */
    420	memcpy(skb_push(s, NSHL), &nsh, NSHL);
    421	skb_queue_tail(&(info->txq), s);
    422
    423	dtl1_write_wakeup(info);
    424
    425	kfree_skb(skb);
    426
    427	return 0;
    428}
    429
    430
    431
    432/* ======================== Card services HCI interaction ======================== */
    433
    434
    435static int dtl1_open(struct dtl1_info *info)
    436{
    437	unsigned long flags;
    438	unsigned int iobase = info->p_dev->resource[0]->start;
    439	struct hci_dev *hdev;
    440
    441	spin_lock_init(&(info->lock));
    442
    443	skb_queue_head_init(&(info->txq));
    444
    445	info->rx_state = RECV_WAIT_NSH;
    446	info->rx_count = NSHL;
    447	info->rx_skb = NULL;
    448
    449	set_bit(XMIT_WAITING, &(info->tx_state));
    450
    451	/* Initialize HCI device */
    452	hdev = hci_alloc_dev();
    453	if (!hdev) {
    454		BT_ERR("Can't allocate HCI device");
    455		return -ENOMEM;
    456	}
    457
    458	info->hdev = hdev;
    459
    460	hdev->bus = HCI_PCCARD;
    461	hci_set_drvdata(hdev, info);
    462	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
    463
    464	hdev->open  = dtl1_hci_open;
    465	hdev->close = dtl1_hci_close;
    466	hdev->flush = dtl1_hci_flush;
    467	hdev->send  = dtl1_hci_send_frame;
    468
    469	spin_lock_irqsave(&(info->lock), flags);
    470
    471	/* Reset UART */
    472	outb(0, iobase + UART_MCR);
    473
    474	/* Turn off interrupts */
    475	outb(0, iobase + UART_IER);
    476
    477	/* Initialize UART */
    478	outb(UART_LCR_WLEN8, iobase + UART_LCR);	/* Reset DLAB */
    479	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
    480
    481	info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
    482				& UART_MSR_RI;
    483
    484	/* Turn on interrupts */
    485	outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
    486
    487	spin_unlock_irqrestore(&(info->lock), flags);
    488
    489	/* Timeout before it is safe to send the first HCI packet */
    490	msleep(2000);
    491
    492	/* Register HCI device */
    493	if (hci_register_dev(hdev) < 0) {
    494		BT_ERR("Can't register HCI device");
    495		info->hdev = NULL;
    496		hci_free_dev(hdev);
    497		return -ENODEV;
    498	}
    499
    500	return 0;
    501}
    502
    503
    504static int dtl1_close(struct dtl1_info *info)
    505{
    506	unsigned long flags;
    507	unsigned int iobase = info->p_dev->resource[0]->start;
    508	struct hci_dev *hdev = info->hdev;
    509
    510	if (!hdev)
    511		return -ENODEV;
    512
    513	dtl1_hci_close(hdev);
    514
    515	spin_lock_irqsave(&(info->lock), flags);
    516
    517	/* Reset UART */
    518	outb(0, iobase + UART_MCR);
    519
    520	/* Turn off interrupts */
    521	outb(0, iobase + UART_IER);
    522
    523	spin_unlock_irqrestore(&(info->lock), flags);
    524
    525	hci_unregister_dev(hdev);
    526	hci_free_dev(hdev);
    527
    528	return 0;
    529}
    530
    531static int dtl1_probe(struct pcmcia_device *link)
    532{
    533	struct dtl1_info *info;
    534
    535	/* Create new info device */
    536	info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
    537	if (!info)
    538		return -ENOMEM;
    539
    540	info->p_dev = link;
    541	link->priv = info;
    542
    543	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
    544
    545	return dtl1_config(link);
    546}
    547
    548
    549static void dtl1_detach(struct pcmcia_device *link)
    550{
    551	struct dtl1_info *info = link->priv;
    552
    553	dtl1_close(info);
    554	pcmcia_disable_device(link);
    555}
    556
    557static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
    558{
    559	if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8))
    560		return -ENODEV;
    561
    562	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
    563	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
    564
    565	return pcmcia_request_io(p_dev);
    566}
    567
    568static int dtl1_config(struct pcmcia_device *link)
    569{
    570	struct dtl1_info *info = link->priv;
    571	int ret;
    572
    573	/* Look for a generic full-sized window */
    574	link->resource[0]->end = 8;
    575	ret = pcmcia_loop_config(link, dtl1_confcheck, NULL);
    576	if (ret)
    577		goto failed;
    578
    579	ret = pcmcia_request_irq(link, dtl1_interrupt);
    580	if (ret)
    581		goto failed;
    582
    583	ret = pcmcia_enable_device(link);
    584	if (ret)
    585		goto failed;
    586
    587	ret = dtl1_open(info);
    588	if (ret)
    589		goto failed;
    590
    591	return 0;
    592
    593failed:
    594	dtl1_detach(link);
    595	return ret;
    596}
    597
    598static const struct pcmcia_device_id dtl1_ids[] = {
    599	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
    600	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
    601	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
    602	PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
    603	PCMCIA_DEVICE_NULL
    604};
    605MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
    606
    607static struct pcmcia_driver dtl1_driver = {
    608	.owner		= THIS_MODULE,
    609	.name		= "dtl1_cs",
    610	.probe		= dtl1_probe,
    611	.remove		= dtl1_detach,
    612	.id_table	= dtl1_ids,
    613};
    614module_pcmcia_driver(dtl1_driver);