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

pcmcia_cis.c (12984B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * PCMCIA high-level CIS access functions
      4 *
      5 * The initial developer of the original code is David A. Hinds
      6 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
      7 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
      8 *
      9 * Copyright (C) 1999	     David A. Hinds
     10 * Copyright (C) 2004-2010   Dominik Brodowski
     11 */
     12
     13#include <linux/slab.h>
     14#include <linux/module.h>
     15#include <linux/kernel.h>
     16#include <linux/netdevice.h>
     17#include <linux/etherdevice.h>
     18
     19#include <pcmcia/cisreg.h>
     20#include <pcmcia/cistpl.h>
     21#include <pcmcia/ss.h>
     22#include <pcmcia/ds.h>
     23#include "cs_internal.h"
     24
     25
     26/**
     27 * pccard_read_tuple() - internal CIS tuple access
     28 * @s:		the struct pcmcia_socket where the card is inserted
     29 * @function:	the device function we loop for
     30 * @code:	which CIS code shall we look for?
     31 * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
     32 *
     33 * pccard_read_tuple() reads out one tuple and attempts to parse it
     34 */
     35int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
     36		cisdata_t code, void *parse)
     37{
     38	tuple_t tuple;
     39	cisdata_t *buf;
     40	int ret;
     41
     42	buf = kmalloc(256, GFP_KERNEL);
     43	if (buf == NULL) {
     44		dev_warn(&s->dev, "no memory to read tuple\n");
     45		return -ENOMEM;
     46	}
     47	tuple.DesiredTuple = code;
     48	tuple.Attributes = 0;
     49	if (function == BIND_FN_ALL)
     50		tuple.Attributes = TUPLE_RETURN_COMMON;
     51	ret = pccard_get_first_tuple(s, function, &tuple);
     52	if (ret != 0)
     53		goto done;
     54	tuple.TupleData = buf;
     55	tuple.TupleOffset = 0;
     56	tuple.TupleDataMax = 255;
     57	ret = pccard_get_tuple_data(s, &tuple);
     58	if (ret != 0)
     59		goto done;
     60	ret = pcmcia_parse_tuple(&tuple, parse);
     61done:
     62	kfree(buf);
     63	return ret;
     64}
     65
     66
     67/**
     68 * pccard_loop_tuple() - loop over tuples in the CIS
     69 * @s:		the struct pcmcia_socket where the card is inserted
     70 * @function:	the device function we loop for
     71 * @code:	which CIS code shall we look for?
     72 * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
     73 * @priv_data:	private data to be passed to the loop_tuple function.
     74 * @loop_tuple:	function to call for each CIS entry of type @function. IT
     75 *		gets passed the raw tuple, the paresed tuple (if @parse is
     76 *		set) and @priv_data.
     77 *
     78 * pccard_loop_tuple() loops over all CIS entries of type @function, and
     79 * calls the @loop_tuple function for each entry. If the call to @loop_tuple
     80 * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
     81 */
     82static int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
     83			     cisdata_t code, cisparse_t *parse, void *priv_data,
     84			     int (*loop_tuple) (tuple_t *tuple,
     85					 cisparse_t *parse,
     86					 void *priv_data))
     87{
     88	tuple_t tuple;
     89	cisdata_t *buf;
     90	int ret;
     91
     92	buf = kzalloc(256, GFP_KERNEL);
     93	if (buf == NULL) {
     94		dev_warn(&s->dev, "no memory to read tuple\n");
     95		return -ENOMEM;
     96	}
     97
     98	tuple.TupleData = buf;
     99	tuple.TupleDataMax = 255;
    100	tuple.TupleOffset = 0;
    101	tuple.DesiredTuple = code;
    102	tuple.Attributes = 0;
    103
    104	ret = pccard_get_first_tuple(s, function, &tuple);
    105	while (!ret) {
    106		if (pccard_get_tuple_data(s, &tuple))
    107			goto next_entry;
    108
    109		if (parse)
    110			if (pcmcia_parse_tuple(&tuple, parse))
    111				goto next_entry;
    112
    113		ret = loop_tuple(&tuple, parse, priv_data);
    114		if (!ret)
    115			break;
    116
    117next_entry:
    118		ret = pccard_get_next_tuple(s, function, &tuple);
    119	}
    120
    121	kfree(buf);
    122	return ret;
    123}
    124
    125
    126/*
    127 * pcmcia_io_cfg_data_width() - convert cfgtable to data path width parameter
    128 */
    129static int pcmcia_io_cfg_data_width(unsigned int flags)
    130{
    131	if (!(flags & CISTPL_IO_8BIT))
    132		return IO_DATA_PATH_WIDTH_16;
    133	if (!(flags & CISTPL_IO_16BIT))
    134		return IO_DATA_PATH_WIDTH_8;
    135	return IO_DATA_PATH_WIDTH_AUTO;
    136}
    137
    138
    139struct pcmcia_cfg_mem {
    140	struct pcmcia_device *p_dev;
    141	int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data);
    142	void *priv_data;
    143	cisparse_t parse;
    144	cistpl_cftable_entry_t dflt;
    145};
    146
    147/*
    148 * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
    149 *
    150 * pcmcia_do_loop_config() is the internal callback for the call from
    151 * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
    152 * by a struct pcmcia_cfg_mem.
    153 */
    154static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
    155{
    156	struct pcmcia_cfg_mem *cfg_mem = priv;
    157	struct pcmcia_device *p_dev = cfg_mem->p_dev;
    158	cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
    159	cistpl_cftable_entry_t *dflt = &cfg_mem->dflt;
    160	unsigned int flags = p_dev->config_flags;
    161	unsigned int vcc = p_dev->socket->socket.Vcc;
    162
    163	dev_dbg(&p_dev->dev, "testing configuration %x, autoconf %x\n",
    164		cfg->index, flags);
    165
    166	/* default values */
    167	cfg_mem->p_dev->config_index = cfg->index;
    168	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
    169		cfg_mem->dflt = *cfg;
    170
    171	/* check for matching Vcc? */
    172	if (flags & CONF_AUTO_CHECK_VCC) {
    173		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
    174			if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
    175				return -ENODEV;
    176		} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
    177			if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
    178				return -ENODEV;
    179		}
    180	}
    181
    182	/* set Vpp? */
    183	if (flags & CONF_AUTO_SET_VPP) {
    184		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
    185			p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
    186		else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
    187			p_dev->vpp =
    188				dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
    189	}
    190
    191	/* enable audio? */
    192	if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO))
    193		p_dev->config_flags |= CONF_ENABLE_SPKR;
    194
    195
    196	/* IO window settings? */
    197	if (flags & CONF_AUTO_SET_IO) {
    198		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
    199		int i = 0;
    200
    201		p_dev->resource[0]->start = p_dev->resource[0]->end = 0;
    202		p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
    203		if (io->nwin == 0)
    204			return -ENODEV;
    205
    206		p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
    207		p_dev->resource[0]->flags |=
    208					pcmcia_io_cfg_data_width(io->flags);
    209		if (io->nwin > 1) {
    210			/* For multifunction cards, by convention, we
    211			 * configure the network function with window 0,
    212			 * and serial with window 1 */
    213			i = (io->win[1].len > io->win[0].len);
    214			p_dev->resource[1]->flags = p_dev->resource[0]->flags;
    215			p_dev->resource[1]->start = io->win[1-i].base;
    216			p_dev->resource[1]->end = io->win[1-i].len;
    217		}
    218		p_dev->resource[0]->start = io->win[i].base;
    219		p_dev->resource[0]->end = io->win[i].len;
    220		p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
    221	}
    222
    223	/* MEM window settings? */
    224	if (flags & CONF_AUTO_SET_IOMEM) {
    225		/* so far, we only set one memory window */
    226		cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
    227
    228		p_dev->resource[2]->start = p_dev->resource[2]->end = 0;
    229		if (mem->nwin == 0)
    230			return -ENODEV;
    231
    232		p_dev->resource[2]->start = mem->win[0].host_addr;
    233		p_dev->resource[2]->end = mem->win[0].len;
    234		if (p_dev->resource[2]->end < 0x1000)
    235			p_dev->resource[2]->end = 0x1000;
    236		p_dev->card_addr = mem->win[0].card_addr;
    237	}
    238
    239	dev_dbg(&p_dev->dev,
    240		"checking configuration %x: %pr %pr %pr (%d lines)\n",
    241		p_dev->config_index, p_dev->resource[0], p_dev->resource[1],
    242		p_dev->resource[2], p_dev->io_lines);
    243
    244	return cfg_mem->conf_check(p_dev, cfg_mem->priv_data);
    245}
    246
    247/**
    248 * pcmcia_loop_config() - loop over configuration options
    249 * @p_dev:	the struct pcmcia_device which we need to loop for.
    250 * @conf_check:	function to call for each configuration option.
    251 *		It gets passed the struct pcmcia_device and private data
    252 *		being passed to pcmcia_loop_config()
    253 * @priv_data:	private data to be passed to the conf_check function.
    254 *
    255 * pcmcia_loop_config() loops over all configuration options, and calls
    256 * the driver-specific conf_check() for each one, checking whether
    257 * it is a valid one. Returns 0 on success or errorcode otherwise.
    258 */
    259int pcmcia_loop_config(struct pcmcia_device *p_dev,
    260		       int	(*conf_check)	(struct pcmcia_device *p_dev,
    261						 void *priv_data),
    262		       void *priv_data)
    263{
    264	struct pcmcia_cfg_mem *cfg_mem;
    265	int ret;
    266
    267	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
    268	if (cfg_mem == NULL)
    269		return -ENOMEM;
    270
    271	cfg_mem->p_dev = p_dev;
    272	cfg_mem->conf_check = conf_check;
    273	cfg_mem->priv_data = priv_data;
    274
    275	ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
    276				CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
    277				cfg_mem, pcmcia_do_loop_config);
    278
    279	kfree(cfg_mem);
    280	return ret;
    281}
    282EXPORT_SYMBOL(pcmcia_loop_config);
    283
    284
    285struct pcmcia_loop_mem {
    286	struct pcmcia_device *p_dev;
    287	void *priv_data;
    288	int (*loop_tuple) (struct pcmcia_device *p_dev,
    289			   tuple_t *tuple,
    290			   void *priv_data);
    291};
    292
    293/*
    294 * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
    295 *
    296 * pcmcia_do_loop_tuple() is the internal callback for the call from
    297 * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
    298 * by a struct pcmcia_cfg_mem.
    299 */
    300static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
    301{
    302	struct pcmcia_loop_mem *loop = priv;
    303
    304	return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
    305};
    306
    307/**
    308 * pcmcia_loop_tuple() - loop over tuples in the CIS
    309 * @p_dev:	the struct pcmcia_device which we need to loop for.
    310 * @code:	which CIS code shall we look for?
    311 * @priv_data:	private data to be passed to the loop_tuple function.
    312 * @loop_tuple:	function to call for each CIS entry of type @function. IT
    313 *		gets passed the raw tuple and @priv_data.
    314 *
    315 * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
    316 * calls the @loop_tuple function for each entry. If the call to @loop_tuple
    317 * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
    318 */
    319int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
    320		      int (*loop_tuple) (struct pcmcia_device *p_dev,
    321					 tuple_t *tuple,
    322					 void *priv_data),
    323		      void *priv_data)
    324{
    325	struct pcmcia_loop_mem loop = {
    326		.p_dev = p_dev,
    327		.loop_tuple = loop_tuple,
    328		.priv_data = priv_data};
    329
    330	return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
    331				 &loop, pcmcia_do_loop_tuple);
    332}
    333EXPORT_SYMBOL(pcmcia_loop_tuple);
    334
    335
    336struct pcmcia_loop_get {
    337	size_t len;
    338	cisdata_t **buf;
    339};
    340
    341/*
    342 * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
    343 *
    344 * pcmcia_do_get_tuple() is the internal callback for the call from
    345 * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
    346 * the first tuple, return 0 unconditionally. Create a memory buffer large
    347 * enough to hold the content of the tuple, and fill it with the tuple data.
    348 * The caller is responsible to free the buffer.
    349 */
    350static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
    351			       void *priv)
    352{
    353	struct pcmcia_loop_get *get = priv;
    354
    355	*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
    356	if (*get->buf) {
    357		get->len = tuple->TupleDataLen;
    358		memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
    359	} else
    360		dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
    361	return 0;
    362}
    363
    364/**
    365 * pcmcia_get_tuple() - get first tuple from CIS
    366 * @p_dev:	the struct pcmcia_device which we need to loop for.
    367 * @code:	which CIS code shall we look for?
    368 * @buf:        pointer to store the buffer to.
    369 *
    370 * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
    371 * It returns the buffer length (or zero). The caller is responsible to free
    372 * the buffer passed in @buf.
    373 */
    374size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
    375			unsigned char **buf)
    376{
    377	struct pcmcia_loop_get get = {
    378		.len = 0,
    379		.buf = buf,
    380	};
    381
    382	*get.buf = NULL;
    383	pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
    384
    385	return get.len;
    386}
    387EXPORT_SYMBOL(pcmcia_get_tuple);
    388
    389#ifdef CONFIG_NET
    390/*
    391 * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
    392 *
    393 * pcmcia_do_get_mac() is the internal callback for the call from
    394 * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
    395 * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
    396 * to struct net_device->dev_addr[i].
    397 */
    398static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
    399			     void *priv)
    400{
    401	struct net_device *dev = priv;
    402
    403	if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
    404		return -EINVAL;
    405	if (tuple->TupleDataLen < ETH_ALEN + 2) {
    406		dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
    407			"LAN_NODE_ID\n");
    408		return -EINVAL;
    409	}
    410
    411	if (tuple->TupleData[1] != ETH_ALEN) {
    412		dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
    413		return -EINVAL;
    414	}
    415	eth_hw_addr_set(dev, &tuple->TupleData[2]);
    416	return 0;
    417}
    418
    419/**
    420 * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
    421 * @p_dev:	the struct pcmcia_device for which we want the address.
    422 * @dev:	a properly prepared struct net_device to store the info to.
    423 *
    424 * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
    425 * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
    426 * must be set up properly by the driver (see examples!).
    427 */
    428int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
    429{
    430	return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
    431}
    432EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
    433
    434#endif /* CONFIG_NET */