1#include <linux/completion.h> 2#include "wilc_wlan_if.h" 3#include "wilc_wlan.h" 4#include "wilc_wfi_netdevice.h" 5#include "wilc_wlan_cfg.h" 6 7static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP; 8 9static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire) 10{ 11 mutex_lock(&wilc->hif_cs); 12 if (acquire == ACQUIRE_AND_WAKEUP) 13 chip_wakeup(wilc); 14} 15 16static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release) 17{ 18 if (release == RELEASE_ALLOW_SLEEP) 19 chip_allow_sleep(wilc); 20 mutex_unlock(&wilc->hif_cs); 21} 22 23static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe) 24{ 25 if (tqe == wilc->txq_head) { 26 wilc->txq_head = tqe->next; 27 if (wilc->txq_head) 28 wilc->txq_head->prev = NULL; 29 } else if (tqe == wilc->txq_tail) { 30 wilc->txq_tail = (tqe->prev); 31 if (wilc->txq_tail) 32 wilc->txq_tail->next = NULL; 33 } else { 34 tqe->prev->next = tqe->next; 35 tqe->next->prev = tqe->prev; 36 } 37 wilc->txq_entries -= 1; 38} 39 40static struct txq_entry_t * 41wilc_wlan_txq_remove_from_head(struct net_device *dev) 42{ 43 struct txq_entry_t *tqe; 44 unsigned long flags; 45 struct wilc_vif *vif; 46 struct wilc *wilc; 47 48 vif = netdev_priv(dev); 49 wilc = vif->wilc; 50 51 spin_lock_irqsave(&wilc->txq_spinlock, flags); 52 if (wilc->txq_head) { 53 tqe = wilc->txq_head; 54 wilc->txq_head = tqe->next; 55 if (wilc->txq_head) 56 wilc->txq_head->prev = NULL; 57 58 wilc->txq_entries -= 1; 59 } else { 60 tqe = NULL; 61 } 62 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 63 return tqe; 64} 65 66static void wilc_wlan_txq_add_to_tail(struct net_device *dev, 67 struct txq_entry_t *tqe) 68{ 69 unsigned long flags; 70 struct wilc_vif *vif; 71 struct wilc *wilc; 72 73 vif = netdev_priv(dev); 74 wilc = vif->wilc; 75 76 spin_lock_irqsave(&wilc->txq_spinlock, flags); 77 78 if (!wilc->txq_head) { 79 tqe->next = NULL; 80 tqe->prev = NULL; 81 wilc->txq_head = tqe; 82 wilc->txq_tail = tqe; 83 } else { 84 tqe->next = NULL; 85 tqe->prev = wilc->txq_tail; 86 wilc->txq_tail->next = tqe; 87 wilc->txq_tail = tqe; 88 } 89 wilc->txq_entries += 1; 90 91 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 92 93 complete(&wilc->txq_event); 94} 95 96static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif, 97 struct txq_entry_t *tqe) 98{ 99 unsigned long flags; 100 struct wilc *wilc = vif->wilc; 101 102 mutex_lock(&wilc->txq_add_to_head_cs); 103 104 spin_lock_irqsave(&wilc->txq_spinlock, flags); 105 106 if (!wilc->txq_head) { 107 tqe->next = NULL; 108 tqe->prev = NULL; 109 wilc->txq_head = tqe; 110 wilc->txq_tail = tqe; 111 } else { 112 tqe->next = wilc->txq_head; 113 tqe->prev = NULL; 114 wilc->txq_head->prev = tqe; 115 wilc->txq_head = tqe; 116 } 117 wilc->txq_entries += 1; 118 119 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 120 mutex_unlock(&wilc->txq_add_to_head_cs); 121 complete(&wilc->txq_event); 122 123 return 0; 124} 125 126struct ack_session_info; 127struct ack_session_info { 128 u32 seq_num; 129 u32 bigger_ack_num; 130 u16 src_port; 131 u16 dst_port; 132 u16 status; 133}; 134 135struct pending_acks_info { 136 u32 ack_num; 137 u32 session_index; 138 struct txq_entry_t *txqe; 139}; 140 141#define NOT_TCP_ACK (-1) 142 143#define MAX_TCP_SESSION 25 144#define MAX_PENDING_ACKS 256 145static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; 146static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; 147 148static u32 pending_base; 149static u32 tcp_session; 150static u32 pending_acks; 151 152static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) 153{ 154 if (tcp_session < 2 * MAX_TCP_SESSION) { 155 ack_session_info[tcp_session].seq_num = seq; 156 ack_session_info[tcp_session].bigger_ack_num = 0; 157 ack_session_info[tcp_session].src_port = src_prt; 158 ack_session_info[tcp_session].dst_port = dst_prt; 159 tcp_session++; 160 } 161 return 0; 162} 163 164static inline int update_tcp_session(u32 index, u32 ack) 165{ 166 if (index < 2 * MAX_TCP_SESSION && 167 ack > ack_session_info[index].bigger_ack_num) 168 ack_session_info[index].bigger_ack_num = ack; 169 return 0; 170} 171 172static inline int add_tcp_pending_ack(u32 ack, u32 session_index, 173 struct txq_entry_t *txqe) 174{ 175 if (pending_base + pending_acks < MAX_PENDING_ACKS) { 176 pending_acks_info[pending_base + pending_acks].ack_num = ack; 177 pending_acks_info[pending_base + pending_acks].txqe = txqe; 178 pending_acks_info[pending_base + pending_acks].session_index = session_index; 179 txqe->tcp_pending_ack_idx = pending_base + pending_acks; 180 pending_acks++; 181 } 182 return 0; 183} 184 185static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe) 186{ 187 u8 *eth_hdr_ptr; 188 u8 *buffer = tqe->buffer; 189 unsigned short h_proto; 190 int i; 191 unsigned long flags; 192 struct wilc_vif *vif; 193 struct wilc *wilc; 194 195 vif = netdev_priv(dev); 196 wilc = vif->wilc; 197 198 spin_lock_irqsave(&wilc->txq_spinlock, flags); 199 200 eth_hdr_ptr = &buffer[0]; 201 h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12])); 202 if (h_proto == ETH_P_IP) { 203 u8 *ip_hdr_ptr; 204 u8 protocol; 205 206 ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN]; 207 protocol = ip_hdr_ptr[9]; 208 209 if (protocol == 0x06) { 210 u8 *tcp_hdr_ptr; 211 u32 IHL, total_length, data_offset; 212 213 tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN]; 214 IHL = (ip_hdr_ptr[0] & 0xf) << 2; 215 total_length = ((u32)ip_hdr_ptr[2] << 8) + 216 (u32)ip_hdr_ptr[3]; 217 data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2; 218 if (total_length == (IHL + data_offset)) { 219 u32 seq_no, ack_no; 220 221 seq_no = ((u32)tcp_hdr_ptr[4] << 24) + 222 ((u32)tcp_hdr_ptr[5] << 16) + 223 ((u32)tcp_hdr_ptr[6] << 8) + 224 (u32)tcp_hdr_ptr[7]; 225 226 ack_no = ((u32)tcp_hdr_ptr[8] << 24) + 227 ((u32)tcp_hdr_ptr[9] << 16) + 228 ((u32)tcp_hdr_ptr[10] << 8) + 229 (u32)tcp_hdr_ptr[11]; 230 231 for (i = 0; i < tcp_session; i++) { 232 if (i < 2 * MAX_TCP_SESSION && 233 ack_session_info[i].seq_num == seq_no) { 234 update_tcp_session(i, ack_no); 235 break; 236 } 237 } 238 if (i == tcp_session) 239 add_tcp_session(0, 0, seq_no); 240 241 add_tcp_pending_ack(ack_no, i, tqe); 242 } 243 } 244 } 245 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 246} 247 248static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) 249{ 250 struct wilc_vif *vif; 251 struct wilc *wilc; 252 u32 i = 0; 253 u32 dropped = 0; 254 255 vif = netdev_priv(dev); 256 wilc = vif->wilc; 257 258 spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags); 259 for (i = pending_base; i < (pending_base + pending_acks); i++) { 260 if (i >= MAX_PENDING_ACKS || 261 pending_acks_info[i].session_index >= 2 * MAX_TCP_SESSION) 262 break; 263 if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) { 264 struct txq_entry_t *tqe; 265 266 tqe = pending_acks_info[i].txqe; 267 if (tqe) { 268 wilc_wlan_txq_remove(wilc, tqe); 269 tqe->status = 1; 270 if (tqe->tx_complete_func) 271 tqe->tx_complete_func(tqe->priv, 272 tqe->status); 273 kfree(tqe); 274 dropped++; 275 } 276 } 277 } 278 pending_acks = 0; 279 tcp_session = 0; 280 281 if (pending_base == 0) 282 pending_base = MAX_TCP_SESSION; 283 else 284 pending_base = 0; 285 286 spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags); 287 288 while (dropped > 0) { 289 wait_for_completion_timeout(&wilc->txq_event, 290 msecs_to_jiffies(1)); 291 dropped--; 292 } 293 294 return 1; 295} 296 297static bool enabled; 298 299void wilc_enable_tcp_ack_filter(bool value) 300{ 301 enabled = value; 302} 303 304static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, 305 u32 buffer_size) 306{ 307 struct txq_entry_t *tqe; 308 struct wilc *wilc = vif->wilc; 309 310 netdev_dbg(vif->ndev, "Adding config packet ...\n"); 311 if (wilc->quit) { 312 netdev_dbg(vif->ndev, "Return due to clear function\n"); 313 complete(&wilc->cfg_event); 314 return 0; 315 } 316 317 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); 318 if (!tqe) 319 return 0; 320 321 tqe->type = WILC_CFG_PKT; 322 tqe->buffer = buffer; 323 tqe->buffer_size = buffer_size; 324 tqe->tx_complete_func = NULL; 325 tqe->priv = NULL; 326 tqe->tcp_pending_ack_idx = NOT_TCP_ACK; 327 328 if (wilc_wlan_txq_add_to_head(vif, tqe)) { 329 kfree(tqe); 330 return 0; 331 } 332 333 return 1; 334} 335 336int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, 337 u32 buffer_size, wilc_tx_complete_func_t func) 338{ 339 struct txq_entry_t *tqe; 340 struct wilc_vif *vif = netdev_priv(dev); 341 struct wilc *wilc; 342 343 wilc = vif->wilc; 344 345 if (wilc->quit) 346 return 0; 347 348 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); 349 350 if (!tqe) 351 return 0; 352 tqe->type = WILC_NET_PKT; 353 tqe->buffer = buffer; 354 tqe->buffer_size = buffer_size; 355 tqe->tx_complete_func = func; 356 tqe->priv = priv; 357 358 tqe->tcp_pending_ack_idx = NOT_TCP_ACK; 359 if (enabled) 360 tcp_process(dev, tqe); 361 wilc_wlan_txq_add_to_tail(dev, tqe); 362 return wilc->txq_entries; 363} 364 365int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, 366 u32 buffer_size, wilc_tx_complete_func_t func) 367{ 368 struct txq_entry_t *tqe; 369 struct wilc_vif *vif = netdev_priv(dev); 370 struct wilc *wilc; 371 372 wilc = vif->wilc; 373 374 if (wilc->quit) 375 return 0; 376 377 tqe = kmalloc(sizeof(*tqe), GFP_KERNEL); 378 379 if (!tqe) 380 return 0; 381 tqe->type = WILC_MGMT_PKT; 382 tqe->buffer = buffer; 383 tqe->buffer_size = buffer_size; 384 tqe->tx_complete_func = func; 385 tqe->priv = priv; 386 tqe->tcp_pending_ack_idx = NOT_TCP_ACK; 387 wilc_wlan_txq_add_to_tail(dev, tqe); 388 return 1; 389} 390 391static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc) 392{ 393 struct txq_entry_t *tqe; 394 unsigned long flags; 395 396 spin_lock_irqsave(&wilc->txq_spinlock, flags); 397 398 tqe = wilc->txq_head; 399 400 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 401 402 return tqe; 403} 404 405static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, 406 struct txq_entry_t *tqe) 407{ 408 unsigned long flags; 409 410 spin_lock_irqsave(&wilc->txq_spinlock, flags); 411 412 tqe = tqe->next; 413 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 414 415 return tqe; 416} 417 418static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) 419{ 420 if (wilc->quit) 421 return 0; 422 423 mutex_lock(&wilc->rxq_cs); 424 if (!wilc->rxq_head) { 425 rqe->next = NULL; 426 wilc->rxq_head = rqe; 427 wilc->rxq_tail = rqe; 428 } else { 429 wilc->rxq_tail->next = rqe; 430 rqe->next = NULL; 431 wilc->rxq_tail = rqe; 432 } 433 wilc->rxq_entries += 1; 434 mutex_unlock(&wilc->rxq_cs); 435 return wilc->rxq_entries; 436} 437 438static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) 439{ 440 if (wilc->rxq_head) { 441 struct rxq_entry_t *rqe; 442 443 mutex_lock(&wilc->rxq_cs); 444 rqe = wilc->rxq_head; 445 wilc->rxq_head = wilc->rxq_head->next; 446 wilc->rxq_entries -= 1; 447 mutex_unlock(&wilc->rxq_cs); 448 return rqe; 449 } 450 return NULL; 451} 452 453void chip_allow_sleep(struct wilc *wilc) 454{ 455 u32 reg = 0; 456 457 wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); 458 459 wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); 460 wilc->hif_func->hif_write_reg(wilc, 0xfa, 0); 461} 462EXPORT_SYMBOL_GPL(chip_allow_sleep); 463 464void chip_wakeup(struct wilc *wilc) 465{ 466 u32 reg, clk_status_reg; 467 468 if ((wilc->io_type & 0x1) == HIF_SPI) { 469 do { 470 wilc->hif_func->hif_read_reg(wilc, 1, ®); 471 wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1)); 472 wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1)); 473 474 do { 475 usleep_range(2 * 1000, 2 * 1000); 476 wilc_get_chipid(wilc, true); 477 } while (wilc_get_chipid(wilc, true) == 0); 478 } while (wilc_get_chipid(wilc, true) == 0); 479 } else if ((wilc->io_type & 0x1) == HIF_SDIO) { 480 wilc->hif_func->hif_write_reg(wilc, 0xfa, 1); 481 udelay(200); 482 wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); 483 do { 484 wilc->hif_func->hif_write_reg(wilc, 0xf0, 485 reg | BIT(0)); 486 wilc->hif_func->hif_read_reg(wilc, 0xf1, 487 &clk_status_reg); 488 489 while ((clk_status_reg & 0x1) == 0) { 490 usleep_range(2 * 1000, 2 * 1000); 491 492 wilc->hif_func->hif_read_reg(wilc, 0xf1, 493 &clk_status_reg); 494 } 495 if ((clk_status_reg & 0x1) == 0) { 496 wilc->hif_func->hif_write_reg(wilc, 0xf0, 497 reg & (~BIT(0))); 498 } 499 } while ((clk_status_reg & 0x1) == 0); 500 } 501 502 if (chip_ps_state == CHIP_SLEEPING_MANUAL) { 503 if (wilc_get_chipid(wilc, false) < 0x1002b0) { 504 u32 val32; 505 506 wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32); 507 val32 |= BIT(6); 508 wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32); 509 510 wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32); 511 val32 |= BIT(6); 512 wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32); 513 } 514 } 515 chip_ps_state = CHIP_WAKEDUP; 516} 517EXPORT_SYMBOL_GPL(chip_wakeup); 518 519void wilc_chip_sleep_manually(struct wilc *wilc) 520{ 521 if (chip_ps_state != CHIP_WAKEDUP) 522 return; 523 acquire_bus(wilc, ACQUIRE_ONLY); 524 525 chip_allow_sleep(wilc); 526 wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1); 527 528 chip_ps_state = CHIP_SLEEPING_MANUAL; 529 release_bus(wilc, RELEASE_ONLY); 530} 531EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually); 532 533void host_wakeup_notify(struct wilc *wilc) 534{ 535 acquire_bus(wilc, ACQUIRE_ONLY); 536 wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1); 537 release_bus(wilc, RELEASE_ONLY); 538} 539EXPORT_SYMBOL_GPL(host_wakeup_notify); 540 541void host_sleep_notify(struct wilc *wilc) 542{ 543 acquire_bus(wilc, ACQUIRE_ONLY); 544 wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1); 545 release_bus(wilc, RELEASE_ONLY); 546} 547EXPORT_SYMBOL_GPL(host_sleep_notify); 548 549int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) 550{ 551 int i, entries = 0; 552 u32 sum; 553 u32 reg; 554 u8 *txb; 555 u32 offset = 0; 556 int vmm_sz = 0; 557 struct txq_entry_t *tqe; 558 int ret = 0; 559 int counter; 560 int timeout; 561 u32 vmm_table[WILC_VMM_TBL_SIZE]; 562 struct wilc_vif *vif; 563 struct wilc *wilc; 564 565 vif = netdev_priv(dev); 566 wilc = vif->wilc; 567 568 txb = wilc->tx_buffer; 569 wilc->txq_exit = 0; 570 do { 571 if (wilc->quit) 572 break; 573 574 mutex_lock(&wilc->txq_add_to_head_cs); 575 wilc_wlan_txq_filter_dup_tcp_ack(dev); 576 tqe = wilc_wlan_txq_get_first(wilc); 577 i = 0; 578 sum = 0; 579 do { 580 if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) { 581 if (tqe->type == WILC_CFG_PKT) 582 vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; 583 584 else if (tqe->type == WILC_NET_PKT) 585 vmm_sz = ETH_ETHERNET_HDR_OFFSET; 586 587 else 588 vmm_sz = HOST_HDR_OFFSET; 589 590 vmm_sz += tqe->buffer_size; 591 592 if (vmm_sz & 0x3) 593 vmm_sz = (vmm_sz + 4) & ~0x3; 594 595 if ((sum + vmm_sz) > LINUX_TX_SIZE) 596 break; 597 598 vmm_table[i] = vmm_sz / 4; 599 if (tqe->type == WILC_CFG_PKT) 600 vmm_table[i] |= BIT(10); 601 vmm_table[i] = cpu_to_le32(vmm_table[i]); 602 603 i++; 604 sum += vmm_sz; 605 tqe = wilc_wlan_txq_get_next(wilc, tqe); 606 } else { 607 break; 608 } 609 } while (1); 610 611 if (i == 0) 612 break; 613 vmm_table[i] = 0x0; 614 615 acquire_bus(wilc, ACQUIRE_AND_WAKEUP); 616 counter = 0; 617 do { 618 ret = wilc->hif_func->hif_read_reg(wilc, 619 WILC_HOST_TX_CTRL, 620 ®); 621 if (!ret) 622 break; 623 624 if ((reg & 0x1) == 0) 625 break; 626 627 counter++; 628 if (counter > 200) { 629 counter = 0; 630 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); 631 break; 632 } 633 } while (!wilc->quit); 634 635 if (!ret) 636 goto _end_; 637 638 timeout = 200; 639 do { 640 ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4)); 641 if (!ret) 642 break; 643 644 ret = wilc->hif_func->hif_write_reg(wilc, 645 WILC_HOST_VMM_CTL, 646 0x2); 647 if (!ret) 648 break; 649 650 do { 651 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®); 652 if (!ret) 653 break; 654 if ((reg >> 2) & 0x1) { 655 entries = ((reg >> 3) & 0x3f); 656 break; 657 } 658 release_bus(wilc, RELEASE_ALLOW_SLEEP); 659 } while (--timeout); 660 if (timeout <= 0) { 661 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); 662 break; 663 } 664 665 if (!ret) 666 break; 667 668 if (entries == 0) { 669 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); 670 if (!ret) 671 break; 672 reg &= ~BIT(0); 673 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg); 674 if (!ret) 675 break; 676 break; 677 } 678 break; 679 } while (1); 680 681 if (!ret) 682 goto _end_; 683 684 if (entries == 0) { 685 ret = WILC_TX_ERR_NO_BUF; 686 goto _end_; 687 } 688 689 release_bus(wilc, RELEASE_ALLOW_SLEEP); 690 691 offset = 0; 692 i = 0; 693 do { 694 tqe = wilc_wlan_txq_remove_from_head(dev); 695 if (tqe && (vmm_table[i] != 0)) { 696 u32 header, buffer_offset; 697 698 vmm_table[i] = cpu_to_le32(vmm_table[i]); 699 vmm_sz = (vmm_table[i] & 0x3ff); 700 vmm_sz *= 4; 701 header = (tqe->type << 31) | 702 (tqe->buffer_size << 15) | 703 vmm_sz; 704 if (tqe->type == WILC_MGMT_PKT) 705 header |= BIT(30); 706 else 707 header &= ~BIT(30); 708 709 header = cpu_to_le32(header); 710 memcpy(&txb[offset], &header, 4); 711 if (tqe->type == WILC_CFG_PKT) { 712 buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; 713 } else if (tqe->type == WILC_NET_PKT) { 714 char *bssid = ((struct tx_complete_data *)(tqe->priv))->bssid; 715 716 buffer_offset = ETH_ETHERNET_HDR_OFFSET; 717 memcpy(&txb[offset + 4], bssid, 6); 718 } else { 719 buffer_offset = HOST_HDR_OFFSET; 720 } 721 722 memcpy(&txb[offset + buffer_offset], 723 tqe->buffer, tqe->buffer_size); 724 offset += vmm_sz; 725 i++; 726 tqe->status = 1; 727 if (tqe->tx_complete_func) 728 tqe->tx_complete_func(tqe->priv, 729 tqe->status); 730 if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK && 731 tqe->tcp_pending_ack_idx < MAX_PENDING_ACKS) 732 pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL; 733 kfree(tqe); 734 } else { 735 break; 736 } 737 } while (--entries); 738 739 acquire_bus(wilc, ACQUIRE_AND_WAKEUP); 740 741 ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM); 742 if (!ret) 743 goto _end_; 744 745 ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset); 746 if (!ret) 747 goto _end_; 748 749_end_: 750 751 release_bus(wilc, RELEASE_ALLOW_SLEEP); 752 if (ret != 1) 753 break; 754 } while (0); 755 mutex_unlock(&wilc->txq_add_to_head_cs); 756 757 wilc->txq_exit = 1; 758 *txq_count = wilc->txq_entries; 759 return ret; 760} 761 762static void wilc_wlan_handle_rxq(struct wilc *wilc) 763{ 764 int offset = 0, size; 765 u8 *buffer; 766 struct rxq_entry_t *rqe; 767 768 wilc->rxq_exit = 0; 769 770 do { 771 if (wilc->quit) { 772 complete(&wilc->cfg_event); 773 break; 774 } 775 rqe = wilc_wlan_rxq_remove(wilc); 776 if (!rqe) 777 break; 778 779 buffer = rqe->buffer; 780 size = rqe->buffer_size; 781 offset = 0; 782 783 do { 784 u32 header; 785 u32 pkt_len, pkt_offset, tp_len; 786 int is_cfg_packet; 787 788 memcpy(&header, &buffer[offset], 4); 789 header = cpu_to_le32(header); 790 791 is_cfg_packet = (header >> 31) & 0x1; 792 pkt_offset = (header >> 22) & 0x1ff; 793 tp_len = (header >> 11) & 0x7ff; 794 pkt_len = header & 0x7ff; 795 796 if (pkt_len == 0 || tp_len == 0) 797 break; 798 799 #define IS_MANAGMEMENT 0x100 800 #define IS_MANAGMEMENT_CALLBACK 0x080 801 #define IS_MGMT_STATUS_SUCCES 0x040 802 803 if (pkt_offset & IS_MANAGMEMENT) { 804 pkt_offset &= ~(IS_MANAGMEMENT | 805 IS_MANAGMEMENT_CALLBACK | 806 IS_MGMT_STATUS_SUCCES); 807 808 WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len); 809 } else { 810 if (!is_cfg_packet) { 811 if (pkt_len > 0) { 812 wilc_frmw_to_linux(wilc, 813 &buffer[offset], 814 pkt_len, 815 pkt_offset); 816 } 817 } else { 818 struct wilc_cfg_rsp rsp; 819 820 wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp); 821 if (rsp.type == WILC_CFG_RSP) { 822 if (wilc->cfg_seq_no == rsp.seq_no) 823 complete(&wilc->cfg_event); 824 } else if (rsp.type == WILC_CFG_RSP_STATUS) { 825 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS); 826 827 } else if (rsp.type == WILC_CFG_RSP_SCAN) { 828 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN); 829 } 830 } 831 } 832 offset += tp_len; 833 if (offset >= size) 834 break; 835 } while (1); 836 kfree(rqe); 837 } while (1); 838 839 wilc->rxq_exit = 1; 840} 841 842static void wilc_unknown_isr_ext(struct wilc *wilc) 843{ 844 wilc->hif_func->hif_clear_int_ext(wilc, 0); 845} 846 847static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) 848{ 849 int trials = 10; 850 851 wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR); 852 853 if (wilc->io_type == HIF_SDIO) 854 mdelay(WILC_PLL_TO_SDIO); 855 else 856 mdelay(WILC_PLL_TO_SPI); 857 858 while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials)) 859 mdelay(1); 860} 861 862static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) 863{ 864 wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR); 865} 866 867static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) 868{ 869 u32 offset = wilc->rx_buffer_offset; 870 u8 *buffer = NULL; 871 u32 size; 872 u32 retries = 0; 873 int ret = 0; 874 struct rxq_entry_t *rqe; 875 876 size = (int_status & 0x7fff) << 2; 877 878 while (!size && retries < 10) { 879 wilc->hif_func->hif_read_size(wilc, &size); 880 size = (size & 0x7fff) << 2; 881 retries++; 882 } 883 884 if (size > 0) { 885 if (LINUX_RX_SIZE - offset < size) 886 offset = 0; 887 888 if (wilc->rx_buffer) 889 buffer = &wilc->rx_buffer[offset]; 890 else 891 goto _end_; 892 893 wilc->hif_func->hif_clear_int_ext(wilc, 894 DATA_INT_CLR | ENABLE_RX_VMM); 895 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); 896 897_end_: 898 if (ret) { 899 offset += size; 900 wilc->rx_buffer_offset = offset; 901 rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); 902 if (rqe) { 903 rqe->buffer = buffer; 904 rqe->buffer_size = size; 905 wilc_wlan_rxq_add(wilc, rqe); 906 } 907 } 908 } 909 wilc_wlan_handle_rxq(wilc); 910} 911 912void wilc_handle_isr(struct wilc *wilc) 913{ 914 u32 int_status; 915 916 acquire_bus(wilc, ACQUIRE_AND_WAKEUP); 917 wilc->hif_func->hif_read_int(wilc, &int_status); 918 919 if (int_status & PLL_INT_EXT) 920 wilc_pllupdate_isr_ext(wilc, int_status); 921 922 if (int_status & DATA_INT_EXT) 923 wilc_wlan_handle_isr_ext(wilc, int_status); 924 925 if (int_status & SLEEP_INT_EXT) 926 wilc_sleeptimer_isr_ext(wilc, int_status); 927 928 if (!(int_status & (ALL_INT_EXT))) 929 wilc_unknown_isr_ext(wilc); 930 931 release_bus(wilc, RELEASE_ALLOW_SLEEP); 932} 933EXPORT_SYMBOL_GPL(wilc_handle_isr); 934 935int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, 936 u32 buffer_size) 937{ 938 u32 offset; 939 u32 addr, size, size2, blksz; 940 u8 *dma_buffer; 941 int ret = 0; 942 943 blksz = BIT(12); 944 945 dma_buffer = kmalloc(blksz, GFP_KERNEL); 946 if (!dma_buffer) 947 return -EIO; 948 949 offset = 0; 950 do { 951 memcpy(&addr, &buffer[offset], 4); 952 memcpy(&size, &buffer[offset + 4], 4); 953 addr = cpu_to_le32(addr); 954 size = cpu_to_le32(size); 955 acquire_bus(wilc, ACQUIRE_ONLY); 956 offset += 8; 957 while (((int)size) && (offset < buffer_size)) { 958 if (size <= blksz) 959 size2 = size; 960 else 961 size2 = blksz; 962 963 memcpy(dma_buffer, &buffer[offset], size2); 964 ret = wilc->hif_func->hif_block_tx(wilc, addr, 965 dma_buffer, size2); 966 if (!ret) 967 break; 968 969 addr += size2; 970 offset += size2; 971 size -= size2; 972 } 973 release_bus(wilc, RELEASE_ONLY); 974 975 if (!ret) { 976 ret = -EIO; 977 goto _fail_; 978 } 979 } while (offset < buffer_size); 980 981_fail_: 982 983 kfree(dma_buffer); 984 985 return (ret < 0) ? ret : 0; 986} 987 988int wilc_wlan_start(struct wilc *wilc) 989{ 990 u32 reg = 0; 991 int ret; 992 u32 chipid; 993 994 if (wilc->io_type == HIF_SDIO) { 995 reg = 0; 996 reg |= BIT(3); 997 } else if (wilc->io_type == HIF_SPI) { 998 reg = 1; 999 } 1000 acquire_bus(wilc, ACQUIRE_ONLY);
1001 ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg); 1002 if (!ret) { 1003 release_bus(wilc, RELEASE_ONLY); 1004 return -EIO; 1005 } 1006 reg = 0; 1007 if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num) 1008 reg |= WILC_HAVE_SDIO_IRQ_GPIO; 1009 1010#ifdef WILC_DISABLE_PMU 1011#else 1012 reg |= WILC_HAVE_USE_PMU; 1013#endif 1014 1015#ifdef WILC_SLEEP_CLK_SRC_XO 1016 reg |= WILC_HAVE_SLEEP_CLK_SRC_XO; 1017#elif defined WILC_SLEEP_CLK_SRC_RTC 1018 reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC; 1019#endif 1020 1021#ifdef WILC_EXT_PA_INV_TX_RX 1022 reg |= WILC_HAVE_EXT_PA_INV_TX_RX; 1023#endif 1024 reg |= WILC_HAVE_USE_IRQ_AS_HOST_WAKE; 1025 reg |= WILC_HAVE_LEGACY_RF_SETTINGS; 1026#ifdef XTAL_24 1027 reg |= WILC_HAVE_XTAL_24; 1028#endif 1029#ifdef DISABLE_WILC_UART 1030 reg |= WILC_HAVE_DISABLE_WILC_UART; 1031#endif 1032 1033 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg); 1034 if (!ret) { 1035 release_bus(wilc, RELEASE_ONLY); 1036 return -EIO; 1037 } 1038 1039 wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT); 1040 1041 ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid); 1042 if (!ret) { 1043 release_bus(wilc, RELEASE_ONLY); 1044 return -EIO; 1045 } 1046 1047 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1048 if ((reg & BIT(10)) == BIT(10)) { 1049 reg &= ~BIT(10); 1050 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1051 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1052 } 1053 1054 reg |= BIT(10); 1055 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1056 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1057 release_bus(wilc, RELEASE_ONLY); 1058 1059 return (ret < 0) ? ret : 0; 1060} 1061 1062int wilc_wlan_stop(struct wilc *wilc) 1063{ 1064 u32 reg = 0; 1065 int ret; 1066 u8 timeout = 10; 1067 1068 acquire_bus(wilc, ACQUIRE_AND_WAKEUP); 1069 1070 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1071 if (!ret) { 1072 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1073 return ret; 1074 } 1075 1076 reg &= ~BIT(10); 1077 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1078 if (!ret) { 1079 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1080 return ret; 1081 } 1082 1083 do { 1084 ret = wilc->hif_func->hif_read_reg(wilc, 1085 WILC_GLB_RESET_0, ®); 1086 if (!ret) { 1087 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1088 return ret; 1089 } 1090 1091 if ((reg & BIT(10))) { 1092 reg &= ~BIT(10); 1093 ret = wilc->hif_func->hif_write_reg(wilc, 1094 WILC_GLB_RESET_0, 1095 reg); 1096 timeout--; 1097 } else { 1098 ret = wilc->hif_func->hif_read_reg(wilc, 1099 WILC_GLB_RESET_0, 1100 ®); 1101 if (!ret) { 1102 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1103 return ret; 1104 } 1105 break; 1106 } 1107 1108 } while (timeout); 1109 reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) | 1110 BIT(29) | BIT(30) | BIT(31)); 1111 1112 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1113 reg = (u32)~BIT(10); 1114 1115 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1116 1117 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1118 1119 return ret; 1120} 1121 1122void wilc_wlan_cleanup(struct net_device *dev) 1123{ 1124 struct txq_entry_t *tqe; 1125 struct rxq_entry_t *rqe; 1126 u32 reg = 0; 1127 int ret; 1128 struct wilc_vif *vif; 1129 struct wilc *wilc; 1130 1131 vif = netdev_priv(dev); 1132 wilc = vif->wilc; 1133 1134 wilc->quit = 1; 1135 do { 1136 tqe = wilc_wlan_txq_remove_from_head(dev); 1137 if (!tqe) 1138 break; 1139 if (tqe->tx_complete_func) 1140 tqe->tx_complete_func(tqe->priv, 0); 1141 kfree(tqe); 1142 } while (1); 1143 1144 do { 1145 rqe = wilc_wlan_rxq_remove(wilc); 1146 if (!rqe) 1147 break; 1148 kfree(rqe); 1149 } while (1); 1150 1151 kfree(wilc->rx_buffer); 1152 wilc->rx_buffer = NULL; 1153 kfree(wilc->tx_buffer); 1154 wilc->tx_buffer = NULL; 1155 1156 acquire_bus(wilc, ACQUIRE_AND_WAKEUP); 1157 1158 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); 1159 if (!ret) 1160 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1161 1162 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, 1163 (reg | ABORT_INT)); 1164 if (!ret) 1165 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1166 1167 release_bus(wilc, RELEASE_ALLOW_SLEEP); 1168 wilc->hif_func->hif_deinit(NULL); 1169} 1170 1171static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, 1172 u32 drv_handler) 1173{ 1174 struct wilc *wilc = vif->wilc; 1175 struct wilc_cfg_frame *cfg = &wilc->cfg_frame; 1176 int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; 1177 int seq_no = wilc->cfg_seq_no % 256; 1178 int driver_handler = (u32)drv_handler; 1179 1180 if (type == WILC_CFG_SET) 1181 cfg->wid_header[0] = 'W'; 1182 else 1183 cfg->wid_header[0] = 'Q'; 1184 cfg->wid_header[1] = seq_no; 1185 cfg->wid_header[2] = (u8)total_len; 1186 cfg->wid_header[3] = (u8)(total_len >> 8); 1187 cfg->wid_header[4] = (u8)driver_handler; 1188 cfg->wid_header[5] = (u8)(driver_handler >> 8); 1189 cfg->wid_header[6] = (u8)(driver_handler >> 16); 1190 cfg->wid_header[7] = (u8)(driver_handler >> 24); 1191 wilc->cfg_seq_no = seq_no; 1192 1193 if (!wilc_wlan_txq_add_cfg_pkt(vif, &cfg->wid_header[0], total_len)) 1194 return -1; 1195 1196 return 0; 1197} 1198 1199int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, 1200 u32 buffer_size, int commit, u32 drv_handler) 1201{ 1202 u32 offset; 1203 int ret_size; 1204 struct wilc *wilc = vif->wilc; 1205 1206 if (wilc->cfg_frame_in_use) 1207 return 0; 1208 1209 if (start) 1210 wilc->cfg_frame_offset = 0; 1211 1212 offset = wilc->cfg_frame_offset; 1213 ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset, 1214 wid, buffer, buffer_size); 1215 offset += ret_size; 1216 wilc->cfg_frame_offset = offset; 1217 1218 if (commit) { 1219 netdev_dbg(vif->ndev, 1220 "[WILC]PACKET Commit with sequence number %d\n", 1221 wilc->cfg_seq_no); 1222 netdev_dbg(vif->ndev, "Processing cfg_set()\n"); 1223 wilc->cfg_frame_in_use = 1; 1224 1225 if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler)) 1226 ret_size = 0; 1227 1228 if (!wait_for_completion_timeout(&wilc->cfg_event, 1229 msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { 1230 netdev_dbg(vif->ndev, "Set Timed Out\n"); 1231 ret_size = 0; 1232 } 1233 1234 wilc->cfg_frame_in_use = 0; 1235 wilc->cfg_frame_offset = 0; 1236 wilc->cfg_seq_no += 1; 1237 } 1238 1239 return ret_size; 1240} 1241 1242int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, 1243 u32 drv_handler) 1244{ 1245 u32 offset; 1246 int ret_size; 1247 struct wilc *wilc = vif->wilc; 1248 1249 if (wilc->cfg_frame_in_use) 1250 return 0; 1251 1252 if (start) 1253 wilc->cfg_frame_offset = 0; 1254 1255 offset = wilc->cfg_frame_offset; 1256 ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid); 1257 offset += ret_size; 1258 wilc->cfg_frame_offset = offset; 1259 1260 if (commit) { 1261 wilc->cfg_frame_in_use = 1; 1262 1263 if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler)) 1264 ret_size = 0; 1265 1266 if (!wait_for_completion_timeout(&wilc->cfg_event, 1267 msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { 1268 netdev_dbg(vif->ndev, "Get Timed Out\n"); 1269 ret_size = 0; 1270 } 1271 wilc->cfg_frame_in_use = 0; 1272 wilc->cfg_frame_offset = 0; 1273 wilc->cfg_seq_no += 1; 1274 } 1275 1276 return ret_size; 1277} 1278 1279int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size) 1280{ 1281 return wilc_wlan_cfg_get_wid_value(wid, buffer, buffer_size); 1282} 1283 1284int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, 1285 u32 count, u32 drv) 1286{ 1287 int i; 1288 int ret = 0; 1289 1290 if (mode == GET_CFG) { 1291 for (i = 0; i < count; i++) { 1292 if (!wilc_wlan_cfg_get(vif, !i, 1293 wids[i].id, 1294 (i == count - 1), 1295 drv)) { 1296 ret = -ETIMEDOUT; 1297 break; 1298 } 1299 } 1300 for (i = 0; i < count; i++) { 1301 wids[i].size = wilc_wlan_cfg_get_val(wids[i].id, 1302 wids[i].val, 1303 wids[i].size); 1304 } 1305 } else if (mode == SET_CFG) { 1306 for (i = 0; i < count; i++) { 1307 if (!wilc_wlan_cfg_set(vif, !i, 1308 wids[i].id, 1309 wids[i].val, 1310 wids[i].size, 1311 (i == count - 1), 1312 drv)) { 1313 ret = -ETIMEDOUT; 1314 break; 1315 } 1316 } 1317 } 1318 1319 return ret; 1320} 1321 1322static u32 init_chip(struct net_device *dev) 1323{ 1324 u32 chipid; 1325 u32 reg, ret = 0; 1326 struct wilc_vif *vif; 1327 struct wilc *wilc; 1328 1329 vif = netdev_priv(dev); 1330 wilc = vif->wilc; 1331 1332 acquire_bus(wilc, ACQUIRE_ONLY); 1333 1334 chipid = wilc_get_chipid(wilc, true); 1335 1336 if ((chipid & 0xfff) != 0xa0) { 1337 ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, ®); 1338 if (!ret) { 1339 netdev_err(dev, "fail read reg 0x1118\n"); 1340 return ret; 1341 } 1342 reg |= BIT(0); 1343 ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg); 1344 if (!ret) { 1345 netdev_err(dev, "fail write reg 0x1118\n"); 1346 return ret; 1347 } 1348 ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71); 1349 if (!ret) { 1350 netdev_err(dev, "fail write reg 0xc0000\n"); 1351 return ret; 1352 } 1353 } 1354 1355 release_bus(wilc, RELEASE_ONLY); 1356 1357 return ret; 1358} 1359 1360u32 wilc_get_chipid(struct wilc *wilc, bool update) 1361{ 1362 static u32 chipid; 1363 u32 tempchipid = 0; 1364 u32 rfrevid = 0; 1365 1366 if (chipid == 0 || update) { 1367 wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid); 1368 wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid); 1369 if (!ISWILC1000(tempchipid)) { 1370 chipid = 0; 1371 return chipid; 1372 } 1373 if (tempchipid == 0x1002a0) { 1374 if (rfrevid != 0x1) 1375 tempchipid = 0x1002a1; 1376 } else if (tempchipid == 0x1002b0) { 1377 if (rfrevid == 0x4) 1378 tempchipid = 0x1002b1; 1379 else if (rfrevid != 0x3) 1380 tempchipid = 0x1002b2; 1381 } 1382 1383 chipid = tempchipid; 1384 } 1385 return chipid; 1386} 1387 1388int wilc_wlan_init(struct net_device *dev) 1389{ 1390 int ret = 0; 1391 struct wilc_vif *vif = netdev_priv(dev); 1392 struct wilc *wilc; 1393 1394 wilc = vif->wilc; 1395 1396 wilc->quit = 0; 1397 1398 if (!wilc->hif_func->hif_init(wilc, false)) { 1399 ret = -EIO; 1400 goto _fail_; 1401 } 1402 1403 if (!wilc_wlan_cfg_init()) { 1404 ret = -ENOBUFS; 1405 goto _fail_; 1406 } 1407 1408 if (!wilc->tx_buffer) 1409 wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); 1410 1411 if (!wilc->tx_buffer) { 1412 ret = -ENOBUFS; 1413 goto _fail_; 1414 } 1415 1416 if (!wilc->rx_buffer) 1417 wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); 1418 1419 if (!wilc->rx_buffer) { 1420 ret = -ENOBUFS; 1421 goto _fail_; 1422 } 1423 1424 if (!init_chip(dev)) { 1425 ret = -EIO; 1426 goto _fail_; 1427 } 1428 1429 return 1; 1430 1431_fail_: 1432 1433 kfree(wilc->rx_buffer); 1434 wilc->rx_buffer = NULL; 1435 kfree(wilc->tx_buffer); 1436 wilc->tx_buffer = NULL; 1437 1438 return ret; 1439} 1440