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, void *priv, u8 *buffer, 412 u32 buffer_size, 413 void (*tx_complete_fn)(void *, int)) 414 { 415 struct txq_entry_t *tqe; 416 struct wilc_vif *vif = netdev_priv(dev); 417 struct wilc *wilc; 418 u8 q_num; 419 420 wilc = vif->wilc; 421 422 if (wilc->quit) { 423 tx_complete_fn(priv, 0); 424 return 0; 425 } 426 427 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); 428 429 if (!tqe) { 430 tx_complete_fn(priv, 0); 431 return 0; 432 } 433 tqe->type = WILC_NET_PKT; 434 tqe->buffer = buffer; 435 tqe->buffer_size = buffer_size; 436 tqe->tx_complete_func = tx_complete_fn; 437 tqe->priv = priv; 438 tqe->vif = vif; 439 440 q_num = ac_classify(wilc, priv); 441 tqe->q_num = q_num; 442 if (ac_change(wilc, &q_num)) { 443 tx_complete_fn(priv, 0); 444 kfree(tqe); 445 return 0; 446 } 447 448 if (is_ac_q_limit(wilc, q_num)) { 449 tqe->ack_idx = NOT_TCP_ACK; 450 if (vif->ack_filter.enabled) 451 tcp_process(dev, tqe); 452 wilc_wlan_txq_add_to_tail(dev, q_num, tqe); 453 } else { 454 tx_complete_fn(priv, 0); 455 kfree(tqe); 456 } 457 458 return wilc->txq_entries; 459 } 460 461 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, 462 u32 buffer_size, 463 void (*tx_complete_fn)(void *, int)) 464 { 465 struct txq_entry_t *tqe; 466 struct wilc_vif *vif = netdev_priv(dev); 467 struct wilc *wilc; 468 469 wilc = vif->wilc; 470 471 if (wilc->quit) { 472 tx_complete_fn(priv, 0); 473 return 0; 474 } 475 476 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); 477 478 if (!tqe) { 479 tx_complete_fn(priv, 0); 480 return 0; 481 } 482 tqe->type = WILC_MGMT_PKT; 483 tqe->buffer = buffer; 484 tqe->buffer_size = buffer_size; 485 tqe->tx_complete_func = tx_complete_fn; 486 tqe->priv = priv; 487 tqe->q_num = AC_BE_Q; 488 tqe->ack_idx = NOT_TCP_ACK; 489 tqe->vif = vif; 490 wilc_wlan_txq_add_to_tail(dev, AC_VO_Q, tqe); 491 return 1; 492 } 493 494 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc, u8 q_num) 495 { 496 struct txq_entry_t *tqe = NULL; 497 unsigned long flags; 498 499 spin_lock_irqsave(&wilc->txq_spinlock, flags); 500 501 if (!list_empty(&wilc->txq[q_num].txq_head.list)) 502 tqe = list_first_entry(&wilc->txq[q_num].txq_head.list, 503 struct txq_entry_t, list); 504 505 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 506 507 return tqe; 508 } 509 510 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, 511 struct txq_entry_t *tqe, 512 u8 q_num) 513 { 514 unsigned long flags; 515 516 spin_lock_irqsave(&wilc->txq_spinlock, flags); 517 518 if (!list_is_last(&tqe->list, &wilc->txq[q_num].txq_head.list)) 519 tqe = list_next_entry(tqe, list); 520 else 521 tqe = NULL; 522 spin_unlock_irqrestore(&wilc->txq_spinlock, flags); 523 524 return tqe; 525 } 526 527 static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) 528 { 529 if (wilc->quit) 530 return; 531 532 mutex_lock(&wilc->rxq_cs); 533 list_add_tail(&rqe->list, &wilc->rxq_head.list); 534 mutex_unlock(&wilc->rxq_cs); 535 } 536 537 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) 538 { 539 struct rxq_entry_t *rqe = NULL; 540 541 mutex_lock(&wilc->rxq_cs); 542 if (!list_empty(&wilc->rxq_head.list)) { 543 rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t, 544 list); 545 list_del(&rqe->list); 546 } 547 mutex_unlock(&wilc->rxq_cs); 548 return rqe; 549 } 550 551 void chip_allow_sleep(struct wilc *wilc) 552 { 553 u32 reg = 0; 554 555 wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®); 556 557 wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, 558 reg & ~WILC_SDIO_WAKEUP_BIT); 559 wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0); 560 } 561 EXPORT_SYMBOL_GPL(chip_allow_sleep); 562 563 void chip_wakeup(struct wilc *wilc) 564 { 565 u32 reg, clk_status_reg; 566 const struct wilc_hif_func *h = wilc->hif_func; 567 568 if (wilc->io_type == WILC_HIF_SPI) { 569 do { 570 h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®); 571 h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG, 572 reg | WILC_SPI_WAKEUP_BIT); 573 h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG, 574 reg & ~WILC_SPI_WAKEUP_BIT); 575 576 do { 577 usleep_range(2000, 2500); 578 wilc_get_chipid(wilc, true); 579 } while (wilc_get_chipid(wilc, true) == 0); 580 } while (wilc_get_chipid(wilc, true) == 0); 581 } else if (wilc->io_type == WILC_HIF_SDIO) { 582 h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 583 WILC_SDIO_HOST_TO_FW_BIT); 584 usleep_range(200, 400); 585 h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®); 586 do { 587 h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, 588 reg | WILC_SDIO_WAKEUP_BIT); 589 h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG, 590 &clk_status_reg); 591 592 while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) { 593 usleep_range(2000, 2500); 594 595 h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG, 596 &clk_status_reg); 597 } 598 if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) { 599 h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, 600 reg & ~WILC_SDIO_WAKEUP_BIT); 601 } 602 } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)); 603 } 604 605 if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) { 606 if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) { 607 u32 val32; 608 609 h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32); 610 val32 |= BIT(6); 611 h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32); 612 613 h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32); 614 val32 |= BIT(6); 615 h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32); 616 } 617 } 618 wilc->chip_ps_state = WILC_CHIP_WAKEDUP; 619 } 620 EXPORT_SYMBOL_GPL(chip_wakeup); 621 622 void host_wakeup_notify(struct wilc *wilc) 623 { 624 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); 625 wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1); 626 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 627 } 628 EXPORT_SYMBOL_GPL(host_wakeup_notify); 629 630 void host_sleep_notify(struct wilc *wilc) 631 { 632 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); 633 wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1); 634 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 635 } 636 EXPORT_SYMBOL_GPL(host_sleep_notify); 637 638 int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) 639 { 640 int i, entries = 0; 641 u8 k, ac; 642 u32 sum; 643 u32 reg; 644 u8 ac_desired_ratio[NQUEUES] = {0, 0, 0, 0}; 645 u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1}; 646 u8 *num_pkts_to_add; 647 u8 vmm_entries_ac[WILC_VMM_TBL_SIZE]; 648 u32 offset = 0; 649 bool max_size_over = 0, ac_exist = 0; 650 int vmm_sz = 0; 651 struct txq_entry_t *tqe_q[NQUEUES]; 652 int ret = 0; 653 int counter; 654 int timeout; 655 u32 vmm_table[WILC_VMM_TBL_SIZE]; 656 u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0}; 657 const struct wilc_hif_func *func; 658 int srcu_idx; 659 u8 *txb = wilc->tx_buffer; 660 struct wilc_vif *vif; 661 662 if (wilc->quit) 663 goto out_update_cnt; 664 665 if (ac_balance(wilc, ac_desired_ratio)) 666 return -EINVAL; 667 668 mutex_lock(&wilc->txq_add_to_head_cs); 669 670 srcu_idx = srcu_read_lock(&wilc->srcu); 671 list_for_each_entry_rcu(vif, &wilc->vif_list, list) 672 wilc_wlan_txq_filter_dup_tcp_ack(vif->ndev); 673 srcu_read_unlock(&wilc->srcu, srcu_idx); 674 675 for (ac = 0; ac < NQUEUES; ac++) 676 tqe_q[ac] = wilc_wlan_txq_get_first(wilc, ac); 677 678 i = 0; 679 sum = 0; 680 max_size_over = 0; 681 num_pkts_to_add = ac_desired_ratio; 682 do { 683 ac_exist = 0; 684 for (ac = 0; (ac < NQUEUES) && (!max_size_over); ac++) { 685 if (!tqe_q[ac]) 686 continue; 687 688 ac_exist = 1; 689 for (k = 0; (k < num_pkts_to_add[ac]) && 690 (!max_size_over) && tqe_q[ac]; k++) { 691 if (i >= (WILC_VMM_TBL_SIZE - 1)) { 692 max_size_over = 1; 693 break; 694 } 695 696 if (tqe_q[ac]->type == WILC_CFG_PKT) 697 vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; 698 else if (tqe_q[ac]->type == WILC_NET_PKT) 699 vmm_sz = ETH_ETHERNET_HDR_OFFSET; 700 else 701 vmm_sz = HOST_HDR_OFFSET; 702 703 vmm_sz += tqe_q[ac]->buffer_size; 704 vmm_sz = ALIGN(vmm_sz, 4); 705 706 if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) { 707 max_size_over = 1; 708 break; 709 } 710 vmm_table[i] = vmm_sz / 4; 711 if (tqe_q[ac]->type == WILC_CFG_PKT) 712 vmm_table[i] |= BIT(10); 713 714 cpu_to_le32s(&vmm_table[i]); 715 vmm_entries_ac[i] = ac; 716 717 i++; 718 sum += vmm_sz; 719 tqe_q[ac] = wilc_wlan_txq_get_next(wilc, 720 tqe_q[ac], 721 ac); 722 } 723 } 724 num_pkts_to_add = ac_preserve_ratio; 725 } while (!max_size_over && ac_exist); 726 727 if (i == 0) 728 goto out_unlock; 729 vmm_table[i] = 0x0; 730 731 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); 732 counter = 0; 733 func = wilc->hif_func; 734 do { 735 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); 736 if (ret) 737 break; 738 739 if ((reg & 0x1) == 0) { 740 ac_update_fw_ac_pkt_info(wilc, reg); 741 break; 742 } 743 744 counter++; 745 if (counter > 200) { 746 counter = 0; 747 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); 748 break; 749 } 750 } while (!wilc->quit); 751 752 if (ret) 753 goto out_release_bus; 754 755 timeout = 200; 756 do { 757 ret = func->hif_block_tx(wilc, 758 WILC_VMM_TBL_RX_SHADOW_BASE, 759 (u8 *)vmm_table, 760 ((i + 1) * 4)); 761 if (ret) 762 break; 763 764 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2); 765 if (ret) 766 break; 767 768 do { 769 ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®); 770 if (ret) 771 break; 772 if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) { 773 entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg); 774 break; 775 } 776 } while (--timeout); 777 if (timeout <= 0) { 778 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); 779 break; 780 } 781 782 if (ret) 783 break; 784 785 if (entries == 0) { 786 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®); 787 if (ret) 788 break; 789 reg &= ~BIT(0); 790 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg); 791 } 792 } while (0); 793 794 if (ret) 795 goto out_release_bus; 796 797 if (entries == 0) { 798 /* 799 * No VMM space available in firmware so retry to transmit 800 * the packet from tx queue. 801 */ 802 ret = WILC_VMM_ENTRY_FULL_RETRY; 803 goto out_release_bus; 804 } 805 806 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 807 808 offset = 0; 809 i = 0; 810 do { 811 struct txq_entry_t *tqe; 812 u32 header, buffer_offset; 813 char *bssid; 814 u8 mgmt_ptk = 0; 815 816 tqe = wilc_wlan_txq_remove_from_head(wilc, vmm_entries_ac[i]); 817 ac_pkt_num_to_chip[vmm_entries_ac[i]]++; 818 if (!tqe) 819 break; 820 821 vif = tqe->vif; 822 if (vmm_table[i] == 0) 823 break; 824 825 le32_to_cpus(&vmm_table[i]); 826 vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]); 827 vmm_sz *= 4; 828 829 if (tqe->type == WILC_MGMT_PKT) 830 mgmt_ptk = 1; 831 832 header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) | 833 FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) | 834 FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) | 835 FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz)); 836 837 cpu_to_le32s(&header); 838 memcpy(&txb[offset], &header, 4); 839 if (tqe->type == WILC_CFG_PKT) { 840 buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; 841 } else if (tqe->type == WILC_NET_PKT) { 842 int prio = tqe->q_num; 843 844 bssid = tqe->vif->bssid; 845 buffer_offset = ETH_ETHERNET_HDR_OFFSET; 846 memcpy(&txb[offset + 4], &prio, sizeof(prio)); 847 memcpy(&txb[offset + 8], bssid, 6); 848 } else { 849 buffer_offset = HOST_HDR_OFFSET; 850 } 851 852 memcpy(&txb[offset + buffer_offset], 853 tqe->buffer, tqe->buffer_size); 854 offset += vmm_sz; 855 i++; 856 tqe->status = 1; 857 if (tqe->tx_complete_func) 858 tqe->tx_complete_func(tqe->priv, tqe->status); 859 if (tqe->ack_idx != NOT_TCP_ACK && 860 tqe->ack_idx < MAX_PENDING_ACKS) 861 vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL; 862 kfree(tqe); 863 } while (--entries); 864 for (i = 0; i < NQUEUES; i++) 865 wilc->txq[i].fw.count += ac_pkt_num_to_chip[i]; 866 867 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); 868 869 ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM); 870 if (ret) 871 goto out_release_bus; 872 873 ret = func->hif_block_tx_ext(wilc, 0, txb, offset); 874 875 out_release_bus: 876 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 877 878 out_unlock: 879 mutex_unlock(&wilc->txq_add_to_head_cs); 880 881 out_update_cnt: 882 *txq_count = wilc->txq_entries; 883 return ret; 884 } 885 886 static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size) 887 { 888 int offset = 0; 889 u32 header; 890 u32 pkt_len, pkt_offset, tp_len; 891 int is_cfg_packet; 892 u8 *buff_ptr; 893 894 do { 895 buff_ptr = buffer + offset; 896 header = get_unaligned_le32(buff_ptr); 897 898 is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header); 899 pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header); 900 tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header); 901 pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header); 902 903 if (pkt_len == 0 || tp_len == 0) 904 break; 905 906 if (pkt_offset & IS_MANAGMEMENT) { 907 buff_ptr += HOST_HDR_OFFSET; 908 wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len); 909 } else { 910 if (!is_cfg_packet) { 911 wilc_frmw_to_host(wilc, buff_ptr, pkt_len, 912 pkt_offset); 913 } else { 914 struct wilc_cfg_rsp rsp; 915 916 buff_ptr += pkt_offset; 917 918 wilc_wlan_cfg_indicate_rx(wilc, buff_ptr, 919 pkt_len, 920 &rsp); 921 if (rsp.type == WILC_CFG_RSP) { 922 if (wilc->cfg_seq_no == rsp.seq_no) 923 complete(&wilc->cfg_event); 924 } else if (rsp.type == WILC_CFG_RSP_STATUS) { 925 wilc_mac_indicate(wilc); 926 } 927 } 928 } 929 offset += tp_len; 930 } while (offset < size); 931 } 932 933 static void wilc_wlan_handle_rxq(struct wilc *wilc) 934 { 935 int size; 936 u8 *buffer; 937 struct rxq_entry_t *rqe; 938 939 while (!wilc->quit) { 940 rqe = wilc_wlan_rxq_remove(wilc); 941 if (!rqe) 942 break; 943 944 buffer = rqe->buffer; 945 size = rqe->buffer_size; 946 wilc_wlan_handle_rx_buff(wilc, buffer, size); 947 948 kfree(rqe); 949 } 950 if (wilc->quit) 951 complete(&wilc->cfg_event); 952 } 953 954 static void wilc_unknown_isr_ext(struct wilc *wilc) 955 { 956 wilc->hif_func->hif_clear_int_ext(wilc, 0); 957 } 958 959 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) 960 { 961 u32 offset = wilc->rx_buffer_offset; 962 u8 *buffer = NULL; 963 u32 size; 964 u32 retries = 0; 965 int ret = 0; 966 struct rxq_entry_t *rqe; 967 968 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2; 969 970 while (!size && retries < 10) { 971 wilc->hif_func->hif_read_size(wilc, &size); 972 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2; 973 retries++; 974 } 975 976 if (size <= 0) 977 return; 978 979 if (WILC_RX_BUFF_SIZE - offset < size) 980 offset = 0; 981 982 buffer = &wilc->rx_buffer[offset]; 983 984 wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM); 985 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); 986 if (ret) 987 return; 988 989 offset += size; 990 wilc->rx_buffer_offset = offset; 991 rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); 992 if (!rqe) 993 return; 994 995 rqe->buffer = buffer; 996 rqe->buffer_size = size; 997 wilc_wlan_rxq_add(wilc, rqe); 998 wilc_wlan_handle_rxq(wilc); 999 } 1000 1001 void wilc_handle_isr(struct wilc *wilc) 1002 { 1003 u32 int_status; 1004 1005 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); 1006 wilc->hif_func->hif_read_int(wilc, &int_status); 1007 1008 if (int_status & DATA_INT_EXT) 1009 wilc_wlan_handle_isr_ext(wilc, int_status); 1010 1011 if (!(int_status & (ALL_INT_EXT))) 1012 wilc_unknown_isr_ext(wilc); 1013 1014 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1015 } 1016 EXPORT_SYMBOL_GPL(wilc_handle_isr); 1017 1018 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, 1019 u32 buffer_size) 1020 { 1021 u32 offset; 1022 u32 addr, size, size2, blksz; 1023 u8 *dma_buffer; 1024 int ret = 0; 1025 1026 blksz = BIT(12); 1027 1028 dma_buffer = kmalloc(blksz, GFP_KERNEL); 1029 if (!dma_buffer) 1030 return -EIO; 1031 1032 offset = 0; 1033 do { 1034 addr = get_unaligned_le32(&buffer[offset]); 1035 size = get_unaligned_le32(&buffer[offset + 4]); 1036 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); 1037 offset += 8; 1038 while (((int)size) && (offset < buffer_size)) { 1039 if (size <= blksz) 1040 size2 = size; 1041 else 1042 size2 = blksz; 1043 1044 memcpy(dma_buffer, &buffer[offset], size2); 1045 ret = wilc->hif_func->hif_block_tx(wilc, addr, 1046 dma_buffer, size2); 1047 if (ret) 1048 break; 1049 1050 addr += size2; 1051 offset += size2; 1052 size -= size2; 1053 } 1054 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1055 1056 if (ret) 1057 goto fail; 1058 } while (offset < buffer_size); 1059 1060 fail: 1061 1062 kfree(dma_buffer); 1063 1064 return ret; 1065 } 1066 1067 int wilc_wlan_start(struct wilc *wilc) 1068 { 1069 u32 reg = 0; 1070 int ret; 1071 u32 chipid; 1072 1073 if (wilc->io_type == WILC_HIF_SDIO) { 1074 reg = 0; 1075 reg |= BIT(3); 1076 } else if (wilc->io_type == WILC_HIF_SPI) { 1077 reg = 1; 1078 } 1079 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); 1080 ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg); 1081 if (ret) { 1082 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1083 return ret; 1084 } 1085 reg = 0; 1086 if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num) 1087 reg |= WILC_HAVE_SDIO_IRQ_GPIO; 1088 1089 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg); 1090 if (ret) { 1091 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1092 return ret; 1093 } 1094 1095 wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT); 1096 1097 ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid); 1098 if (ret) { 1099 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1100 return ret; 1101 } 1102 1103 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1104 if ((reg & BIT(10)) == BIT(10)) { 1105 reg &= ~BIT(10); 1106 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1107 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1108 } 1109 1110 reg |= BIT(10); 1111 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); 1112 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); 1113 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1114 1115 return ret; 1116 } 1117 1118 int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) 1119 { 1120 u32 reg = 0; 1121 int ret; 1122 1123 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); 1124 1125 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); 1126 if (ret) { 1127 netdev_err(vif->ndev, "Error while reading reg\n"); 1128 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1129 return ret; 1130 } 1131 1132 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, 1133 (reg | WILC_ABORT_REQ_BIT)); 1134 if (ret) { 1135 netdev_err(vif->ndev, "Error while writing reg\n"); 1136 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1137 return ret; 1138 } 1139 1140 ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, ®); 1141 if (ret) { 1142 netdev_err(vif->ndev, "Error while reading reg\n"); 1143 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1144 return ret; 1145 } 1146 reg = BIT(0); 1147 1148 ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg); 1149 if (ret) { 1150 netdev_err(vif->ndev, "Error while writing reg\n"); 1151 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1152 return ret; 1153 } 1154 1155 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); 1156 1157 return 0; 1158 } 1159 1160 void wilc_wlan_cleanup(struct net_device *dev) 1161 { 1162 struct txq_entry_t *tqe; 1163 struct rxq_entry_t *rqe; 1164 u8 ac; 1165 struct wilc_vif *vif = netdev_priv(dev); 1166 struct wilc *wilc = vif->wilc; 1167 1168 wilc->quit = 1; 1169 for (ac = 0; ac < NQUEUES; ac++) { 1170 while ((tqe = wilc_wlan_txq_remove_from_head(wilc, ac))) { 1171 if (tqe->tx_complete_func) 1172 tqe->tx_complete_func(tqe->priv, 0); 1173 kfree(tqe); 1174 } 1175 } 1176 1177 while ((rqe = wilc_wlan_rxq_remove(wilc))) 1178 kfree(rqe); 1179 1180 kfree(wilc->rx_buffer); 1181 wilc->rx_buffer = NULL; 1182 kfree(wilc->tx_buffer); 1183 wilc->tx_buffer = NULL; 1184 wilc->hif_func->hif_deinit(NULL); 1185 } 1186 1187 static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, 1188 u32 drv_handler) 1189 { 1190 struct wilc *wilc = vif->wilc; 1191 struct wilc_cfg_frame *cfg = &wilc->cfg_frame; 1192 int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr); 1193 1194 if (type == WILC_CFG_SET) 1195 cfg->hdr.cmd_type = 'W'; 1196 else 1197 cfg->hdr.cmd_type = 'Q'; 1198 1199 cfg->hdr.seq_no = wilc->cfg_seq_no % 256; 1200 cfg->hdr.total_len = cpu_to_le16(t_len); 1201 cfg->hdr.driver_handler = cpu_to_le32(drv_handler); 1202 wilc->cfg_seq_no = cfg->hdr.seq_no; 1203 1204 if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len)) 1205 return -1; 1206 1207 return 0; 1208 } 1209 1210 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, 1211 u32 buffer_size, int commit, u32 drv_handler) 1212 { 1213 u32 offset; 1214 int ret_size; 1215 struct wilc *wilc = vif->wilc; 1216 1217 mutex_lock(&wilc->cfg_cmd_lock); 1218 1219 if (start) 1220 wilc->cfg_frame_offset = 0; 1221 1222 offset = wilc->cfg_frame_offset; 1223 ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset, 1224 wid, buffer, buffer_size); 1225 offset += ret_size; 1226 wilc->cfg_frame_offset = offset; 1227 1228 if (!commit) { 1229 mutex_unlock(&wilc->cfg_cmd_lock); 1230 return ret_size; 1231 } 1232 1233 netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no); 1234 1235 if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler)) 1236 ret_size = 0; 1237 1238 if (!wait_for_completion_timeout(&wilc->cfg_event, 1239 WILC_CFG_PKTS_TIMEOUT)) { 1240 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); 1241 ret_size = 0; 1242 } 1243 1244 wilc->cfg_frame_offset = 0; 1245 wilc->cfg_seq_no += 1; 1246 mutex_unlock(&wilc->cfg_cmd_lock); 1247 1248 return ret_size; 1249 } 1250 1251 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, 1252 u32 drv_handler) 1253 { 1254 u32 offset; 1255 int ret_size; 1256 struct wilc *wilc = vif->wilc; 1257 1258 mutex_lock(&wilc->cfg_cmd_lock); 1259 1260 if (start) 1261 wilc->cfg_frame_offset = 0; 1262 1263 offset = wilc->cfg_frame_offset; 1264 ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid); 1265 offset += ret_size; 1266 wilc->cfg_frame_offset = offset; 1267 1268 if (!commit) { 1269 mutex_unlock(&wilc->cfg_cmd_lock); 1270 return ret_size; 1271 } 1272 1273 if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler)) 1274 ret_size = 0; 1275 1276 if (!wait_for_completion_timeout(&wilc->cfg_event, 1277 WILC_CFG_PKTS_TIMEOUT)) { 1278 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); 1279 ret_size = 0; 1280 } 1281 wilc->cfg_frame_offset = 0; 1282 wilc->cfg_seq_no += 1; 1283 mutex_unlock(&wilc->cfg_cmd_lock); 1284 1285 return ret_size; 1286 } 1287 1288 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, 1289 u32 count) 1290 { 1291 int i; 1292 int ret = 0; 1293 u32 drv = wilc_get_vif_idx(vif); 1294 1295 if (mode == WILC_GET_CFG) { 1296 for (i = 0; i < count; i++) { 1297 if (!wilc_wlan_cfg_get(vif, !i, 1298 wids[i].id, 1299 (i == count - 1), 1300 drv)) { 1301 ret = -ETIMEDOUT; 1302 break; 1303 } 1304 } 1305 for (i = 0; i < count; i++) { 1306 wids[i].size = wilc_wlan_cfg_get_val(vif->wilc, 1307 wids[i].id, 1308 wids[i].val, 1309 wids[i].size); 1310 } 1311 } else if (mode == WILC_SET_CFG) { 1312 for (i = 0; i < count; i++) { 1313 if (!wilc_wlan_cfg_set(vif, !i, 1314 wids[i].id, 1315 wids[i].val, 1316 wids[i].size, 1317 (i == count - 1), 1318 drv)) { 1319 ret = -ETIMEDOUT; 1320 break; 1321 } 1322 } 1323 } 1324 1325 return ret; 1326 } 1327 1328 static int init_chip(struct net_device *dev) 1329 { 1330 u32 chipid; 1331 u32 reg; 1332 int ret = 0; 1333 struct wilc_vif *vif = netdev_priv(dev); 1334 struct wilc *wilc = vif->wilc; 1335 1336 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); 1337 1338 chipid = wilc_get_chipid(wilc, true); 1339 1340 if ((chipid & 0xfff) != 0xa0) { 1341 ret = wilc->hif_func->hif_read_reg(wilc, 1342 WILC_CORTUS_RESET_MUX_SEL, 1343 ®); 1344 if (ret) { 1345 netdev_err(dev, "fail read reg 0x1118\n"); 1346 goto release; 1347 } 1348 reg |= BIT(0); 1349 ret = wilc->hif_func->hif_write_reg(wilc, 1350 WILC_CORTUS_RESET_MUX_SEL, 1351 reg); 1352 if (ret) { 1353 netdev_err(dev, "fail write reg 0x1118\n"); 1354 goto release; 1355 } 1356 ret = wilc->hif_func->hif_write_reg(wilc, 1357 WILC_CORTUS_BOOT_REGISTER, 1358 WILC_CORTUS_BOOT_FROM_IRAM); 1359 if (ret) { 1360 netdev_err(dev, "fail write reg 0xc0000\n"); 1361 goto release; 1362 } 1363 } 1364 1365 release: 1366 release_bus(wilc, WILC_BUS_RELEASE_ONLY); 1367 1368 return ret; 1369 } 1370 1371 u32 wilc_get_chipid(struct wilc *wilc, bool update) 1372 { 1373 static u32 chipid; 1374 u32 tempchipid = 0; 1375 u32 rfrevid = 0; 1376 1377 if (chipid == 0 || update) { 1378 wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid); 1379 wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID, 1380 &rfrevid); 1381 if (!is_wilc1000(tempchipid)) { 1382 chipid = 0; 1383 return chipid; 1384 } 1385 if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */ 1386 if (rfrevid != 0x1) 1387 tempchipid = WILC_1000_BASE_ID_2A_REV1; 1388 } else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */ 1389 if (rfrevid == 0x4) 1390 tempchipid = WILC_1000_BASE_ID_2B_REV1; 1391 else if (rfrevid != 0x3) 1392 tempchipid = WILC_1000_BASE_ID_2B_REV2; 1393 } 1394 1395 chipid = tempchipid; 1396 } 1397 return chipid; 1398 } 1399 1400 int wilc_wlan_init(struct net_device *dev) 1401 { 1402 int ret = 0; 1403 struct wilc_vif *vif = netdev_priv(dev); 1404 struct wilc *wilc; 1405 1406 wilc = vif->wilc; 1407 1408 wilc->quit = 0; 1409 1410 if (wilc->hif_func->hif_init(wilc, false)) { 1411 ret = -EIO; 1412 goto fail; 1413 } 1414 1415 if (!wilc->tx_buffer) 1416 wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL); 1417 1418 if (!wilc->tx_buffer) { 1419 ret = -ENOBUFS; 1420 goto fail; 1421 } 1422 1423 if (!wilc->rx_buffer) 1424 wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL); 1425 1426 if (!wilc->rx_buffer) { 1427 ret = -ENOBUFS; 1428 goto fail; 1429 } 1430 1431 if (init_chip(dev)) { 1432 ret = -EIO; 1433 goto fail; 1434 } 1435 1436 return 0; 1437 1438 fail: 1439 1440 kfree(wilc->rx_buffer); 1441 wilc->rx_buffer = NULL; 1442 kfree(wilc->tx_buffer); 1443 wilc->tx_buffer = NULL; 1444 1445 return ret; 1446 } 1447