aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/axnet_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/axnet_cs.c')
-rw-r--r--drivers/net/pcmcia/axnet_cs.c126
1 files changed, 45 insertions, 81 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 1cc94b2d76c1..56233afcb2b3 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -86,8 +86,8 @@ static char *version =
86 86
87/*====================================================================*/ 87/*====================================================================*/
88 88
89static void axnet_config(dev_link_t *link); 89static int axnet_config(struct pcmcia_device *link);
90static void axnet_release(dev_link_t *link); 90static void axnet_release(struct pcmcia_device *link);
91static int axnet_open(struct net_device *dev); 91static int axnet_open(struct net_device *dev);
92static int axnet_close(struct net_device *dev); 92static int axnet_close(struct net_device *dev);
93static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 93static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -117,7 +117,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
117/*====================================================================*/ 117/*====================================================================*/
118 118
119typedef struct axnet_dev_t { 119typedef struct axnet_dev_t {
120 dev_link_t link; 120 struct pcmcia_device *p_dev;
121 dev_node_t node; 121 dev_node_t node;
122 caddr_t base; 122 caddr_t base;
123 struct timer_list watchdog; 123 struct timer_list watchdog;
@@ -142,10 +142,9 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
142 142
143======================================================================*/ 143======================================================================*/
144 144
145static int axnet_attach(struct pcmcia_device *p_dev) 145static int axnet_probe(struct pcmcia_device *link)
146{ 146{
147 axnet_dev_t *info; 147 axnet_dev_t *info;
148 dev_link_t *link;
149 struct net_device *dev; 148 struct net_device *dev;
150 149
151 DEBUG(0, "axnet_attach()\n"); 150 DEBUG(0, "axnet_attach()\n");
@@ -157,7 +156,7 @@ static int axnet_attach(struct pcmcia_device *p_dev)
157 return -ENOMEM; 156 return -ENOMEM;
158 157
159 info = PRIV(dev); 158 info = PRIV(dev);
160 link = &info->link; 159 info->p_dev = link;
161 link->priv = dev; 160 link->priv = dev;
162 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 161 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
163 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 162 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
@@ -169,13 +168,7 @@ static int axnet_attach(struct pcmcia_device *p_dev)
169 dev->do_ioctl = &axnet_ioctl; 168 dev->do_ioctl = &axnet_ioctl;
170 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 169 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
171 170
172 link->handle = p_dev; 171 return axnet_config(link);
173 p_dev->instance = link;
174
175 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
176 axnet_config(link);
177
178 return 0;
179} /* axnet_attach */ 172} /* axnet_attach */
180 173
181/*====================================================================== 174/*======================================================================
@@ -187,18 +180,16 @@ static int axnet_attach(struct pcmcia_device *p_dev)
187 180
188======================================================================*/ 181======================================================================*/
189 182
190static void axnet_detach(struct pcmcia_device *p_dev) 183static void axnet_detach(struct pcmcia_device *link)
191{ 184{
192 dev_link_t *link = dev_to_instance(p_dev);
193 struct net_device *dev = link->priv; 185 struct net_device *dev = link->priv;
194 186
195 DEBUG(0, "axnet_detach(0x%p)\n", link); 187 DEBUG(0, "axnet_detach(0x%p)\n", link);
196 188
197 if (link->dev) 189 if (link->dev_node)
198 unregister_netdev(dev); 190 unregister_netdev(dev);
199 191
200 if (link->state & DEV_CONFIG) 192 axnet_release(link);
201 axnet_release(link);
202 193
203 free_netdev(dev); 194 free_netdev(dev);
204} /* axnet_detach */ 195} /* axnet_detach */
@@ -209,7 +200,7 @@ static void axnet_detach(struct pcmcia_device *p_dev)
209 200
210======================================================================*/ 201======================================================================*/
211 202
212static int get_prom(dev_link_t *link) 203static int get_prom(struct pcmcia_device *link)
213{ 204{
214 struct net_device *dev = link->priv; 205 struct net_device *dev = link->priv;
215 kio_addr_t ioaddr = dev->base_addr; 206 kio_addr_t ioaddr = dev->base_addr;
@@ -263,7 +254,7 @@ static int get_prom(dev_link_t *link)
263#define CS_CHECK(fn, ret) \ 254#define CS_CHECK(fn, ret) \
264do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 255do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
265 256
266static int try_io_port(dev_link_t *link) 257static int try_io_port(struct pcmcia_device *link)
267{ 258{
268 int j, ret; 259 int j, ret;
269 if (link->io.NumPorts1 == 32) { 260 if (link->io.NumPorts1 == 32) {
@@ -284,25 +275,23 @@ static int try_io_port(dev_link_t *link)
284 for (j = 0; j < 0x400; j += 0x20) { 275 for (j = 0; j < 0x400; j += 0x20) {
285 link->io.BasePort1 = j ^ 0x300; 276 link->io.BasePort1 = j ^ 0x300;
286 link->io.BasePort2 = (j ^ 0x300) + 0x10; 277 link->io.BasePort2 = (j ^ 0x300) + 0x10;
287 ret = pcmcia_request_io(link->handle, &link->io); 278 ret = pcmcia_request_io(link, &link->io);
288 if (ret == CS_SUCCESS) return ret; 279 if (ret == CS_SUCCESS) return ret;
289 } 280 }
290 return ret; 281 return ret;
291 } else { 282 } else {
292 return pcmcia_request_io(link->handle, &link->io); 283 return pcmcia_request_io(link, &link->io);
293 } 284 }
294} 285}
295 286
296static void axnet_config(dev_link_t *link) 287static int axnet_config(struct pcmcia_device *link)
297{ 288{
298 client_handle_t handle = link->handle;
299 struct net_device *dev = link->priv; 289 struct net_device *dev = link->priv;
300 axnet_dev_t *info = PRIV(dev); 290 axnet_dev_t *info = PRIV(dev);
301 tuple_t tuple; 291 tuple_t tuple;
302 cisparse_t parse; 292 cisparse_t parse;
303 int i, j, last_ret, last_fn; 293 int i, j, last_ret, last_fn;
304 u_short buf[64]; 294 u_short buf[64];
305 config_info_t conf;
306 295
307 DEBUG(0, "axnet_config(0x%p)\n", link); 296 DEBUG(0, "axnet_config(0x%p)\n", link);
308 297
@@ -311,29 +300,22 @@ static void axnet_config(dev_link_t *link)
311 tuple.TupleDataMax = sizeof(buf); 300 tuple.TupleDataMax = sizeof(buf);
312 tuple.TupleOffset = 0; 301 tuple.TupleOffset = 0;
313 tuple.DesiredTuple = CISTPL_CONFIG; 302 tuple.DesiredTuple = CISTPL_CONFIG;
314 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 303 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
315 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 304 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
316 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 305 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
317 link->conf.ConfigBase = parse.config.base; 306 link->conf.ConfigBase = parse.config.base;
318 /* don't trust the CIS on this; Linksys got it wrong */ 307 /* don't trust the CIS on this; Linksys got it wrong */
319 link->conf.Present = 0x63; 308 link->conf.Present = 0x63;
320 309
321 /* Configure card */
322 link->state |= DEV_CONFIG;
323
324 /* Look up current Vcc */
325 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
326 link->conf.Vcc = conf.Vcc;
327
328 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 310 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
329 tuple.Attributes = 0; 311 tuple.Attributes = 0;
330 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 312 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
331 while (last_ret == CS_SUCCESS) { 313 while (last_ret == CS_SUCCESS) {
332 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 314 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
333 cistpl_io_t *io = &(parse.cftable_entry.io); 315 cistpl_io_t *io = &(parse.cftable_entry.io);
334 316
335 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 317 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
336 pcmcia_parse_tuple(handle, &tuple, &parse) != 0 || 318 pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
337 cfg->index == 0 || cfg->io.nwin == 0) 319 cfg->index == 0 || cfg->io.nwin == 0)
338 goto next_entry; 320 goto next_entry;
339 321
@@ -355,21 +337,21 @@ static void axnet_config(dev_link_t *link)
355 if (last_ret == CS_SUCCESS) break; 337 if (last_ret == CS_SUCCESS) break;
356 } 338 }
357 next_entry: 339 next_entry:
358 last_ret = pcmcia_get_next_tuple(handle, &tuple); 340 last_ret = pcmcia_get_next_tuple(link, &tuple);
359 } 341 }
360 if (last_ret != CS_SUCCESS) { 342 if (last_ret != CS_SUCCESS) {
361 cs_error(handle, RequestIO, last_ret); 343 cs_error(link, RequestIO, last_ret);
362 goto failed; 344 goto failed;
363 } 345 }
364 346
365 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 347 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
366 348
367 if (link->io.NumPorts2 == 8) { 349 if (link->io.NumPorts2 == 8) {
368 link->conf.Attributes |= CONF_ENABLE_SPKR; 350 link->conf.Attributes |= CONF_ENABLE_SPKR;
369 link->conf.Status = CCSR_AUDIO_ENA; 351 link->conf.Status = CCSR_AUDIO_ENA;
370 } 352 }
371 353
372 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 354 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
373 dev->irq = link->irq.AssignedIRQ; 355 dev->irq = link->irq.AssignedIRQ;
374 dev->base_addr = link->io.BasePort1; 356 dev->base_addr = link->io.BasePort1;
375 357
@@ -406,7 +388,7 @@ static void axnet_config(dev_link_t *link)
406 Bit 2 of CCSR is active low. */ 388 Bit 2 of CCSR is active low. */
407 if (i == 32) { 389 if (i == 32) {
408 conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 }; 390 conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
409 pcmcia_access_configuration_register(link->handle, &reg); 391 pcmcia_access_configuration_register(link, &reg);
410 for (i = 0; i < 32; i++) { 392 for (i = 0; i < 32; i++) {
411 j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); 393 j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
412 if ((j != 0) && (j != 0xffff)) break; 394 if ((j != 0) && (j != 0xffff)) break;
@@ -414,13 +396,12 @@ static void axnet_config(dev_link_t *link)
414 } 396 }
415 397
416 info->phy_id = (i < 32) ? i : -1; 398 info->phy_id = (i < 32) ? i : -1;
417 link->dev = &info->node; 399 link->dev_node = &info->node;
418 link->state &= ~DEV_CONFIG_PENDING; 400 SET_NETDEV_DEV(dev, &handle_to_dev(link));
419 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
420 401
421 if (register_netdev(dev) != 0) { 402 if (register_netdev(dev) != 0) {
422 printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); 403 printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
423 link->dev = NULL; 404 link->dev_node = NULL;
424 goto failed; 405 goto failed;
425 } 406 }
426 407
@@ -436,14 +417,13 @@ static void axnet_config(dev_link_t *link)
436 } else { 417 } else {
437 printk(KERN_NOTICE " No MII transceivers found!\n"); 418 printk(KERN_NOTICE " No MII transceivers found!\n");
438 } 419 }
439 return; 420 return 0;
440 421
441cs_failed: 422cs_failed:
442 cs_error(link->handle, last_fn, last_ret); 423 cs_error(link, last_fn, last_ret);
443failed: 424failed:
444 axnet_release(link); 425 axnet_release(link);
445 link->state &= ~DEV_CONFIG_PENDING; 426 return -ENODEV;
446 return;
447} /* axnet_config */ 427} /* axnet_config */
448 428
449/*====================================================================== 429/*======================================================================
@@ -454,45 +434,29 @@ failed:
454 434
455======================================================================*/ 435======================================================================*/
456 436
457static void axnet_release(dev_link_t *link) 437static void axnet_release(struct pcmcia_device *link)
458{ 438{
459 DEBUG(0, "axnet_release(0x%p)\n", link); 439 pcmcia_disable_device(link);
460
461 pcmcia_release_configuration(link->handle);
462 pcmcia_release_io(link->handle, &link->io);
463 pcmcia_release_irq(link->handle, &link->irq);
464
465 link->state &= ~DEV_CONFIG;
466} 440}
467 441
468static int axnet_suspend(struct pcmcia_device *p_dev) 442static int axnet_suspend(struct pcmcia_device *link)
469{ 443{
470 dev_link_t *link = dev_to_instance(p_dev);
471 struct net_device *dev = link->priv; 444 struct net_device *dev = link->priv;
472 445
473 link->state |= DEV_SUSPEND; 446 if (link->open)
474 if (link->state & DEV_CONFIG) { 447 netif_device_detach(dev);
475 if (link->open)
476 netif_device_detach(dev);
477 pcmcia_release_configuration(link->handle);
478 }
479 448
480 return 0; 449 return 0;
481} 450}
482 451
483static int axnet_resume(struct pcmcia_device *p_dev) 452static int axnet_resume(struct pcmcia_device *link)
484{ 453{
485 dev_link_t *link = dev_to_instance(p_dev);
486 struct net_device *dev = link->priv; 454 struct net_device *dev = link->priv;
487 455
488 link->state &= ~DEV_SUSPEND; 456 if (link->open) {
489 if (link->state & DEV_CONFIG) { 457 axnet_reset_8390(dev);
490 pcmcia_request_configuration(link->handle, &link->conf); 458 AX88190_init(dev, 1);
491 if (link->open) { 459 netif_device_attach(dev);
492 axnet_reset_8390(dev);
493 AX88190_init(dev, 1);
494 netif_device_attach(dev);
495 }
496 } 460 }
497 461
498 return 0; 462 return 0;
@@ -562,11 +526,11 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
562static int axnet_open(struct net_device *dev) 526static int axnet_open(struct net_device *dev)
563{ 527{
564 axnet_dev_t *info = PRIV(dev); 528 axnet_dev_t *info = PRIV(dev);
565 dev_link_t *link = &info->link; 529 struct pcmcia_device *link = info->p_dev;
566 530
567 DEBUG(2, "axnet_open('%s')\n", dev->name); 531 DEBUG(2, "axnet_open('%s')\n", dev->name);
568 532
569 if (!DEV_OK(link)) 533 if (!pcmcia_dev_present(link))
570 return -ENODEV; 534 return -ENODEV;
571 535
572 link->open++; 536 link->open++;
@@ -588,7 +552,7 @@ static int axnet_open(struct net_device *dev)
588static int axnet_close(struct net_device *dev) 552static int axnet_close(struct net_device *dev)
589{ 553{
590 axnet_dev_t *info = PRIV(dev); 554 axnet_dev_t *info = PRIV(dev);
591 dev_link_t *link = &info->link; 555 struct pcmcia_device *link = info->p_dev;
592 556
593 DEBUG(2, "axnet_close('%s')\n", dev->name); 557 DEBUG(2, "axnet_close('%s')\n", dev->name);
594 558
@@ -833,7 +797,7 @@ static struct pcmcia_driver axnet_cs_driver = {
833 .drv = { 797 .drv = {
834 .name = "axnet_cs", 798 .name = "axnet_cs",
835 }, 799 },
836 .probe = axnet_attach, 800 .probe = axnet_probe,
837 .remove = axnet_detach, 801 .remove = axnet_detach,
838 .id_table = axnet_ids, 802 .id_table = axnet_ids,
839 .suspend = axnet_suspend, 803 .suspend = axnet_suspend,