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