Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at c9a28fa7b9ac19b676deefa0a171ce7df8755c08 1077 lines 22 kB view raw
1/* 2 * linux/drivers/net/wireless/libertas/if_sdio.c 3 * 4 * Copyright 2007 Pierre Ossman 5 * 6 * Inspired by if_cs.c, Copyright 2007 Holger Schurig 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This hardware has more or less no CMD53 support, so all registers 14 * must be accessed using sdio_readb()/sdio_writeb(). 15 * 16 * Transfers must be in one transaction or the firmware goes bonkers. 17 * This means that the transfer must either be small enough to do a 18 * byte based transfer or it must be padded to a multiple of the 19 * current block size. 20 * 21 * As SDIO is still new to the kernel, it is unfortunately common with 22 * bugs in the host controllers related to that. One such bug is that 23 * controllers cannot do transfers that aren't a multiple of 4 bytes. 24 * If you don't have time to fix the host controller driver, you can 25 * work around the problem by modifying if_sdio_host_to_card() and 26 * if_sdio_card_to_host() to pad the data. 27 */ 28 29#include <linux/moduleparam.h> 30#include <linux/firmware.h> 31#include <linux/netdevice.h> 32#include <linux/delay.h> 33#include <linux/mmc/card.h> 34#include <linux/mmc/sdio_func.h> 35#include <linux/mmc/sdio_ids.h> 36 37#include "host.h" 38#include "decl.h" 39#include "defs.h" 40#include "dev.h" 41#include "if_sdio.h" 42 43static char *lbs_helper_name = NULL; 44module_param_named(helper_name, lbs_helper_name, charp, 0644); 45 46static char *lbs_fw_name = NULL; 47module_param_named(fw_name, lbs_fw_name, charp, 0644); 48 49static const struct sdio_device_id if_sdio_ids[] = { 50 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, 51 { /* end: all zeroes */ }, 52}; 53 54MODULE_DEVICE_TABLE(sdio, if_sdio_ids); 55 56struct if_sdio_model { 57 int model; 58 const char *helper; 59 const char *firmware; 60}; 61 62static struct if_sdio_model if_sdio_models[] = { 63 { 64 /* 8385 */ 65 .model = 0x04, 66 .helper = "sd8385_helper.bin", 67 .firmware = "sd8385.bin", 68 }, 69 { 70 /* 8686 */ 71 .model = 0x0B, 72 .helper = "sd8686_helper.bin", 73 .firmware = "sd8686.bin", 74 }, 75}; 76 77struct if_sdio_packet { 78 struct if_sdio_packet *next; 79 u16 nb; 80 u8 buffer[0] __attribute__((aligned(4))); 81}; 82 83struct if_sdio_card { 84 struct sdio_func *func; 85 struct lbs_private *priv; 86 87 int model; 88 unsigned long ioport; 89 90 const char *helper; 91 const char *firmware; 92 93 u8 buffer[65536]; 94 u8 int_cause; 95 u32 event; 96 97 spinlock_t lock; 98 struct if_sdio_packet *packets; 99 struct work_struct packet_worker; 100}; 101 102/********************************************************************/ 103/* I/O */ 104/********************************************************************/ 105 106static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err) 107{ 108 int ret, reg; 109 u16 scratch; 110 111 if (card->model == 0x04) 112 reg = IF_SDIO_SCRATCH_OLD; 113 else 114 reg = IF_SDIO_SCRATCH; 115 116 scratch = sdio_readb(card->func, reg, &ret); 117 if (!ret) 118 scratch |= sdio_readb(card->func, reg + 1, &ret) << 8; 119 120 if (err) 121 *err = ret; 122 123 if (ret) 124 return 0xffff; 125 126 return scratch; 127} 128 129static int if_sdio_handle_cmd(struct if_sdio_card *card, 130 u8 *buffer, unsigned size) 131{ 132 int ret; 133 unsigned long flags; 134 135 lbs_deb_enter(LBS_DEB_SDIO); 136 137 spin_lock_irqsave(&card->priv->driver_lock, flags); 138 139 if (size > LBS_CMD_BUFFER_SIZE) { 140 lbs_deb_sdio("response packet too large (%d bytes)\n", 141 (int)size); 142 ret = -E2BIG; 143 goto out; 144 } 145 146 memcpy(card->priv->upld_buf, buffer, size); 147 card->priv->upld_len = size; 148 149 card->int_cause |= MRVDRV_CMD_UPLD_RDY; 150 151 lbs_interrupt(card->priv); 152 153 ret = 0; 154 155out: 156 spin_unlock_irqrestore(&card->priv->driver_lock, flags); 157 158 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 159 160 return ret; 161} 162 163static int if_sdio_handle_data(struct if_sdio_card *card, 164 u8 *buffer, unsigned size) 165{ 166 int ret; 167 struct sk_buff *skb; 168 char *data; 169 170 lbs_deb_enter(LBS_DEB_SDIO); 171 172 if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { 173 lbs_deb_sdio("response packet too large (%d bytes)\n", 174 (int)size); 175 ret = -E2BIG; 176 goto out; 177 } 178 179 skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN); 180 if (!skb) { 181 ret = -ENOMEM; 182 goto out; 183 } 184 185 skb_reserve(skb, NET_IP_ALIGN); 186 187 data = skb_put(skb, size); 188 189 memcpy(data, buffer, size); 190 191 lbs_process_rxed_packet(card->priv, skb); 192 193 ret = 0; 194 195out: 196 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 197 198 return ret; 199} 200 201static int if_sdio_handle_event(struct if_sdio_card *card, 202 u8 *buffer, unsigned size) 203{ 204 int ret; 205 unsigned long flags; 206 u32 event; 207 208 lbs_deb_enter(LBS_DEB_SDIO); 209 210 if (card->model == 0x04) { 211 event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); 212 if (ret) 213 goto out; 214 } else { 215 if (size < 4) { 216 lbs_deb_sdio("event packet too small (%d bytes)\n", 217 (int)size); 218 ret = -EINVAL; 219 goto out; 220 } 221 event = buffer[3] << 24; 222 event |= buffer[2] << 16; 223 event |= buffer[1] << 8; 224 event |= buffer[0] << 0; 225 event <<= SBI_EVENT_CAUSE_SHIFT; 226 } 227 228 spin_lock_irqsave(&card->priv->driver_lock, flags); 229 230 card->event = event; 231 card->int_cause |= MRVDRV_CARDEVENT; 232 233 lbs_interrupt(card->priv); 234 235 spin_unlock_irqrestore(&card->priv->driver_lock, flags); 236 237 ret = 0; 238 239out: 240 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 241 242 return ret; 243} 244 245static int if_sdio_card_to_host(struct if_sdio_card *card) 246{ 247 int ret; 248 u8 status; 249 u16 size, type, chunk; 250 unsigned long timeout; 251 252 lbs_deb_enter(LBS_DEB_SDIO); 253 254 size = if_sdio_read_scratch(card, &ret); 255 if (ret) 256 goto out; 257 258 if (size < 4) { 259 lbs_deb_sdio("invalid packet size (%d bytes) from firmware\n", 260 (int)size); 261 ret = -EINVAL; 262 goto out; 263 } 264 265 timeout = jiffies + HZ; 266 while (1) { 267 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 268 if (ret) 269 goto out; 270 if (status & IF_SDIO_IO_RDY) 271 break; 272 if (time_after(jiffies, timeout)) { 273 ret = -ETIMEDOUT; 274 goto out; 275 } 276 mdelay(1); 277 } 278 279 /* 280 * The transfer must be in one transaction or the firmware 281 * goes suicidal. 282 */ 283 chunk = size; 284 if ((chunk > card->func->cur_blksize) || (chunk > 512)) { 285 chunk = (chunk + card->func->cur_blksize - 1) / 286 card->func->cur_blksize * card->func->cur_blksize; 287 } 288 289 ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk); 290 if (ret) 291 goto out; 292 293 chunk = card->buffer[0] | (card->buffer[1] << 8); 294 type = card->buffer[2] | (card->buffer[3] << 8); 295 296 lbs_deb_sdio("packet of type %d and size %d bytes\n", 297 (int)type, (int)chunk); 298 299 if (chunk > size) { 300 lbs_deb_sdio("packet fragment (%d > %d)\n", 301 (int)chunk, (int)size); 302 ret = -EINVAL; 303 goto out; 304 } 305 306 if (chunk < size) { 307 lbs_deb_sdio("packet fragment (%d < %d)\n", 308 (int)chunk, (int)size); 309 } 310 311 switch (type) { 312 case MVMS_CMD: 313 ret = if_sdio_handle_cmd(card, card->buffer + 4, chunk - 4); 314 if (ret) 315 goto out; 316 break; 317 case MVMS_DAT: 318 ret = if_sdio_handle_data(card, card->buffer + 4, chunk - 4); 319 if (ret) 320 goto out; 321 break; 322 case MVMS_EVENT: 323 ret = if_sdio_handle_event(card, card->buffer + 4, chunk - 4); 324 if (ret) 325 goto out; 326 break; 327 default: 328 lbs_deb_sdio("invalid type (%d) from firmware\n", 329 (int)type); 330 ret = -EINVAL; 331 goto out; 332 } 333 334out: 335 if (ret) 336 lbs_pr_err("problem fetching packet from firmware\n"); 337 338 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 339 340 return ret; 341} 342 343static void if_sdio_host_to_card_worker(struct work_struct *work) 344{ 345 struct if_sdio_card *card; 346 struct if_sdio_packet *packet; 347 unsigned long timeout; 348 u8 status; 349 int ret; 350 unsigned long flags; 351 352 lbs_deb_enter(LBS_DEB_SDIO); 353 354 card = container_of(work, struct if_sdio_card, packet_worker); 355 356 while (1) { 357 spin_lock_irqsave(&card->lock, flags); 358 packet = card->packets; 359 if (packet) 360 card->packets = packet->next; 361 spin_unlock_irqrestore(&card->lock, flags); 362 363 if (!packet) 364 break; 365 366 sdio_claim_host(card->func); 367 368 timeout = jiffies + HZ; 369 while (1) { 370 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 371 if (ret) 372 goto release; 373 if (status & IF_SDIO_IO_RDY) 374 break; 375 if (time_after(jiffies, timeout)) { 376 ret = -ETIMEDOUT; 377 goto release; 378 } 379 mdelay(1); 380 } 381 382 ret = sdio_writesb(card->func, card->ioport, 383 packet->buffer, packet->nb); 384 if (ret) 385 goto release; 386release: 387 sdio_release_host(card->func); 388 389 kfree(packet); 390 } 391 392 lbs_deb_leave(LBS_DEB_SDIO); 393} 394 395/********************************************************************/ 396/* Firmware */ 397/********************************************************************/ 398 399static int if_sdio_prog_helper(struct if_sdio_card *card) 400{ 401 int ret; 402 u8 status; 403 const struct firmware *fw; 404 unsigned long timeout; 405 u8 *chunk_buffer; 406 u32 chunk_size; 407 u8 *firmware; 408 size_t size; 409 410 lbs_deb_enter(LBS_DEB_SDIO); 411 412 ret = request_firmware(&fw, card->helper, &card->func->dev); 413 if (ret) { 414 lbs_pr_err("can't load helper firmware\n"); 415 goto out; 416 } 417 418 chunk_buffer = kzalloc(64, GFP_KERNEL); 419 if (!chunk_buffer) { 420 ret = -ENOMEM; 421 goto release_fw; 422 } 423 424 sdio_claim_host(card->func); 425 426 ret = sdio_set_block_size(card->func, 32); 427 if (ret) 428 goto release; 429 430 firmware = fw->data; 431 size = fw->size; 432 433 while (size) { 434 timeout = jiffies + HZ; 435 while (1) { 436 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 437 if (ret) 438 goto release; 439 if ((status & IF_SDIO_IO_RDY) && 440 (status & IF_SDIO_DL_RDY)) 441 break; 442 if (time_after(jiffies, timeout)) { 443 ret = -ETIMEDOUT; 444 goto release; 445 } 446 mdelay(1); 447 } 448 449 chunk_size = min(size, (size_t)60); 450 451 *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size); 452 memcpy(chunk_buffer + 4, firmware, chunk_size); 453/* 454 lbs_deb_sdio("sending %d bytes chunk\n", chunk_size); 455*/ 456 ret = sdio_writesb(card->func, card->ioport, 457 chunk_buffer, 64); 458 if (ret) 459 goto release; 460 461 firmware += chunk_size; 462 size -= chunk_size; 463 } 464 465 /* an empty block marks the end of the transfer */ 466 memset(chunk_buffer, 0, 4); 467 ret = sdio_writesb(card->func, card->ioport, chunk_buffer, 64); 468 if (ret) 469 goto release; 470 471 lbs_deb_sdio("waiting for helper to boot...\n"); 472 473 /* wait for the helper to boot by looking at the size register */ 474 timeout = jiffies + HZ; 475 while (1) { 476 u16 req_size; 477 478 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); 479 if (ret) 480 goto release; 481 482 req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; 483 if (ret) 484 goto release; 485 486 if (req_size != 0) 487 break; 488 489 if (time_after(jiffies, timeout)) { 490 ret = -ETIMEDOUT; 491 goto release; 492 } 493 494 msleep(10); 495 } 496 497 ret = 0; 498 499release: 500 sdio_set_block_size(card->func, 0); 501 sdio_release_host(card->func); 502 kfree(chunk_buffer); 503release_fw: 504 release_firmware(fw); 505 506out: 507 if (ret) 508 lbs_pr_err("failed to load helper firmware\n"); 509 510 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 511 512 return ret; 513} 514 515static int if_sdio_prog_real(struct if_sdio_card *card) 516{ 517 int ret; 518 u8 status; 519 const struct firmware *fw; 520 unsigned long timeout; 521 u8 *chunk_buffer; 522 u32 chunk_size; 523 u8 *firmware; 524 size_t size, req_size; 525 526 lbs_deb_enter(LBS_DEB_SDIO); 527 528 ret = request_firmware(&fw, card->firmware, &card->func->dev); 529 if (ret) { 530 lbs_pr_err("can't load firmware\n"); 531 goto out; 532 } 533 534 chunk_buffer = kzalloc(512, GFP_KERNEL); 535 if (!chunk_buffer) { 536 ret = -ENOMEM; 537 goto release_fw; 538 } 539 540 sdio_claim_host(card->func); 541 542 ret = sdio_set_block_size(card->func, 32); 543 if (ret) 544 goto release; 545 546 firmware = fw->data; 547 size = fw->size; 548 549 while (size) { 550 timeout = jiffies + HZ; 551 while (1) { 552 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 553 if (ret) 554 goto release; 555 if ((status & IF_SDIO_IO_RDY) && 556 (status & IF_SDIO_DL_RDY)) 557 break; 558 if (time_after(jiffies, timeout)) { 559 ret = -ETIMEDOUT; 560 goto release; 561 } 562 mdelay(1); 563 } 564 565 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); 566 if (ret) 567 goto release; 568 569 req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; 570 if (ret) 571 goto release; 572/* 573 lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); 574*/ 575 if (req_size == 0) { 576 lbs_deb_sdio("firmware helper gave up early\n"); 577 ret = -EIO; 578 goto release; 579 } 580 581 if (req_size & 0x01) { 582 lbs_deb_sdio("firmware helper signalled error\n"); 583 ret = -EIO; 584 goto release; 585 } 586 587 if (req_size > size) 588 req_size = size; 589 590 while (req_size) { 591 chunk_size = min(req_size, (size_t)512); 592 593 memcpy(chunk_buffer, firmware, chunk_size); 594/* 595 lbs_deb_sdio("sending %d bytes (%d bytes) chunk\n", 596 chunk_size, (chunk_size + 31) / 32 * 32); 597*/ 598 ret = sdio_writesb(card->func, card->ioport, 599 chunk_buffer, (chunk_size + 31) / 32 * 32); 600 if (ret) 601 goto release; 602 603 firmware += chunk_size; 604 size -= chunk_size; 605 req_size -= chunk_size; 606 } 607 } 608 609 ret = 0; 610 611 lbs_deb_sdio("waiting for firmware to boot...\n"); 612 613 /* wait for the firmware to boot */ 614 timeout = jiffies + HZ; 615 while (1) { 616 u16 scratch; 617 618 scratch = if_sdio_read_scratch(card, &ret); 619 if (ret) 620 goto release; 621 622 if (scratch == IF_SDIO_FIRMWARE_OK) 623 break; 624 625 if (time_after(jiffies, timeout)) { 626 ret = -ETIMEDOUT; 627 goto release; 628 } 629 630 msleep(10); 631 } 632 633 ret = 0; 634 635release: 636 sdio_set_block_size(card->func, 0); 637 sdio_release_host(card->func); 638 kfree(chunk_buffer); 639release_fw: 640 release_firmware(fw); 641 642out: 643 if (ret) 644 lbs_pr_err("failed to load firmware\n"); 645 646 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 647 648 return ret; 649} 650 651static int if_sdio_prog_firmware(struct if_sdio_card *card) 652{ 653 int ret; 654 u16 scratch; 655 656 lbs_deb_enter(LBS_DEB_SDIO); 657 658 sdio_claim_host(card->func); 659 scratch = if_sdio_read_scratch(card, &ret); 660 sdio_release_host(card->func); 661 662 if (ret) 663 goto out; 664 665 if (scratch == IF_SDIO_FIRMWARE_OK) { 666 lbs_deb_sdio("firmware already loaded\n"); 667 goto success; 668 } 669 670 ret = if_sdio_prog_helper(card); 671 if (ret) 672 goto out; 673 674 ret = if_sdio_prog_real(card); 675 if (ret) 676 goto out; 677 678success: 679 ret = 0; 680 681out: 682 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 683 684 return ret; 685} 686 687/*******************************************************************/ 688/* Libertas callbacks */ 689/*******************************************************************/ 690 691static int if_sdio_host_to_card(struct lbs_private *priv, 692 u8 type, u8 *buf, u16 nb) 693{ 694 int ret; 695 struct if_sdio_card *card; 696 struct if_sdio_packet *packet, *cur; 697 u16 size; 698 unsigned long flags; 699 700 lbs_deb_enter_args(LBS_DEB_SDIO, "type %d, bytes %d", type, nb); 701 702 card = priv->card; 703 704 if (nb > (65536 - sizeof(struct if_sdio_packet) - 4)) { 705 ret = -EINVAL; 706 goto out; 707 } 708 709 /* 710 * The transfer must be in one transaction or the firmware 711 * goes suicidal. 712 */ 713 size = nb + 4; 714 if ((size > card->func->cur_blksize) || (size > 512)) { 715 size = (size + card->func->cur_blksize - 1) / 716 card->func->cur_blksize * card->func->cur_blksize; 717 } 718 719 packet = kzalloc(sizeof(struct if_sdio_packet) + size, 720 GFP_ATOMIC); 721 if (!packet) { 722 ret = -ENOMEM; 723 goto out; 724 } 725 726 packet->next = NULL; 727 packet->nb = size; 728 729 /* 730 * SDIO specific header. 731 */ 732 packet->buffer[0] = (nb + 4) & 0xff; 733 packet->buffer[1] = ((nb + 4) >> 8) & 0xff; 734 packet->buffer[2] = type; 735 packet->buffer[3] = 0; 736 737 memcpy(packet->buffer + 4, buf, nb); 738 739 spin_lock_irqsave(&card->lock, flags); 740 741 if (!card->packets) 742 card->packets = packet; 743 else { 744 cur = card->packets; 745 while (cur->next) 746 cur = cur->next; 747 cur->next = packet; 748 } 749 750 switch (type) { 751 case MVMS_CMD: 752 priv->dnld_sent = DNLD_CMD_SENT; 753 break; 754 case MVMS_DAT: 755 priv->dnld_sent = DNLD_DATA_SENT; 756 break; 757 default: 758 lbs_deb_sdio("unknown packet type %d\n", (int)type); 759 } 760 761 spin_unlock_irqrestore(&card->lock, flags); 762 763 schedule_work(&card->packet_worker); 764 765 ret = 0; 766 767out: 768 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 769 770 return ret; 771} 772 773static int if_sdio_get_int_status(struct lbs_private *priv, u8 *ireg) 774{ 775 struct if_sdio_card *card; 776 777 lbs_deb_enter(LBS_DEB_SDIO); 778 779 card = priv->card; 780 781 *ireg = card->int_cause; 782 card->int_cause = 0; 783 784 lbs_deb_leave(LBS_DEB_SDIO); 785 786 return 0; 787} 788 789static int if_sdio_read_event_cause(struct lbs_private *priv) 790{ 791 struct if_sdio_card *card; 792 793 lbs_deb_enter(LBS_DEB_SDIO); 794 795 card = priv->card; 796 797 priv->eventcause = card->event; 798 799 lbs_deb_leave(LBS_DEB_SDIO); 800 801 return 0; 802} 803 804/*******************************************************************/ 805/* SDIO callbacks */ 806/*******************************************************************/ 807 808static void if_sdio_interrupt(struct sdio_func *func) 809{ 810 int ret; 811 struct if_sdio_card *card; 812 u8 cause; 813 814 lbs_deb_enter(LBS_DEB_SDIO); 815 816 card = sdio_get_drvdata(func); 817 818 cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret); 819 if (ret) 820 goto out; 821 822 lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause); 823 824 sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret); 825 if (ret) 826 goto out; 827 828 /* 829 * Ignore the define name, this really means the card has 830 * successfully received the command. 831 */ 832 if (cause & IF_SDIO_H_INT_DNLD) 833 lbs_host_to_card_done(card->priv); 834 835 836 if (cause & IF_SDIO_H_INT_UPLD) { 837 ret = if_sdio_card_to_host(card); 838 if (ret) 839 goto out; 840 } 841 842 ret = 0; 843 844out: 845 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 846} 847 848static int if_sdio_probe(struct sdio_func *func, 849 const struct sdio_device_id *id) 850{ 851 struct if_sdio_card *card; 852 struct lbs_private *priv; 853 int ret, i; 854 unsigned int model; 855 struct if_sdio_packet *packet; 856 857 lbs_deb_enter(LBS_DEB_SDIO); 858 859 for (i = 0;i < func->card->num_info;i++) { 860 if (sscanf(func->card->info[i], 861 "802.11 SDIO ID: %x", &model) == 1) 862 break; 863 if (sscanf(func->card->info[i], 864 "ID: %x", &model) == 1) 865 break; 866 if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { 867 model = 4; 868 break; 869 } 870 } 871 872 if (i == func->card->num_info) { 873 lbs_pr_err("unable to identify card model\n"); 874 return -ENODEV; 875 } 876 877 card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL); 878 if (!card) 879 return -ENOMEM; 880 881 card->func = func; 882 card->model = model; 883 spin_lock_init(&card->lock); 884 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); 885 886 for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { 887 if (card->model == if_sdio_models[i].model) 888 break; 889 } 890 891 if (i == ARRAY_SIZE(if_sdio_models)) { 892 lbs_pr_err("unkown card model 0x%x\n", card->model); 893 ret = -ENODEV; 894 goto free; 895 } 896 897 card->helper = if_sdio_models[i].helper; 898 card->firmware = if_sdio_models[i].firmware; 899 900 if (lbs_helper_name) { 901 lbs_deb_sdio("overriding helper firmware: %s\n", 902 lbs_helper_name); 903 card->helper = lbs_helper_name; 904 } 905 906 if (lbs_fw_name) { 907 lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); 908 card->firmware = lbs_fw_name; 909 } 910 911 sdio_claim_host(func); 912 913 ret = sdio_enable_func(func); 914 if (ret) 915 goto release; 916 917 ret = sdio_claim_irq(func, if_sdio_interrupt); 918 if (ret) 919 goto disable; 920 921 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); 922 if (ret) 923 goto release_int; 924 925 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8; 926 if (ret) 927 goto release_int; 928 929 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16; 930 if (ret) 931 goto release_int; 932 933 sdio_release_host(func); 934 935 sdio_set_drvdata(func, card); 936 937 lbs_deb_sdio("class = 0x%X, vendor = 0x%X, " 938 "device = 0x%X, model = 0x%X, ioport = 0x%X\n", 939 func->class, func->vendor, func->device, 940 model, (unsigned)card->ioport); 941 942 ret = if_sdio_prog_firmware(card); 943 if (ret) 944 goto reclaim; 945 946 priv = lbs_add_card(card, &func->dev); 947 if (!priv) { 948 ret = -ENOMEM; 949 goto reclaim; 950 } 951 952 card->priv = priv; 953 954 priv->card = card; 955 priv->hw_host_to_card = if_sdio_host_to_card; 956 priv->hw_get_int_status = if_sdio_get_int_status; 957 priv->hw_read_event_cause = if_sdio_read_event_cause; 958 959 priv->fw_ready = 1; 960 961 /* 962 * Enable interrupts now that everything is set up 963 */ 964 sdio_claim_host(func); 965 sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); 966 sdio_release_host(func); 967 if (ret) 968 goto reclaim; 969 970 ret = lbs_start_card(priv); 971 if (ret) 972 goto err_activate_card; 973 974out: 975 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 976 977 return ret; 978 979err_activate_card: 980 flush_scheduled_work(); 981 free_netdev(priv->dev); 982 kfree(priv); 983reclaim: 984 sdio_claim_host(func); 985release_int: 986 sdio_release_irq(func); 987disable: 988 sdio_disable_func(func); 989release: 990 sdio_release_host(func); 991free: 992 while (card->packets) { 993 packet = card->packets; 994 card->packets = card->packets->next; 995 kfree(packet); 996 } 997 998 kfree(card); 999 1000 goto out; 1001} 1002 1003static void if_sdio_remove(struct sdio_func *func) 1004{ 1005 struct if_sdio_card *card; 1006 struct if_sdio_packet *packet; 1007 1008 lbs_deb_enter(LBS_DEB_SDIO); 1009 1010 card = sdio_get_drvdata(func); 1011 1012 card->priv->surpriseremoved = 1; 1013 1014 lbs_deb_sdio("call remove card\n"); 1015 lbs_stop_card(card->priv); 1016 lbs_remove_card(card->priv); 1017 1018 flush_scheduled_work(); 1019 1020 sdio_claim_host(func); 1021 sdio_release_irq(func); 1022 sdio_disable_func(func); 1023 sdio_release_host(func); 1024 1025 while (card->packets) { 1026 packet = card->packets; 1027 card->packets = card->packets->next; 1028 kfree(packet); 1029 } 1030 1031 kfree(card); 1032 1033 lbs_deb_leave(LBS_DEB_SDIO); 1034} 1035 1036static struct sdio_driver if_sdio_driver = { 1037 .name = "libertas_sdio", 1038 .id_table = if_sdio_ids, 1039 .probe = if_sdio_probe, 1040 .remove = if_sdio_remove, 1041}; 1042 1043/*******************************************************************/ 1044/* Module functions */ 1045/*******************************************************************/ 1046 1047static int __init if_sdio_init_module(void) 1048{ 1049 int ret = 0; 1050 1051 lbs_deb_enter(LBS_DEB_SDIO); 1052 1053 printk(KERN_INFO "libertas_sdio: Libertas SDIO driver\n"); 1054 printk(KERN_INFO "libertas_sdio: Copyright Pierre Ossman\n"); 1055 1056 ret = sdio_register_driver(&if_sdio_driver); 1057 1058 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 1059 1060 return ret; 1061} 1062 1063static void __exit if_sdio_exit_module(void) 1064{ 1065 lbs_deb_enter(LBS_DEB_SDIO); 1066 1067 sdio_unregister_driver(&if_sdio_driver); 1068 1069 lbs_deb_leave(LBS_DEB_SDIO); 1070} 1071 1072module_init(if_sdio_init_module); 1073module_exit(if_sdio_exit_module); 1074 1075MODULE_DESCRIPTION("Libertas SDIO WLAN Driver"); 1076MODULE_AUTHOR("Pierre Ossman"); 1077MODULE_LICENSE("GPL");