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 */