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

mantis_ca.c (5140B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3	Mantis PCI bridge driver
      4
      5	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
      6
      7*/
      8
      9#include <linux/signal.h>
     10#include <linux/slab.h>
     11#include <linux/sched.h>
     12#include <linux/interrupt.h>
     13#include <asm/io.h>
     14
     15#include <media/dmxdev.h>
     16#include <media/dvbdev.h>
     17#include <media/dvb_demux.h>
     18#include <media/dvb_frontend.h>
     19#include <media/dvb_net.h>
     20
     21#include "mantis_common.h"
     22#include "mantis_link.h"
     23#include "mantis_hif.h"
     24#include "mantis_reg.h"
     25
     26#include "mantis_ca.h"
     27
     28static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
     29{
     30	struct mantis_ca *ca = en50221->data;
     31	struct mantis_pci *mantis = ca->ca_priv;
     32
     33	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
     34
     35	if (slot != 0)
     36		return -EINVAL;
     37
     38	return mantis_hif_read_mem(ca, addr);
     39}
     40
     41static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
     42{
     43	struct mantis_ca *ca = en50221->data;
     44	struct mantis_pci *mantis = ca->ca_priv;
     45
     46	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
     47
     48	if (slot != 0)
     49		return -EINVAL;
     50
     51	return mantis_hif_write_mem(ca, addr, data);
     52}
     53
     54static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
     55{
     56	struct mantis_ca *ca = en50221->data;
     57	struct mantis_pci *mantis = ca->ca_priv;
     58
     59	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
     60
     61	if (slot != 0)
     62		return -EINVAL;
     63
     64	return mantis_hif_read_iom(ca, addr);
     65}
     66
     67static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
     68{
     69	struct mantis_ca *ca = en50221->data;
     70	struct mantis_pci *mantis = ca->ca_priv;
     71
     72	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
     73
     74	if (slot != 0)
     75		return -EINVAL;
     76
     77	return mantis_hif_write_iom(ca, addr, data);
     78}
     79
     80static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
     81{
     82	struct mantis_ca *ca = en50221->data;
     83	struct mantis_pci *mantis = ca->ca_priv;
     84
     85	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
     86	udelay(500); /* Wait.. */
     87	mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
     88	udelay(500);
     89	mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
     90	msleep(1000);
     91	dvb_ca_en50221_camready_irq(&ca->en50221, 0);
     92
     93	return 0;
     94}
     95
     96static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
     97{
     98	struct mantis_ca *ca = en50221->data;
     99	struct mantis_pci *mantis = ca->ca_priv;
    100
    101	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
    102
    103	return 0;
    104}
    105
    106static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
    107{
    108	struct mantis_ca *ca = en50221->data;
    109	struct mantis_pci *mantis = ca->ca_priv;
    110
    111	dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
    112
    113	return 0;
    114}
    115
    116static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
    117{
    118	struct mantis_ca *ca = en50221->data;
    119	struct mantis_pci *mantis = ca->ca_priv;
    120
    121	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
    122
    123	if (ca->slot_state == MODULE_INSERTED) {
    124		dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
    125		return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
    126	} else {
    127		dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
    128	}
    129
    130	return 0;
    131}
    132
    133int mantis_ca_init(struct mantis_pci *mantis)
    134{
    135	struct dvb_adapter *dvb_adapter	= &mantis->dvb_adapter;
    136	struct mantis_ca *ca;
    137	int ca_flags = 0, result;
    138
    139	dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
    140	ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
    141	if (!ca) {
    142		dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
    143		result = -ENOMEM;
    144		goto err;
    145	}
    146
    147	ca->ca_priv		= mantis;
    148	mantis->mantis_ca	= ca;
    149	ca_flags		= DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
    150	/* register CA interface */
    151	ca->en50221.owner		= THIS_MODULE;
    152	ca->en50221.read_attribute_mem	= mantis_ca_read_attr_mem;
    153	ca->en50221.write_attribute_mem	= mantis_ca_write_attr_mem;
    154	ca->en50221.read_cam_control	= mantis_ca_read_cam_ctl;
    155	ca->en50221.write_cam_control	= mantis_ca_write_cam_ctl;
    156	ca->en50221.slot_reset		= mantis_ca_slot_reset;
    157	ca->en50221.slot_shutdown	= mantis_ca_slot_shutdown;
    158	ca->en50221.slot_ts_enable	= mantis_ts_control;
    159	ca->en50221.poll_slot_status	= mantis_slot_status;
    160	ca->en50221.data		= ca;
    161
    162	mutex_init(&ca->ca_lock);
    163
    164	init_waitqueue_head(&ca->hif_data_wq);
    165	init_waitqueue_head(&ca->hif_opdone_wq);
    166	init_waitqueue_head(&ca->hif_write_wq);
    167
    168	dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
    169	result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
    170	if (result != 0) {
    171		dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
    172		goto err;
    173	}
    174	dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
    175	mantis_evmgr_init(ca);
    176	return 0;
    177err:
    178	kfree(ca);
    179	return result;
    180}
    181EXPORT_SYMBOL_GPL(mantis_ca_init);
    182
    183void mantis_ca_exit(struct mantis_pci *mantis)
    184{
    185	struct mantis_ca *ca = mantis->mantis_ca;
    186
    187	dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
    188	if (!ca)
    189		return;
    190
    191	mantis_evmgr_exit(ca);
    192	dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
    193	dvb_ca_en50221_release(&ca->en50221);
    194
    195	kfree(ca);
    196}
    197EXPORT_SYMBOL_GPL(mantis_ca_exit);