Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * PCMCIA high-level CIS access functions
0004  *
0005  * The initial developer of the original code is David A. Hinds
0006  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
0007  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
0008  *
0009  * Copyright (C) 1999        David A. Hinds
0010  * Copyright (C) 2004-2010   Dominik Brodowski
0011  */
0012 
0013 #include <linux/slab.h>
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/netdevice.h>
0017 #include <linux/etherdevice.h>
0018 
0019 #include <pcmcia/cisreg.h>
0020 #include <pcmcia/cistpl.h>
0021 #include <pcmcia/ss.h>
0022 #include <pcmcia/ds.h>
0023 #include "cs_internal.h"
0024 
0025 
0026 /**
0027  * pccard_read_tuple() - internal CIS tuple access
0028  * @s:      the struct pcmcia_socket where the card is inserted
0029  * @function:   the device function we loop for
0030  * @code:   which CIS code shall we look for?
0031  * @parse:  buffer where the tuple shall be parsed (or NULL, if no parse)
0032  *
0033  * pccard_read_tuple() reads out one tuple and attempts to parse it
0034  */
0035 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
0036         cisdata_t code, void *parse)
0037 {
0038     tuple_t tuple;
0039     cisdata_t *buf;
0040     int ret;
0041 
0042     buf = kmalloc(256, GFP_KERNEL);
0043     if (buf == NULL) {
0044         dev_warn(&s->dev, "no memory to read tuple\n");
0045         return -ENOMEM;
0046     }
0047     tuple.DesiredTuple = code;
0048     tuple.Attributes = 0;
0049     if (function == BIND_FN_ALL)
0050         tuple.Attributes = TUPLE_RETURN_COMMON;
0051     ret = pccard_get_first_tuple(s, function, &tuple);
0052     if (ret != 0)
0053         goto done;
0054     tuple.TupleData = buf;
0055     tuple.TupleOffset = 0;
0056     tuple.TupleDataMax = 255;
0057     ret = pccard_get_tuple_data(s, &tuple);
0058     if (ret != 0)
0059         goto done;
0060     ret = pcmcia_parse_tuple(&tuple, parse);
0061 done:
0062     kfree(buf);
0063     return ret;
0064 }
0065 
0066 
0067 /**
0068  * pccard_loop_tuple() - loop over tuples in the CIS
0069  * @s:      the struct pcmcia_socket where the card is inserted
0070  * @function:   the device function we loop for
0071  * @code:   which CIS code shall we look for?
0072  * @parse:  buffer where the tuple shall be parsed (or NULL, if no parse)
0073  * @priv_data:  private data to be passed to the loop_tuple function.
0074  * @loop_tuple: function to call for each CIS entry of type @function. IT
0075  *      gets passed the raw tuple, the paresed tuple (if @parse is
0076  *      set) and @priv_data.
0077  *
0078  * pccard_loop_tuple() loops over all CIS entries of type @function, and
0079  * calls the @loop_tuple function for each entry. If the call to @loop_tuple
0080  * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
0081  */
0082 static int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
0083                  cisdata_t code, cisparse_t *parse, void *priv_data,
0084                  int (*loop_tuple) (tuple_t *tuple,
0085                      cisparse_t *parse,
0086                      void *priv_data))
0087 {
0088     tuple_t tuple;
0089     cisdata_t *buf;
0090     int ret;
0091 
0092     buf = kzalloc(256, GFP_KERNEL);
0093     if (buf == NULL) {
0094         dev_warn(&s->dev, "no memory to read tuple\n");
0095         return -ENOMEM;
0096     }
0097 
0098     tuple.TupleData = buf;
0099     tuple.TupleDataMax = 255;
0100     tuple.TupleOffset = 0;
0101     tuple.DesiredTuple = code;
0102     tuple.Attributes = 0;
0103 
0104     ret = pccard_get_first_tuple(s, function, &tuple);
0105     while (!ret) {
0106         if (pccard_get_tuple_data(s, &tuple))
0107             goto next_entry;
0108 
0109         if (parse)
0110             if (pcmcia_parse_tuple(&tuple, parse))
0111                 goto next_entry;
0112 
0113         ret = loop_tuple(&tuple, parse, priv_data);
0114         if (!ret)
0115             break;
0116 
0117 next_entry:
0118         ret = pccard_get_next_tuple(s, function, &tuple);
0119     }
0120 
0121     kfree(buf);
0122     return ret;
0123 }
0124 
0125 
0126 /*
0127  * pcmcia_io_cfg_data_width() - convert cfgtable to data path width parameter
0128  */
0129 static int pcmcia_io_cfg_data_width(unsigned int flags)
0130 {
0131     if (!(flags & CISTPL_IO_8BIT))
0132         return IO_DATA_PATH_WIDTH_16;
0133     if (!(flags & CISTPL_IO_16BIT))
0134         return IO_DATA_PATH_WIDTH_8;
0135     return IO_DATA_PATH_WIDTH_AUTO;
0136 }
0137 
0138 
0139 struct pcmcia_cfg_mem {
0140     struct pcmcia_device *p_dev;
0141     int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data);
0142     void *priv_data;
0143     cisparse_t parse;
0144     cistpl_cftable_entry_t dflt;
0145 };
0146 
0147 /*
0148  * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
0149  *
0150  * pcmcia_do_loop_config() is the internal callback for the call from
0151  * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
0152  * by a struct pcmcia_cfg_mem.
0153  */
0154 static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
0155 {
0156     struct pcmcia_cfg_mem *cfg_mem = priv;
0157     struct pcmcia_device *p_dev = cfg_mem->p_dev;
0158     cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
0159     cistpl_cftable_entry_t *dflt = &cfg_mem->dflt;
0160     unsigned int flags = p_dev->config_flags;
0161     unsigned int vcc = p_dev->socket->socket.Vcc;
0162 
0163     dev_dbg(&p_dev->dev, "testing configuration %x, autoconf %x\n",
0164         cfg->index, flags);
0165 
0166     /* default values */
0167     cfg_mem->p_dev->config_index = cfg->index;
0168     if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
0169         cfg_mem->dflt = *cfg;
0170 
0171     /* check for matching Vcc? */
0172     if (flags & CONF_AUTO_CHECK_VCC) {
0173         if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
0174             if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
0175                 return -ENODEV;
0176         } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
0177             if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
0178                 return -ENODEV;
0179         }
0180     }
0181 
0182     /* set Vpp? */
0183     if (flags & CONF_AUTO_SET_VPP) {
0184         if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
0185             p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
0186         else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
0187             p_dev->vpp =
0188                 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
0189     }
0190 
0191     /* enable audio? */
0192     if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO))
0193         p_dev->config_flags |= CONF_ENABLE_SPKR;
0194 
0195 
0196     /* IO window settings? */
0197     if (flags & CONF_AUTO_SET_IO) {
0198         cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
0199         int i = 0;
0200 
0201         p_dev->resource[0]->start = p_dev->resource[0]->end = 0;
0202         p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
0203         if (io->nwin == 0)
0204             return -ENODEV;
0205 
0206         p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
0207         p_dev->resource[0]->flags |=
0208                     pcmcia_io_cfg_data_width(io->flags);
0209         if (io->nwin > 1) {
0210             /* For multifunction cards, by convention, we
0211              * configure the network function with window 0,
0212              * and serial with window 1 */
0213             i = (io->win[1].len > io->win[0].len);
0214             p_dev->resource[1]->flags = p_dev->resource[0]->flags;
0215             p_dev->resource[1]->start = io->win[1-i].base;
0216             p_dev->resource[1]->end = io->win[1-i].len;
0217         }
0218         p_dev->resource[0]->start = io->win[i].base;
0219         p_dev->resource[0]->end = io->win[i].len;
0220         p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
0221     }
0222 
0223     /* MEM window settings? */
0224     if (flags & CONF_AUTO_SET_IOMEM) {
0225         /* so far, we only set one memory window */
0226         cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
0227 
0228         p_dev->resource[2]->start = p_dev->resource[2]->end = 0;
0229         if (mem->nwin == 0)
0230             return -ENODEV;
0231 
0232         p_dev->resource[2]->start = mem->win[0].host_addr;
0233         p_dev->resource[2]->end = mem->win[0].len;
0234         if (p_dev->resource[2]->end < 0x1000)
0235             p_dev->resource[2]->end = 0x1000;
0236         p_dev->card_addr = mem->win[0].card_addr;
0237     }
0238 
0239     dev_dbg(&p_dev->dev,
0240         "checking configuration %x: %pr %pr %pr (%d lines)\n",
0241         p_dev->config_index, p_dev->resource[0], p_dev->resource[1],
0242         p_dev->resource[2], p_dev->io_lines);
0243 
0244     return cfg_mem->conf_check(p_dev, cfg_mem->priv_data);
0245 }
0246 
0247 /**
0248  * pcmcia_loop_config() - loop over configuration options
0249  * @p_dev:  the struct pcmcia_device which we need to loop for.
0250  * @conf_check: function to call for each configuration option.
0251  *      It gets passed the struct pcmcia_device and private data
0252  *      being passed to pcmcia_loop_config()
0253  * @priv_data:  private data to be passed to the conf_check function.
0254  *
0255  * pcmcia_loop_config() loops over all configuration options, and calls
0256  * the driver-specific conf_check() for each one, checking whether
0257  * it is a valid one. Returns 0 on success or errorcode otherwise.
0258  */
0259 int pcmcia_loop_config(struct pcmcia_device *p_dev,
0260                int  (*conf_check)   (struct pcmcia_device *p_dev,
0261                          void *priv_data),
0262                void *priv_data)
0263 {
0264     struct pcmcia_cfg_mem *cfg_mem;
0265     int ret;
0266 
0267     cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
0268     if (cfg_mem == NULL)
0269         return -ENOMEM;
0270 
0271     cfg_mem->p_dev = p_dev;
0272     cfg_mem->conf_check = conf_check;
0273     cfg_mem->priv_data = priv_data;
0274 
0275     ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
0276                 CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
0277                 cfg_mem, pcmcia_do_loop_config);
0278 
0279     kfree(cfg_mem);
0280     return ret;
0281 }
0282 EXPORT_SYMBOL(pcmcia_loop_config);
0283 
0284 
0285 struct pcmcia_loop_mem {
0286     struct pcmcia_device *p_dev;
0287     void *priv_data;
0288     int (*loop_tuple) (struct pcmcia_device *p_dev,
0289                tuple_t *tuple,
0290                void *priv_data);
0291 };
0292 
0293 /*
0294  * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
0295  *
0296  * pcmcia_do_loop_tuple() is the internal callback for the call from
0297  * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
0298  * by a struct pcmcia_cfg_mem.
0299  */
0300 static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
0301 {
0302     struct pcmcia_loop_mem *loop = priv;
0303 
0304     return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
0305 };
0306 
0307 /**
0308  * pcmcia_loop_tuple() - loop over tuples in the CIS
0309  * @p_dev:  the struct pcmcia_device which we need to loop for.
0310  * @code:   which CIS code shall we look for?
0311  * @priv_data:  private data to be passed to the loop_tuple function.
0312  * @loop_tuple: function to call for each CIS entry of type @function. IT
0313  *      gets passed the raw tuple and @priv_data.
0314  *
0315  * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
0316  * calls the @loop_tuple function for each entry. If the call to @loop_tuple
0317  * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
0318  */
0319 int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
0320               int (*loop_tuple) (struct pcmcia_device *p_dev,
0321                      tuple_t *tuple,
0322                      void *priv_data),
0323               void *priv_data)
0324 {
0325     struct pcmcia_loop_mem loop = {
0326         .p_dev = p_dev,
0327         .loop_tuple = loop_tuple,
0328         .priv_data = priv_data};
0329 
0330     return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
0331                  &loop, pcmcia_do_loop_tuple);
0332 }
0333 EXPORT_SYMBOL(pcmcia_loop_tuple);
0334 
0335 
0336 struct pcmcia_loop_get {
0337     size_t len;
0338     cisdata_t **buf;
0339 };
0340 
0341 /*
0342  * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
0343  *
0344  * pcmcia_do_get_tuple() is the internal callback for the call from
0345  * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
0346  * the first tuple, return 0 unconditionally. Create a memory buffer large
0347  * enough to hold the content of the tuple, and fill it with the tuple data.
0348  * The caller is responsible to free the buffer.
0349  */
0350 static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
0351                    void *priv)
0352 {
0353     struct pcmcia_loop_get *get = priv;
0354 
0355     *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
0356     if (*get->buf) {
0357         get->len = tuple->TupleDataLen;
0358         memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
0359     } else
0360         dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
0361     return 0;
0362 }
0363 
0364 /**
0365  * pcmcia_get_tuple() - get first tuple from CIS
0366  * @p_dev:  the struct pcmcia_device which we need to loop for.
0367  * @code:   which CIS code shall we look for?
0368  * @buf:        pointer to store the buffer to.
0369  *
0370  * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
0371  * It returns the buffer length (or zero). The caller is responsible to free
0372  * the buffer passed in @buf.
0373  */
0374 size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
0375             unsigned char **buf)
0376 {
0377     struct pcmcia_loop_get get = {
0378         .len = 0,
0379         .buf = buf,
0380     };
0381 
0382     *get.buf = NULL;
0383     pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
0384 
0385     return get.len;
0386 }
0387 EXPORT_SYMBOL(pcmcia_get_tuple);
0388 
0389 #ifdef CONFIG_NET
0390 /*
0391  * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
0392  *
0393  * pcmcia_do_get_mac() is the internal callback for the call from
0394  * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
0395  * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
0396  * to struct net_device->dev_addr[i].
0397  */
0398 static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
0399                  void *priv)
0400 {
0401     struct net_device *dev = priv;
0402 
0403     if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
0404         return -EINVAL;
0405     if (tuple->TupleDataLen < ETH_ALEN + 2) {
0406         dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
0407             "LAN_NODE_ID\n");
0408         return -EINVAL;
0409     }
0410 
0411     if (tuple->TupleData[1] != ETH_ALEN) {
0412         dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
0413         return -EINVAL;
0414     }
0415     eth_hw_addr_set(dev, &tuple->TupleData[2]);
0416     return 0;
0417 }
0418 
0419 /**
0420  * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
0421  * @p_dev:  the struct pcmcia_device for which we want the address.
0422  * @dev:    a properly prepared struct net_device to store the info to.
0423  *
0424  * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
0425  * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
0426  * must be set up properly by the driver (see examples!).
0427  */
0428 int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
0429 {
0430     return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
0431 }
0432 EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
0433 
0434 #endif /* CONFIG_NET */