1/* 2 * drivers/net/wireless/mwl8k.c 3 * Driver for Marvell TOPDOG 802.11 Wireless cards 4 * 5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc. 6 * 7 * This file is licensed under the terms of the GNU General Public 8 * License version 2. This program is licensed "as is" without any 9 * warranty of any kind, whether express or implied. 10 */ 11 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/sched.h> 16#include <linux/spinlock.h> 17#include <linux/list.h> 18#include <linux/pci.h> 19#include <linux/delay.h> 20#include <linux/completion.h> 21#include <linux/etherdevice.h> 22#include <linux/slab.h> 23#include <net/mac80211.h> 24#include <linux/moduleparam.h> 25#include <linux/firmware.h> 26#include <linux/workqueue.h> 27 28#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 29#define MWL8K_NAME KBUILD_MODNAME 30#define MWL8K_VERSION "0.12" 31 32/* Register definitions */ 33#define MWL8K_HIU_GEN_PTR 0x00000c10 34#define MWL8K_MODE_STA 0x0000005a 35#define MWL8K_MODE_AP 0x000000a5 36#define MWL8K_HIU_INT_CODE 0x00000c14 37#define MWL8K_FWSTA_READY 0xf0f1f2f4 38#define MWL8K_FWAP_READY 0xf1f2f4a5 39#define MWL8K_INT_CODE_CMD_FINISHED 0x00000005 40#define MWL8K_HIU_SCRATCH 0x00000c40 41 42/* Host->device communications */ 43#define MWL8K_HIU_H2A_INTERRUPT_EVENTS 0x00000c18 44#define MWL8K_HIU_H2A_INTERRUPT_STATUS 0x00000c1c 45#define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20 46#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24 47#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28 48#define MWL8K_H2A_INT_DUMMY (1 << 20) 49#define MWL8K_H2A_INT_RESET (1 << 15) 50#define MWL8K_H2A_INT_DOORBELL (1 << 1) 51#define MWL8K_H2A_INT_PPA_READY (1 << 0) 52 53/* Device->host communications */ 54#define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c 55#define MWL8K_HIU_A2H_INTERRUPT_STATUS 0x00000c30 56#define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34 57#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38 58#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c 59#define MWL8K_A2H_INT_DUMMY (1 << 20) 60#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11) 61#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10) 62#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7) 63#define MWL8K_A2H_INT_RADIO_ON (1 << 6) 64#define MWL8K_A2H_INT_RADIO_OFF (1 << 5) 65#define MWL8K_A2H_INT_MAC_EVENT (1 << 3) 66#define MWL8K_A2H_INT_OPC_DONE (1 << 2) 67#define MWL8K_A2H_INT_RX_READY (1 << 1) 68#define MWL8K_A2H_INT_TX_DONE (1 << 0) 69 70#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ 71 MWL8K_A2H_INT_CHNL_SWITCHED | \ 72 MWL8K_A2H_INT_QUEUE_EMPTY | \ 73 MWL8K_A2H_INT_RADAR_DETECT | \ 74 MWL8K_A2H_INT_RADIO_ON | \ 75 MWL8K_A2H_INT_RADIO_OFF | \ 76 MWL8K_A2H_INT_MAC_EVENT | \ 77 MWL8K_A2H_INT_OPC_DONE | \ 78 MWL8K_A2H_INT_RX_READY | \ 79 MWL8K_A2H_INT_TX_DONE) 80 81#define MWL8K_RX_QUEUES 1 82#define MWL8K_TX_QUEUES 4 83 84struct rxd_ops { 85 int rxd_size; 86 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); 87 void (*rxd_refill)(void *rxd, dma_addr_t addr, int len); 88 int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status, 89 __le16 *qos, s8 *noise); 90}; 91 92struct mwl8k_device_info { 93 char *part_name; 94 char *helper_image; 95 char *fw_image; 96 struct rxd_ops *ap_rxd_ops; 97}; 98 99struct mwl8k_rx_queue { 100 int rxd_count; 101 102 /* hw receives here */ 103 int head; 104 105 /* refill descs here */ 106 int tail; 107 108 void *rxd; 109 dma_addr_t rxd_dma; 110 struct { 111 struct sk_buff *skb; 112 DEFINE_DMA_UNMAP_ADDR(dma); 113 } *buf; 114}; 115 116struct mwl8k_tx_queue { 117 /* hw transmits here */ 118 int head; 119 120 /* sw appends here */ 121 int tail; 122 123 unsigned int len; 124 struct mwl8k_tx_desc *txd; 125 dma_addr_t txd_dma; 126 struct sk_buff **skb; 127}; 128 129struct mwl8k_priv { 130 struct ieee80211_hw *hw; 131 struct pci_dev *pdev; 132 133 struct mwl8k_device_info *device_info; 134 135 void __iomem *sram; 136 void __iomem *regs; 137 138 /* firmware */ 139 struct firmware *fw_helper; 140 struct firmware *fw_ucode; 141 142 /* hardware/firmware parameters */ 143 bool ap_fw; 144 struct rxd_ops *rxd_ops; 145 struct ieee80211_supported_band band_24; 146 struct ieee80211_channel channels_24[14]; 147 struct ieee80211_rate rates_24[14]; 148 struct ieee80211_supported_band band_50; 149 struct ieee80211_channel channels_50[4]; 150 struct ieee80211_rate rates_50[9]; 151 u32 ap_macids_supported; 152 u32 sta_macids_supported; 153 154 /* firmware access */ 155 struct mutex fw_mutex; 156 struct task_struct *fw_mutex_owner; 157 int fw_mutex_depth; 158 struct completion *hostcmd_wait; 159 160 /* lock held over TX and TX reap */ 161 spinlock_t tx_lock; 162 163 /* TX quiesce completion, protected by fw_mutex and tx_lock */ 164 struct completion *tx_wait; 165 166 /* List of interfaces. */ 167 u32 macids_used; 168 struct list_head vif_list; 169 170 /* power management status cookie from firmware */ 171 u32 *cookie; 172 dma_addr_t cookie_dma; 173 174 u16 num_mcaddrs; 175 u8 hw_rev; 176 u32 fw_rev; 177 178 /* 179 * Running count of TX packets in flight, to avoid 180 * iterating over the transmit rings each time. 181 */ 182 int pending_tx_pkts; 183 184 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 185 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 186 187 bool radio_on; 188 bool radio_short_preamble; 189 bool sniffer_enabled; 190 bool wmm_enabled; 191 192 bool capture_beacon; 193 u8 capture_bssid[ETH_ALEN]; 194 struct sk_buff *beacon_skb; 195 196 /* 197 * This FJ worker has to be global as it is scheduled from the 198 * RX handler. At this point we don't know which interface it 199 * belongs to until the list of bssids waiting to complete join 200 * is checked. 201 */ 202 struct work_struct finalize_join_worker; 203 204 /* Tasklet to perform TX reclaim. */ 205 struct tasklet_struct poll_tx_task; 206 207 /* Tasklet to perform RX. */ 208 struct tasklet_struct poll_rx_task; 209 210 /* Most recently reported noise in dBm */ 211 s8 noise; 212}; 213 214/* Per interface specific private data */ 215struct mwl8k_vif { 216 struct list_head list; 217 struct ieee80211_vif *vif; 218 219 /* Firmware macid for this vif. */ 220 int macid; 221 222 /* Non AMPDU sequence number assigned by driver. */ 223 u16 seqno; 224}; 225#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 226 227struct mwl8k_sta { 228 /* Index into station database. Returned by UPDATE_STADB. */ 229 u8 peer_id; 230}; 231#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) 232 233static const struct ieee80211_channel mwl8k_channels_24[] = { 234 { .center_freq = 2412, .hw_value = 1, }, 235 { .center_freq = 2417, .hw_value = 2, }, 236 { .center_freq = 2422, .hw_value = 3, }, 237 { .center_freq = 2427, .hw_value = 4, }, 238 { .center_freq = 2432, .hw_value = 5, }, 239 { .center_freq = 2437, .hw_value = 6, }, 240 { .center_freq = 2442, .hw_value = 7, }, 241 { .center_freq = 2447, .hw_value = 8, }, 242 { .center_freq = 2452, .hw_value = 9, }, 243 { .center_freq = 2457, .hw_value = 10, }, 244 { .center_freq = 2462, .hw_value = 11, }, 245 { .center_freq = 2467, .hw_value = 12, }, 246 { .center_freq = 2472, .hw_value = 13, }, 247 { .center_freq = 2484, .hw_value = 14, }, 248}; 249 250static const struct ieee80211_rate mwl8k_rates_24[] = { 251 { .bitrate = 10, .hw_value = 2, }, 252 { .bitrate = 20, .hw_value = 4, }, 253 { .bitrate = 55, .hw_value = 11, }, 254 { .bitrate = 110, .hw_value = 22, }, 255 { .bitrate = 220, .hw_value = 44, }, 256 { .bitrate = 60, .hw_value = 12, }, 257 { .bitrate = 90, .hw_value = 18, }, 258 { .bitrate = 120, .hw_value = 24, }, 259 { .bitrate = 180, .hw_value = 36, }, 260 { .bitrate = 240, .hw_value = 48, }, 261 { .bitrate = 360, .hw_value = 72, }, 262 { .bitrate = 480, .hw_value = 96, }, 263 { .bitrate = 540, .hw_value = 108, }, 264 { .bitrate = 720, .hw_value = 144, }, 265}; 266 267static const struct ieee80211_channel mwl8k_channels_50[] = { 268 { .center_freq = 5180, .hw_value = 36, }, 269 { .center_freq = 5200, .hw_value = 40, }, 270 { .center_freq = 5220, .hw_value = 44, }, 271 { .center_freq = 5240, .hw_value = 48, }, 272}; 273 274static const struct ieee80211_rate mwl8k_rates_50[] = { 275 { .bitrate = 60, .hw_value = 12, }, 276 { .bitrate = 90, .hw_value = 18, }, 277 { .bitrate = 120, .hw_value = 24, }, 278 { .bitrate = 180, .hw_value = 36, }, 279 { .bitrate = 240, .hw_value = 48, }, 280 { .bitrate = 360, .hw_value = 72, }, 281 { .bitrate = 480, .hw_value = 96, }, 282 { .bitrate = 540, .hw_value = 108, }, 283 { .bitrate = 720, .hw_value = 144, }, 284}; 285 286/* Set or get info from Firmware */ 287#define MWL8K_CMD_SET 0x0001 288#define MWL8K_CMD_GET 0x0000 289 290/* Firmware command codes */ 291#define MWL8K_CMD_CODE_DNLD 0x0001 292#define MWL8K_CMD_GET_HW_SPEC 0x0003 293#define MWL8K_CMD_SET_HW_SPEC 0x0004 294#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 295#define MWL8K_CMD_GET_STAT 0x0014 296#define MWL8K_CMD_RADIO_CONTROL 0x001c 297#define MWL8K_CMD_RF_TX_POWER 0x001e 298#define MWL8K_CMD_RF_ANTENNA 0x0020 299#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */ 300#define MWL8K_CMD_SET_PRE_SCAN 0x0107 301#define MWL8K_CMD_SET_POST_SCAN 0x0108 302#define MWL8K_CMD_SET_RF_CHANNEL 0x010a 303#define MWL8K_CMD_SET_AID 0x010d 304#define MWL8K_CMD_SET_RATE 0x0110 305#define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111 306#define MWL8K_CMD_RTS_THRESHOLD 0x0113 307#define MWL8K_CMD_SET_SLOT 0x0114 308#define MWL8K_CMD_SET_EDCA_PARAMS 0x0115 309#define MWL8K_CMD_SET_WMM_MODE 0x0123 310#define MWL8K_CMD_MIMO_CONFIG 0x0125 311#define MWL8K_CMD_USE_FIXED_RATE 0x0126 312#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 313#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ 314#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 315#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ 316#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ 317#define MWL8K_CMD_UPDATE_STADB 0x1123 318 319static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) 320{ 321 u16 command = le16_to_cpu(cmd); 322 323#define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\ 324 snprintf(buf, bufsize, "%s", #x);\ 325 return buf;\ 326 } while (0) 327 switch (command & ~0x8000) { 328 MWL8K_CMDNAME(CODE_DNLD); 329 MWL8K_CMDNAME(GET_HW_SPEC); 330 MWL8K_CMDNAME(SET_HW_SPEC); 331 MWL8K_CMDNAME(MAC_MULTICAST_ADR); 332 MWL8K_CMDNAME(GET_STAT); 333 MWL8K_CMDNAME(RADIO_CONTROL); 334 MWL8K_CMDNAME(RF_TX_POWER); 335 MWL8K_CMDNAME(RF_ANTENNA); 336 MWL8K_CMDNAME(SET_BEACON); 337 MWL8K_CMDNAME(SET_PRE_SCAN); 338 MWL8K_CMDNAME(SET_POST_SCAN); 339 MWL8K_CMDNAME(SET_RF_CHANNEL); 340 MWL8K_CMDNAME(SET_AID); 341 MWL8K_CMDNAME(SET_RATE); 342 MWL8K_CMDNAME(SET_FINALIZE_JOIN); 343 MWL8K_CMDNAME(RTS_THRESHOLD); 344 MWL8K_CMDNAME(SET_SLOT); 345 MWL8K_CMDNAME(SET_EDCA_PARAMS); 346 MWL8K_CMDNAME(SET_WMM_MODE); 347 MWL8K_CMDNAME(MIMO_CONFIG); 348 MWL8K_CMDNAME(USE_FIXED_RATE); 349 MWL8K_CMDNAME(ENABLE_SNIFFER); 350 MWL8K_CMDNAME(SET_MAC_ADDR); 351 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 352 MWL8K_CMDNAME(BSS_START); 353 MWL8K_CMDNAME(SET_NEW_STN); 354 MWL8K_CMDNAME(UPDATE_STADB); 355 default: 356 snprintf(buf, bufsize, "0x%x", cmd); 357 } 358#undef MWL8K_CMDNAME 359 360 return buf; 361} 362 363/* Hardware and firmware reset */ 364static void mwl8k_hw_reset(struct mwl8k_priv *priv) 365{ 366 iowrite32(MWL8K_H2A_INT_RESET, 367 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 368 iowrite32(MWL8K_H2A_INT_RESET, 369 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 370 msleep(20); 371} 372 373/* Release fw image */ 374static void mwl8k_release_fw(struct firmware **fw) 375{ 376 if (*fw == NULL) 377 return; 378 release_firmware(*fw); 379 *fw = NULL; 380} 381 382static void mwl8k_release_firmware(struct mwl8k_priv *priv) 383{ 384 mwl8k_release_fw(&priv->fw_ucode); 385 mwl8k_release_fw(&priv->fw_helper); 386} 387 388/* Request fw image */ 389static int mwl8k_request_fw(struct mwl8k_priv *priv, 390 const char *fname, struct firmware **fw) 391{ 392 /* release current image */ 393 if (*fw != NULL) 394 mwl8k_release_fw(fw); 395 396 return request_firmware((const struct firmware **)fw, 397 fname, &priv->pdev->dev); 398} 399 400static int mwl8k_request_firmware(struct mwl8k_priv *priv) 401{ 402 struct mwl8k_device_info *di = priv->device_info; 403 int rc; 404 405 if (di->helper_image != NULL) { 406 rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper); 407 if (rc) { 408 printk(KERN_ERR "%s: Error requesting helper " 409 "firmware file %s\n", pci_name(priv->pdev), 410 di->helper_image); 411 return rc; 412 } 413 } 414 415 rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode); 416 if (rc) { 417 printk(KERN_ERR "%s: Error requesting firmware file %s\n", 418 pci_name(priv->pdev), di->fw_image); 419 mwl8k_release_fw(&priv->fw_helper); 420 return rc; 421 } 422 423 return 0; 424} 425 426struct mwl8k_cmd_pkt { 427 __le16 code; 428 __le16 length; 429 __u8 seq_num; 430 __u8 macid; 431 __le16 result; 432 char payload[0]; 433} __packed; 434 435/* 436 * Firmware loading. 437 */ 438static int 439mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length) 440{ 441 void __iomem *regs = priv->regs; 442 dma_addr_t dma_addr; 443 int loops; 444 445 dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE); 446 if (pci_dma_mapping_error(priv->pdev, dma_addr)) 447 return -ENOMEM; 448 449 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); 450 iowrite32(0, regs + MWL8K_HIU_INT_CODE); 451 iowrite32(MWL8K_H2A_INT_DOORBELL, 452 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 453 iowrite32(MWL8K_H2A_INT_DUMMY, 454 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 455 456 loops = 1000; 457 do { 458 u32 int_code; 459 460 int_code = ioread32(regs + MWL8K_HIU_INT_CODE); 461 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) { 462 iowrite32(0, regs + MWL8K_HIU_INT_CODE); 463 break; 464 } 465 466 cond_resched(); 467 udelay(1); 468 } while (--loops); 469 470 pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE); 471 472 return loops ? 0 : -ETIMEDOUT; 473} 474 475static int mwl8k_load_fw_image(struct mwl8k_priv *priv, 476 const u8 *data, size_t length) 477{ 478 struct mwl8k_cmd_pkt *cmd; 479 int done; 480 int rc = 0; 481 482 cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL); 483 if (cmd == NULL) 484 return -ENOMEM; 485 486 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); 487 cmd->seq_num = 0; 488 cmd->macid = 0; 489 cmd->result = 0; 490 491 done = 0; 492 while (length) { 493 int block_size = length > 256 ? 256 : length; 494 495 memcpy(cmd->payload, data + done, block_size); 496 cmd->length = cpu_to_le16(block_size); 497 498 rc = mwl8k_send_fw_load_cmd(priv, cmd, 499 sizeof(*cmd) + block_size); 500 if (rc) 501 break; 502 503 done += block_size; 504 length -= block_size; 505 } 506 507 if (!rc) { 508 cmd->length = 0; 509 rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd)); 510 } 511 512 kfree(cmd); 513 514 return rc; 515} 516 517static int mwl8k_feed_fw_image(struct mwl8k_priv *priv, 518 const u8 *data, size_t length) 519{ 520 unsigned char *buffer; 521 int may_continue, rc = 0; 522 u32 done, prev_block_size; 523 524 buffer = kmalloc(1024, GFP_KERNEL); 525 if (buffer == NULL) 526 return -ENOMEM; 527 528 done = 0; 529 prev_block_size = 0; 530 may_continue = 1000; 531 while (may_continue > 0) { 532 u32 block_size; 533 534 block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH); 535 if (block_size & 1) { 536 block_size &= ~1; 537 may_continue--; 538 } else { 539 done += prev_block_size; 540 length -= prev_block_size; 541 } 542 543 if (block_size > 1024 || block_size > length) { 544 rc = -EOVERFLOW; 545 break; 546 } 547 548 if (length == 0) { 549 rc = 0; 550 break; 551 } 552 553 if (block_size == 0) { 554 rc = -EPROTO; 555 may_continue--; 556 udelay(1); 557 continue; 558 } 559 560 prev_block_size = block_size; 561 memcpy(buffer, data + done, block_size); 562 563 rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size); 564 if (rc) 565 break; 566 } 567 568 if (!rc && length != 0) 569 rc = -EREMOTEIO; 570 571 kfree(buffer); 572 573 return rc; 574} 575 576static int mwl8k_load_firmware(struct ieee80211_hw *hw) 577{ 578 struct mwl8k_priv *priv = hw->priv; 579 struct firmware *fw = priv->fw_ucode; 580 int rc; 581 int loops; 582 583 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) { 584 struct firmware *helper = priv->fw_helper; 585 586 if (helper == NULL) { 587 printk(KERN_ERR "%s: helper image needed but none " 588 "given\n", pci_name(priv->pdev)); 589 return -EINVAL; 590 } 591 592 rc = mwl8k_load_fw_image(priv, helper->data, helper->size); 593 if (rc) { 594 printk(KERN_ERR "%s: unable to load firmware " 595 "helper image\n", pci_name(priv->pdev)); 596 return rc; 597 } 598 msleep(5); 599 600 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); 601 } else { 602 rc = mwl8k_load_fw_image(priv, fw->data, fw->size); 603 } 604 605 if (rc) { 606 printk(KERN_ERR "%s: unable to load firmware image\n", 607 pci_name(priv->pdev)); 608 return rc; 609 } 610 611 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); 612 613 loops = 500000; 614 do { 615 u32 ready_code; 616 617 ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE); 618 if (ready_code == MWL8K_FWAP_READY) { 619 priv->ap_fw = 1; 620 break; 621 } else if (ready_code == MWL8K_FWSTA_READY) { 622 priv->ap_fw = 0; 623 break; 624 } 625 626 cond_resched(); 627 udelay(1); 628 } while (--loops); 629 630 return loops ? 0 : -ETIMEDOUT; 631} 632 633 634/* DMA header used by firmware and hardware. */ 635struct mwl8k_dma_data { 636 __le16 fwlen; 637 struct ieee80211_hdr wh; 638 char data[0]; 639} __packed; 640 641/* Routines to add/remove DMA header from skb. */ 642static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos) 643{ 644 struct mwl8k_dma_data *tr; 645 int hdrlen; 646 647 tr = (struct mwl8k_dma_data *)skb->data; 648 hdrlen = ieee80211_hdrlen(tr->wh.frame_control); 649 650 if (hdrlen != sizeof(tr->wh)) { 651 if (ieee80211_is_data_qos(tr->wh.frame_control)) { 652 memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2); 653 *((__le16 *)(tr->data - 2)) = qos; 654 } else { 655 memmove(tr->data - hdrlen, &tr->wh, hdrlen); 656 } 657 } 658 659 if (hdrlen != sizeof(*tr)) 660 skb_pull(skb, sizeof(*tr) - hdrlen); 661} 662 663static inline void mwl8k_add_dma_header(struct sk_buff *skb) 664{ 665 struct ieee80211_hdr *wh; 666 int hdrlen; 667 struct mwl8k_dma_data *tr; 668 669 /* 670 * Add a firmware DMA header; the firmware requires that we 671 * present a 2-byte payload length followed by a 4-address 672 * header (without QoS field), followed (optionally) by any 673 * WEP/ExtIV header (but only filled in for CCMP). 674 */ 675 wh = (struct ieee80211_hdr *)skb->data; 676 677 hdrlen = ieee80211_hdrlen(wh->frame_control); 678 if (hdrlen != sizeof(*tr)) 679 skb_push(skb, sizeof(*tr) - hdrlen); 680 681 if (ieee80211_is_data_qos(wh->frame_control)) 682 hdrlen -= 2; 683 684 tr = (struct mwl8k_dma_data *)skb->data; 685 if (wh != &tr->wh) 686 memmove(&tr->wh, wh, hdrlen); 687 if (hdrlen != sizeof(tr->wh)) 688 memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen); 689 690 /* 691 * Firmware length is the length of the fully formed "802.11 692 * payload". That is, everything except for the 802.11 header. 693 * This includes all crypto material including the MIC. 694 */ 695 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr)); 696} 697 698 699/* 700 * Packet reception for 88w8366 AP firmware. 701 */ 702struct mwl8k_rxd_8366_ap { 703 __le16 pkt_len; 704 __u8 sq2; 705 __u8 rate; 706 __le32 pkt_phys_addr; 707 __le32 next_rxd_phys_addr; 708 __le16 qos_control; 709 __le16 htsig2; 710 __le32 hw_rssi_info; 711 __le32 hw_noise_floor_info; 712 __u8 noise_floor; 713 __u8 pad0[3]; 714 __u8 rssi; 715 __u8 rx_status; 716 __u8 channel; 717 __u8 rx_ctrl; 718} __packed; 719 720#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80 721#define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40 722#define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f) 723 724#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80 725 726static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr) 727{ 728 struct mwl8k_rxd_8366_ap *rxd = _rxd; 729 730 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); 731 rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST; 732} 733 734static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) 735{ 736 struct mwl8k_rxd_8366_ap *rxd = _rxd; 737 738 rxd->pkt_len = cpu_to_le16(len); 739 rxd->pkt_phys_addr = cpu_to_le32(addr); 740 wmb(); 741 rxd->rx_ctrl = 0; 742} 743 744static int 745mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, 746 __le16 *qos, s8 *noise) 747{ 748 struct mwl8k_rxd_8366_ap *rxd = _rxd; 749 750 if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST)) 751 return -1; 752 rmb(); 753 754 memset(status, 0, sizeof(*status)); 755 756 status->signal = -rxd->rssi; 757 *noise = -rxd->noise_floor; 758 759 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { 760 status->flag |= RX_FLAG_HT; 761 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ) 762 status->flag |= RX_FLAG_40MHZ; 763 status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate); 764 } else { 765 int i; 766 767 for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) { 768 if (mwl8k_rates_24[i].hw_value == rxd->rate) { 769 status->rate_idx = i; 770 break; 771 } 772 } 773 } 774 775 if (rxd->channel > 14) { 776 status->band = IEEE80211_BAND_5GHZ; 777 if (!(status->flag & RX_FLAG_HT)) 778 status->rate_idx -= 5; 779 } else { 780 status->band = IEEE80211_BAND_2GHZ; 781 } 782 status->freq = ieee80211_channel_to_frequency(rxd->channel); 783 784 *qos = rxd->qos_control; 785 786 return le16_to_cpu(rxd->pkt_len); 787} 788 789static struct rxd_ops rxd_8366_ap_ops = { 790 .rxd_size = sizeof(struct mwl8k_rxd_8366_ap), 791 .rxd_init = mwl8k_rxd_8366_ap_init, 792 .rxd_refill = mwl8k_rxd_8366_ap_refill, 793 .rxd_process = mwl8k_rxd_8366_ap_process, 794}; 795 796/* 797 * Packet reception for STA firmware. 798 */ 799struct mwl8k_rxd_sta { 800 __le16 pkt_len; 801 __u8 link_quality; 802 __u8 noise_level; 803 __le32 pkt_phys_addr; 804 __le32 next_rxd_phys_addr; 805 __le16 qos_control; 806 __le16 rate_info; 807 __le32 pad0[4]; 808 __u8 rssi; 809 __u8 channel; 810 __le16 pad1; 811 __u8 rx_ctrl; 812 __u8 rx_status; 813 __u8 pad2[2]; 814} __packed; 815 816#define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000 817#define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3) 818#define MWL8K_STA_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f) 819#define MWL8K_STA_RATE_INFO_40MHZ 0x0004 820#define MWL8K_STA_RATE_INFO_SHORTGI 0x0002 821#define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001 822 823#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02 824 825static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr) 826{ 827 struct mwl8k_rxd_sta *rxd = _rxd; 828 829 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); 830 rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST; 831} 832 833static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) 834{ 835 struct mwl8k_rxd_sta *rxd = _rxd; 836 837 rxd->pkt_len = cpu_to_le16(len); 838 rxd->pkt_phys_addr = cpu_to_le32(addr); 839 wmb(); 840 rxd->rx_ctrl = 0; 841} 842 843static int 844mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, 845 __le16 *qos, s8 *noise) 846{ 847 struct mwl8k_rxd_sta *rxd = _rxd; 848 u16 rate_info; 849 850 if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST)) 851 return -1; 852 rmb(); 853 854 rate_info = le16_to_cpu(rxd->rate_info); 855 856 memset(status, 0, sizeof(*status)); 857 858 status->signal = -rxd->rssi; 859 *noise = -rxd->noise_level; 860 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); 861 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); 862 863 if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE) 864 status->flag |= RX_FLAG_SHORTPRE; 865 if (rate_info & MWL8K_STA_RATE_INFO_40MHZ) 866 status->flag |= RX_FLAG_40MHZ; 867 if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI) 868 status->flag |= RX_FLAG_SHORT_GI; 869 if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT) 870 status->flag |= RX_FLAG_HT; 871 872 if (rxd->channel > 14) { 873 status->band = IEEE80211_BAND_5GHZ; 874 if (!(status->flag & RX_FLAG_HT)) 875 status->rate_idx -= 5; 876 } else { 877 status->band = IEEE80211_BAND_2GHZ; 878 } 879 status->freq = ieee80211_channel_to_frequency(rxd->channel); 880 881 *qos = rxd->qos_control; 882 883 return le16_to_cpu(rxd->pkt_len); 884} 885 886static struct rxd_ops rxd_sta_ops = { 887 .rxd_size = sizeof(struct mwl8k_rxd_sta), 888 .rxd_init = mwl8k_rxd_sta_init, 889 .rxd_refill = mwl8k_rxd_sta_refill, 890 .rxd_process = mwl8k_rxd_sta_process, 891}; 892 893 894#define MWL8K_RX_DESCS 256 895#define MWL8K_RX_MAXSZ 3800 896 897static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) 898{ 899 struct mwl8k_priv *priv = hw->priv; 900 struct mwl8k_rx_queue *rxq = priv->rxq + index; 901 int size; 902 int i; 903 904 rxq->rxd_count = 0; 905 rxq->head = 0; 906 rxq->tail = 0; 907 908 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size; 909 910 rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); 911 if (rxq->rxd == NULL) { 912 wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); 913 return -ENOMEM; 914 } 915 memset(rxq->rxd, 0, size); 916 917 rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); 918 if (rxq->buf == NULL) { 919 wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); 920 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); 921 return -ENOMEM; 922 } 923 memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf)); 924 925 for (i = 0; i < MWL8K_RX_DESCS; i++) { 926 int desc_size; 927 void *rxd; 928 int nexti; 929 dma_addr_t next_dma_addr; 930 931 desc_size = priv->rxd_ops->rxd_size; 932 rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size); 933 934 nexti = i + 1; 935 if (nexti == MWL8K_RX_DESCS) 936 nexti = 0; 937 next_dma_addr = rxq->rxd_dma + (nexti * desc_size); 938 939 priv->rxd_ops->rxd_init(rxd, next_dma_addr); 940 } 941 942 return 0; 943} 944 945static int rxq_refill(struct ieee80211_hw *hw, int index, int limit) 946{ 947 struct mwl8k_priv *priv = hw->priv; 948 struct mwl8k_rx_queue *rxq = priv->rxq + index; 949 int refilled; 950 951 refilled = 0; 952 while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) { 953 struct sk_buff *skb; 954 dma_addr_t addr; 955 int rx; 956 void *rxd; 957 958 skb = dev_alloc_skb(MWL8K_RX_MAXSZ); 959 if (skb == NULL) 960 break; 961 962 addr = pci_map_single(priv->pdev, skb->data, 963 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE); 964 965 rxq->rxd_count++; 966 rx = rxq->tail++; 967 if (rxq->tail == MWL8K_RX_DESCS) 968 rxq->tail = 0; 969 rxq->buf[rx].skb = skb; 970 dma_unmap_addr_set(&rxq->buf[rx], dma, addr); 971 972 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size); 973 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ); 974 975 refilled++; 976 } 977 978 return refilled; 979} 980 981/* Must be called only when the card's reception is completely halted */ 982static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index) 983{ 984 struct mwl8k_priv *priv = hw->priv; 985 struct mwl8k_rx_queue *rxq = priv->rxq + index; 986 int i; 987 988 for (i = 0; i < MWL8K_RX_DESCS; i++) { 989 if (rxq->buf[i].skb != NULL) { 990 pci_unmap_single(priv->pdev, 991 dma_unmap_addr(&rxq->buf[i], dma), 992 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 993 dma_unmap_addr_set(&rxq->buf[i], dma, 0); 994 995 kfree_skb(rxq->buf[i].skb); 996 rxq->buf[i].skb = NULL; 997 } 998 } 999 1000 kfree(rxq->buf); 1001 rxq->buf = NULL; 1002 1003 pci_free_consistent(priv->pdev, 1004 MWL8K_RX_DESCS * priv->rxd_ops->rxd_size, 1005 rxq->rxd, rxq->rxd_dma); 1006 rxq->rxd = NULL; 1007} 1008 1009 1010/* 1011 * Scan a list of BSSIDs to process for finalize join. 1012 * Allows for extension to process multiple BSSIDs. 1013 */ 1014static inline int 1015mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh) 1016{ 1017 return priv->capture_beacon && 1018 ieee80211_is_beacon(wh->frame_control) && 1019 !compare_ether_addr(wh->addr3, priv->capture_bssid); 1020} 1021 1022static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, 1023 struct sk_buff *skb) 1024{ 1025 struct mwl8k_priv *priv = hw->priv; 1026 1027 priv->capture_beacon = false; 1028 memset(priv->capture_bssid, 0, ETH_ALEN); 1029 1030 /* 1031 * Use GFP_ATOMIC as rxq_process is called from 1032 * the primary interrupt handler, memory allocation call 1033 * must not sleep. 1034 */ 1035 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC); 1036 if (priv->beacon_skb != NULL) 1037 ieee80211_queue_work(hw, &priv->finalize_join_worker); 1038} 1039 1040static int rxq_process(struct ieee80211_hw *hw, int index, int limit) 1041{ 1042 struct mwl8k_priv *priv = hw->priv; 1043 struct mwl8k_rx_queue *rxq = priv->rxq + index; 1044 int processed; 1045 1046 processed = 0; 1047 while (rxq->rxd_count && limit--) { 1048 struct sk_buff *skb; 1049 void *rxd; 1050 int pkt_len; 1051 struct ieee80211_rx_status status; 1052 __le16 qos; 1053 1054 skb = rxq->buf[rxq->head].skb; 1055 if (skb == NULL) 1056 break; 1057 1058 rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); 1059 1060 pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, 1061 &priv->noise); 1062 if (pkt_len < 0) 1063 break; 1064 1065 rxq->buf[rxq->head].skb = NULL; 1066 1067 pci_unmap_single(priv->pdev, 1068 dma_unmap_addr(&rxq->buf[rxq->head], dma), 1069 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 1070 dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); 1071 1072 rxq->head++; 1073 if (rxq->head == MWL8K_RX_DESCS) 1074 rxq->head = 0; 1075 1076 rxq->rxd_count--; 1077 1078 skb_put(skb, pkt_len); 1079 mwl8k_remove_dma_header(skb, qos); 1080 1081 /* 1082 * Check for a pending join operation. Save a 1083 * copy of the beacon and schedule a tasklet to 1084 * send a FINALIZE_JOIN command to the firmware. 1085 */ 1086 if (mwl8k_capture_bssid(priv, (void *)skb->data)) 1087 mwl8k_save_beacon(hw, skb); 1088 1089 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 1090 ieee80211_rx_irqsafe(hw, skb); 1091 1092 processed++; 1093 } 1094 1095 return processed; 1096} 1097 1098 1099/* 1100 * Packet transmission. 1101 */ 1102 1103#define MWL8K_TXD_STATUS_OK 0x00000001 1104#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002 1105#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004 1106#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008 1107#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000 1108 1109#define MWL8K_QOS_QLEN_UNSPEC 0xff00 1110#define MWL8K_QOS_ACK_POLICY_MASK 0x0060 1111#define MWL8K_QOS_ACK_POLICY_NORMAL 0x0000 1112#define MWL8K_QOS_ACK_POLICY_BLOCKACK 0x0060 1113#define MWL8K_QOS_EOSP 0x0010 1114 1115struct mwl8k_tx_desc { 1116 __le32 status; 1117 __u8 data_rate; 1118 __u8 tx_priority; 1119 __le16 qos_control; 1120 __le32 pkt_phys_addr; 1121 __le16 pkt_len; 1122 __u8 dest_MAC_addr[ETH_ALEN]; 1123 __le32 next_txd_phys_addr; 1124 __le32 reserved; 1125 __le16 rate_info; 1126 __u8 peer_id; 1127 __u8 tx_frag_cnt; 1128} __packed; 1129 1130#define MWL8K_TX_DESCS 128 1131 1132static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) 1133{ 1134 struct mwl8k_priv *priv = hw->priv; 1135 struct mwl8k_tx_queue *txq = priv->txq + index; 1136 int size; 1137 int i; 1138 1139 txq->len = 0; 1140 txq->head = 0; 1141 txq->tail = 0; 1142 1143 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc); 1144 1145 txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); 1146 if (txq->txd == NULL) { 1147 wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); 1148 return -ENOMEM; 1149 } 1150 memset(txq->txd, 0, size); 1151 1152 txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); 1153 if (txq->skb == NULL) { 1154 wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); 1155 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); 1156 return -ENOMEM; 1157 } 1158 memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb)); 1159 1160 for (i = 0; i < MWL8K_TX_DESCS; i++) { 1161 struct mwl8k_tx_desc *tx_desc; 1162 int nexti; 1163 1164 tx_desc = txq->txd + i; 1165 nexti = (i + 1) % MWL8K_TX_DESCS; 1166 1167 tx_desc->status = 0; 1168 tx_desc->next_txd_phys_addr = 1169 cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc)); 1170 } 1171 1172 return 0; 1173} 1174 1175static inline void mwl8k_tx_start(struct mwl8k_priv *priv) 1176{ 1177 iowrite32(MWL8K_H2A_INT_PPA_READY, 1178 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1179 iowrite32(MWL8K_H2A_INT_DUMMY, 1180 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1181 ioread32(priv->regs + MWL8K_HIU_INT_CODE); 1182} 1183 1184static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw) 1185{ 1186 struct mwl8k_priv *priv = hw->priv; 1187 int i; 1188 1189 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 1190 struct mwl8k_tx_queue *txq = priv->txq + i; 1191 int fw_owned = 0; 1192 int drv_owned = 0; 1193 int unused = 0; 1194 int desc; 1195 1196 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) { 1197 struct mwl8k_tx_desc *tx_desc = txq->txd + desc; 1198 u32 status; 1199 1200 status = le32_to_cpu(tx_desc->status); 1201 if (status & MWL8K_TXD_STATUS_FW_OWNED) 1202 fw_owned++; 1203 else 1204 drv_owned++; 1205 1206 if (tx_desc->pkt_len == 0) 1207 unused++; 1208 } 1209 1210 wiphy_err(hw->wiphy, 1211 "txq[%d] len=%d head=%d tail=%d " 1212 "fw_owned=%d drv_owned=%d unused=%d\n", 1213 i, 1214 txq->len, txq->head, txq->tail, 1215 fw_owned, drv_owned, unused); 1216 } 1217} 1218 1219/* 1220 * Must be called with priv->fw_mutex held and tx queues stopped. 1221 */ 1222#define MWL8K_TX_WAIT_TIMEOUT_MS 5000 1223 1224static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) 1225{ 1226 struct mwl8k_priv *priv = hw->priv; 1227 DECLARE_COMPLETION_ONSTACK(tx_wait); 1228 int retry; 1229 int rc; 1230 1231 might_sleep(); 1232 1233 /* 1234 * The TX queues are stopped at this point, so this test 1235 * doesn't need to take ->tx_lock. 1236 */ 1237 if (!priv->pending_tx_pkts) 1238 return 0; 1239 1240 retry = 0; 1241 rc = 0; 1242 1243 spin_lock_bh(&priv->tx_lock); 1244 priv->tx_wait = &tx_wait; 1245 while (!rc) { 1246 int oldcount; 1247 unsigned long timeout; 1248 1249 oldcount = priv->pending_tx_pkts; 1250 1251 spin_unlock_bh(&priv->tx_lock); 1252 timeout = wait_for_completion_timeout(&tx_wait, 1253 msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS)); 1254 spin_lock_bh(&priv->tx_lock); 1255 1256 if (timeout) { 1257 WARN_ON(priv->pending_tx_pkts); 1258 if (retry) { 1259 wiphy_notice(hw->wiphy, "tx rings drained\n"); 1260 } 1261 break; 1262 } 1263 1264 if (priv->pending_tx_pkts < oldcount) { 1265 wiphy_notice(hw->wiphy, 1266 "waiting for tx rings to drain (%d -> %d pkts)\n", 1267 oldcount, priv->pending_tx_pkts); 1268 retry = 1; 1269 continue; 1270 } 1271 1272 priv->tx_wait = NULL; 1273 1274 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", 1275 MWL8K_TX_WAIT_TIMEOUT_MS); 1276 mwl8k_dump_tx_rings(hw); 1277 1278 rc = -ETIMEDOUT; 1279 } 1280 spin_unlock_bh(&priv->tx_lock); 1281 1282 return rc; 1283} 1284 1285#define MWL8K_TXD_SUCCESS(status) \ 1286 ((status) & (MWL8K_TXD_STATUS_OK | \ 1287 MWL8K_TXD_STATUS_OK_RETRY | \ 1288 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1289 1290static int 1291mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) 1292{ 1293 struct mwl8k_priv *priv = hw->priv; 1294 struct mwl8k_tx_queue *txq = priv->txq + index; 1295 int processed; 1296 1297 processed = 0; 1298 while (txq->len > 0 && limit--) { 1299 int tx; 1300 struct mwl8k_tx_desc *tx_desc; 1301 unsigned long addr; 1302 int size; 1303 struct sk_buff *skb; 1304 struct ieee80211_tx_info *info; 1305 u32 status; 1306 1307 tx = txq->head; 1308 tx_desc = txq->txd + tx; 1309 1310 status = le32_to_cpu(tx_desc->status); 1311 1312 if (status & MWL8K_TXD_STATUS_FW_OWNED) { 1313 if (!force) 1314 break; 1315 tx_desc->status &= 1316 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED); 1317 } 1318 1319 txq->head = (tx + 1) % MWL8K_TX_DESCS; 1320 BUG_ON(txq->len == 0); 1321 txq->len--; 1322 priv->pending_tx_pkts--; 1323 1324 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1325 size = le16_to_cpu(tx_desc->pkt_len); 1326 skb = txq->skb[tx]; 1327 txq->skb[tx] = NULL; 1328 1329 BUG_ON(skb == NULL); 1330 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE); 1331 1332 mwl8k_remove_dma_header(skb, tx_desc->qos_control); 1333 1334 /* Mark descriptor as unused */ 1335 tx_desc->pkt_phys_addr = 0; 1336 tx_desc->pkt_len = 0; 1337 1338 info = IEEE80211_SKB_CB(skb); 1339 ieee80211_tx_info_clear_status(info); 1340 if (MWL8K_TXD_SUCCESS(status)) 1341 info->flags |= IEEE80211_TX_STAT_ACK; 1342 1343 ieee80211_tx_status_irqsafe(hw, skb); 1344 1345 processed++; 1346 } 1347 1348 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1349 ieee80211_wake_queue(hw, index); 1350 1351 return processed; 1352} 1353 1354/* must be called only when the card's transmit is completely halted */ 1355static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) 1356{ 1357 struct mwl8k_priv *priv = hw->priv; 1358 struct mwl8k_tx_queue *txq = priv->txq + index; 1359 1360 mwl8k_txq_reclaim(hw, index, INT_MAX, 1); 1361 1362 kfree(txq->skb); 1363 txq->skb = NULL; 1364 1365 pci_free_consistent(priv->pdev, 1366 MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc), 1367 txq->txd, txq->txd_dma); 1368 txq->txd = NULL; 1369} 1370 1371static int 1372mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) 1373{ 1374 struct mwl8k_priv *priv = hw->priv; 1375 struct ieee80211_tx_info *tx_info; 1376 struct mwl8k_vif *mwl8k_vif; 1377 struct ieee80211_hdr *wh; 1378 struct mwl8k_tx_queue *txq; 1379 struct mwl8k_tx_desc *tx; 1380 dma_addr_t dma; 1381 u32 txstatus; 1382 u8 txdatarate; 1383 u16 qos; 1384 1385 wh = (struct ieee80211_hdr *)skb->data; 1386 if (ieee80211_is_data_qos(wh->frame_control)) 1387 qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh))); 1388 else 1389 qos = 0; 1390 1391 mwl8k_add_dma_header(skb); 1392 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1393 1394 tx_info = IEEE80211_SKB_CB(skb); 1395 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1396 1397 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1398 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1399 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno); 1400 mwl8k_vif->seqno += 0x10; 1401 } 1402 1403 /* Setup firmware control bit fields for each frame type. */ 1404 txstatus = 0; 1405 txdatarate = 0; 1406 if (ieee80211_is_mgmt(wh->frame_control) || 1407 ieee80211_is_ctl(wh->frame_control)) { 1408 txdatarate = 0; 1409 qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP; 1410 } else if (ieee80211_is_data(wh->frame_control)) { 1411 txdatarate = 1; 1412 if (is_multicast_ether_addr(wh->addr1)) 1413 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX; 1414 1415 qos &= ~MWL8K_QOS_ACK_POLICY_MASK; 1416 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) 1417 qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK; 1418 else 1419 qos |= MWL8K_QOS_ACK_POLICY_NORMAL; 1420 } 1421 1422 dma = pci_map_single(priv->pdev, skb->data, 1423 skb->len, PCI_DMA_TODEVICE); 1424 1425 if (pci_dma_mapping_error(priv->pdev, dma)) { 1426 wiphy_debug(hw->wiphy, 1427 "failed to dma map skb, dropping TX frame.\n"); 1428 dev_kfree_skb(skb); 1429 return NETDEV_TX_OK; 1430 } 1431 1432 spin_lock_bh(&priv->tx_lock); 1433 1434 txq = priv->txq + index; 1435 1436 BUG_ON(txq->skb[txq->tail] != NULL); 1437 txq->skb[txq->tail] = skb; 1438 1439 tx = txq->txd + txq->tail; 1440 tx->data_rate = txdatarate; 1441 tx->tx_priority = index; 1442 tx->qos_control = cpu_to_le16(qos); 1443 tx->pkt_phys_addr = cpu_to_le32(dma); 1444 tx->pkt_len = cpu_to_le16(skb->len); 1445 tx->rate_info = 0; 1446 if (!priv->ap_fw && tx_info->control.sta != NULL) 1447 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; 1448 else 1449 tx->peer_id = 0; 1450 wmb(); 1451 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1452 1453 txq->len++; 1454 priv->pending_tx_pkts++; 1455 1456 txq->tail++; 1457 if (txq->tail == MWL8K_TX_DESCS) 1458 txq->tail = 0; 1459 1460 if (txq->head == txq->tail) 1461 ieee80211_stop_queue(hw, index); 1462 1463 mwl8k_tx_start(priv); 1464 1465 spin_unlock_bh(&priv->tx_lock); 1466 1467 return NETDEV_TX_OK; 1468} 1469 1470 1471/* 1472 * Firmware access. 1473 * 1474 * We have the following requirements for issuing firmware commands: 1475 * - Some commands require that the packet transmit path is idle when 1476 * the command is issued. (For simplicity, we'll just quiesce the 1477 * transmit path for every command.) 1478 * - There are certain sequences of commands that need to be issued to 1479 * the hardware sequentially, with no other intervening commands. 1480 * 1481 * This leads to an implementation of a "firmware lock" as a mutex that 1482 * can be taken recursively, and which is taken by both the low-level 1483 * command submission function (mwl8k_post_cmd) as well as any users of 1484 * that function that require issuing of an atomic sequence of commands, 1485 * and quiesces the transmit path whenever it's taken. 1486 */ 1487static int mwl8k_fw_lock(struct ieee80211_hw *hw) 1488{ 1489 struct mwl8k_priv *priv = hw->priv; 1490 1491 if (priv->fw_mutex_owner != current) { 1492 int rc; 1493 1494 mutex_lock(&priv->fw_mutex); 1495 ieee80211_stop_queues(hw); 1496 1497 rc = mwl8k_tx_wait_empty(hw); 1498 if (rc) { 1499 ieee80211_wake_queues(hw); 1500 mutex_unlock(&priv->fw_mutex); 1501 1502 return rc; 1503 } 1504 1505 priv->fw_mutex_owner = current; 1506 } 1507 1508 priv->fw_mutex_depth++; 1509 1510 return 0; 1511} 1512 1513static void mwl8k_fw_unlock(struct ieee80211_hw *hw) 1514{ 1515 struct mwl8k_priv *priv = hw->priv; 1516 1517 if (!--priv->fw_mutex_depth) { 1518 ieee80211_wake_queues(hw); 1519 priv->fw_mutex_owner = NULL; 1520 mutex_unlock(&priv->fw_mutex); 1521 } 1522} 1523 1524 1525/* 1526 * Command processing. 1527 */ 1528 1529/* Timeout firmware commands after 10s */ 1530#define MWL8K_CMD_TIMEOUT_MS 10000 1531 1532static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) 1533{ 1534 DECLARE_COMPLETION_ONSTACK(cmd_wait); 1535 struct mwl8k_priv *priv = hw->priv; 1536 void __iomem *regs = priv->regs; 1537 dma_addr_t dma_addr; 1538 unsigned int dma_size; 1539 int rc; 1540 unsigned long timeout = 0; 1541 u8 buf[32]; 1542 1543 cmd->result = (__force __le16) 0xffff; 1544 dma_size = le16_to_cpu(cmd->length); 1545 dma_addr = pci_map_single(priv->pdev, cmd, dma_size, 1546 PCI_DMA_BIDIRECTIONAL); 1547 if (pci_dma_mapping_error(priv->pdev, dma_addr)) 1548 return -ENOMEM; 1549 1550 rc = mwl8k_fw_lock(hw); 1551 if (rc) { 1552 pci_unmap_single(priv->pdev, dma_addr, dma_size, 1553 PCI_DMA_BIDIRECTIONAL); 1554 return rc; 1555 } 1556 1557 priv->hostcmd_wait = &cmd_wait; 1558 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); 1559 iowrite32(MWL8K_H2A_INT_DOORBELL, 1560 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1561 iowrite32(MWL8K_H2A_INT_DUMMY, 1562 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1563 1564 timeout = wait_for_completion_timeout(&cmd_wait, 1565 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS)); 1566 1567 priv->hostcmd_wait = NULL; 1568 1569 mwl8k_fw_unlock(hw); 1570 1571 pci_unmap_single(priv->pdev, dma_addr, dma_size, 1572 PCI_DMA_BIDIRECTIONAL); 1573 1574 if (!timeout) { 1575 wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", 1576 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1577 MWL8K_CMD_TIMEOUT_MS); 1578 rc = -ETIMEDOUT; 1579 } else { 1580 int ms; 1581 1582 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout); 1583 1584 rc = cmd->result ? -EINVAL : 0; 1585 if (rc) 1586 wiphy_err(hw->wiphy, "Command %s error 0x%x\n", 1587 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1588 le16_to_cpu(cmd->result)); 1589 else if (ms > 2000) 1590 wiphy_notice(hw->wiphy, "Command %s took %d ms\n", 1591 mwl8k_cmd_name(cmd->code, 1592 buf, sizeof(buf)), 1593 ms); 1594 } 1595 1596 return rc; 1597} 1598 1599static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw, 1600 struct ieee80211_vif *vif, 1601 struct mwl8k_cmd_pkt *cmd) 1602{ 1603 if (vif != NULL) 1604 cmd->macid = MWL8K_VIF(vif)->macid; 1605 return mwl8k_post_cmd(hw, cmd); 1606} 1607 1608/* 1609 * Setup code shared between STA and AP firmware images. 1610 */ 1611static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw) 1612{ 1613 struct mwl8k_priv *priv = hw->priv; 1614 1615 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24)); 1616 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24)); 1617 1618 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24)); 1619 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24)); 1620 1621 priv->band_24.band = IEEE80211_BAND_2GHZ; 1622 priv->band_24.channels = priv->channels_24; 1623 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24); 1624 priv->band_24.bitrates = priv->rates_24; 1625 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24); 1626 1627 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24; 1628} 1629 1630static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw) 1631{ 1632 struct mwl8k_priv *priv = hw->priv; 1633 1634 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50)); 1635 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50)); 1636 1637 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50)); 1638 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50)); 1639 1640 priv->band_50.band = IEEE80211_BAND_5GHZ; 1641 priv->band_50.channels = priv->channels_50; 1642 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50); 1643 priv->band_50.bitrates = priv->rates_50; 1644 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50); 1645 1646 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50; 1647} 1648 1649/* 1650 * CMD_GET_HW_SPEC (STA version). 1651 */ 1652struct mwl8k_cmd_get_hw_spec_sta { 1653 struct mwl8k_cmd_pkt header; 1654 __u8 hw_rev; 1655 __u8 host_interface; 1656 __le16 num_mcaddrs; 1657 __u8 perm_addr[ETH_ALEN]; 1658 __le16 region_code; 1659 __le32 fw_rev; 1660 __le32 ps_cookie; 1661 __le32 caps; 1662 __u8 mcs_bitmap[16]; 1663 __le32 rx_queue_ptr; 1664 __le32 num_tx_queues; 1665 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 1666 __le32 caps2; 1667 __le32 num_tx_desc_per_queue; 1668 __le32 total_rxd; 1669} __packed; 1670 1671#define MWL8K_CAP_MAX_AMSDU 0x20000000 1672#define MWL8K_CAP_GREENFIELD 0x08000000 1673#define MWL8K_CAP_AMPDU 0x04000000 1674#define MWL8K_CAP_RX_STBC 0x01000000 1675#define MWL8K_CAP_TX_STBC 0x00800000 1676#define MWL8K_CAP_SHORTGI_40MHZ 0x00400000 1677#define MWL8K_CAP_SHORTGI_20MHZ 0x00200000 1678#define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000 1679#define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000 1680#define MWL8K_CAP_DELAY_BA 0x00003000 1681#define MWL8K_CAP_MIMO 0x00000200 1682#define MWL8K_CAP_40MHZ 0x00000100 1683#define MWL8K_CAP_BAND_MASK 0x00000007 1684#define MWL8K_CAP_5GHZ 0x00000004 1685#define MWL8K_CAP_2GHZ4 0x00000001 1686 1687static void 1688mwl8k_set_ht_caps(struct ieee80211_hw *hw, 1689 struct ieee80211_supported_band *band, u32 cap) 1690{ 1691 int rx_streams; 1692 int tx_streams; 1693 1694 band->ht_cap.ht_supported = 1; 1695 1696 if (cap & MWL8K_CAP_MAX_AMSDU) 1697 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; 1698 if (cap & MWL8K_CAP_GREENFIELD) 1699 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD; 1700 if (cap & MWL8K_CAP_AMPDU) { 1701 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 1702 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 1703 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; 1704 } 1705 if (cap & MWL8K_CAP_RX_STBC) 1706 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC; 1707 if (cap & MWL8K_CAP_TX_STBC) 1708 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; 1709 if (cap & MWL8K_CAP_SHORTGI_40MHZ) 1710 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; 1711 if (cap & MWL8K_CAP_SHORTGI_20MHZ) 1712 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; 1713 if (cap & MWL8K_CAP_DELAY_BA) 1714 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA; 1715 if (cap & MWL8K_CAP_40MHZ) 1716 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1717 1718 rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK); 1719 tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK); 1720 1721 band->ht_cap.mcs.rx_mask[0] = 0xff; 1722 if (rx_streams >= 2) 1723 band->ht_cap.mcs.rx_mask[1] = 0xff; 1724 if (rx_streams >= 3) 1725 band->ht_cap.mcs.rx_mask[2] = 0xff; 1726 band->ht_cap.mcs.rx_mask[4] = 0x01; 1727 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 1728 1729 if (rx_streams != tx_streams) { 1730 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; 1731 band->ht_cap.mcs.tx_params |= (tx_streams - 1) << 1732 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; 1733 } 1734} 1735 1736static void 1737mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps) 1738{ 1739 struct mwl8k_priv *priv = hw->priv; 1740 1741 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) { 1742 mwl8k_setup_2ghz_band(hw); 1743 if (caps & MWL8K_CAP_MIMO) 1744 mwl8k_set_ht_caps(hw, &priv->band_24, caps); 1745 } 1746 1747 if (caps & MWL8K_CAP_5GHZ) { 1748 mwl8k_setup_5ghz_band(hw); 1749 if (caps & MWL8K_CAP_MIMO) 1750 mwl8k_set_ht_caps(hw, &priv->band_50, caps); 1751 } 1752} 1753 1754static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) 1755{ 1756 struct mwl8k_priv *priv = hw->priv; 1757 struct mwl8k_cmd_get_hw_spec_sta *cmd; 1758 int rc; 1759 int i; 1760 1761 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1762 if (cmd == NULL) 1763 return -ENOMEM; 1764 1765 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); 1766 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1767 1768 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 1769 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 1770 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 1771 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1772 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1773 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 1774 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 1775 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 1776 1777 rc = mwl8k_post_cmd(hw, &cmd->header); 1778 1779 if (!rc) { 1780 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); 1781 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1782 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1783 priv->hw_rev = cmd->hw_rev; 1784 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); 1785 priv->ap_macids_supported = 0x00000000; 1786 priv->sta_macids_supported = 0x00000001; 1787 } 1788 1789 kfree(cmd); 1790 return rc; 1791} 1792 1793/* 1794 * CMD_GET_HW_SPEC (AP version). 1795 */ 1796struct mwl8k_cmd_get_hw_spec_ap { 1797 struct mwl8k_cmd_pkt header; 1798 __u8 hw_rev; 1799 __u8 host_interface; 1800 __le16 num_wcb; 1801 __le16 num_mcaddrs; 1802 __u8 perm_addr[ETH_ALEN]; 1803 __le16 region_code; 1804 __le16 num_antenna; 1805 __le32 fw_rev; 1806 __le32 wcbbase0; 1807 __le32 rxwrptr; 1808 __le32 rxrdptr; 1809 __le32 ps_cookie; 1810 __le32 wcbbase1; 1811 __le32 wcbbase2; 1812 __le32 wcbbase3; 1813} __packed; 1814 1815static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) 1816{ 1817 struct mwl8k_priv *priv = hw->priv; 1818 struct mwl8k_cmd_get_hw_spec_ap *cmd; 1819 int rc; 1820 1821 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1822 if (cmd == NULL) 1823 return -ENOMEM; 1824 1825 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC); 1826 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1827 1828 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 1829 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 1830 1831 rc = mwl8k_post_cmd(hw, &cmd->header); 1832 1833 if (!rc) { 1834 int off; 1835 1836 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); 1837 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1838 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1839 priv->hw_rev = cmd->hw_rev; 1840 mwl8k_setup_2ghz_band(hw); 1841 priv->ap_macids_supported = 0x000000ff; 1842 priv->sta_macids_supported = 0x00000000; 1843 1844 off = le32_to_cpu(cmd->wcbbase0) & 0xffff; 1845 iowrite32(priv->txq[0].txd_dma, priv->sram + off); 1846 1847 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; 1848 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 1849 1850 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; 1851 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 1852 1853 off = le32_to_cpu(cmd->wcbbase1) & 0xffff; 1854 iowrite32(priv->txq[1].txd_dma, priv->sram + off); 1855 1856 off = le32_to_cpu(cmd->wcbbase2) & 0xffff; 1857 iowrite32(priv->txq[2].txd_dma, priv->sram + off); 1858 1859 off = le32_to_cpu(cmd->wcbbase3) & 0xffff; 1860 iowrite32(priv->txq[3].txd_dma, priv->sram + off); 1861 } 1862 1863 kfree(cmd); 1864 return rc; 1865} 1866 1867/* 1868 * CMD_SET_HW_SPEC. 1869 */ 1870struct mwl8k_cmd_set_hw_spec { 1871 struct mwl8k_cmd_pkt header; 1872 __u8 hw_rev; 1873 __u8 host_interface; 1874 __le16 num_mcaddrs; 1875 __u8 perm_addr[ETH_ALEN]; 1876 __le16 region_code; 1877 __le32 fw_rev; 1878 __le32 ps_cookie; 1879 __le32 caps; 1880 __le32 rx_queue_ptr; 1881 __le32 num_tx_queues; 1882 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 1883 __le32 flags; 1884 __le32 num_tx_desc_per_queue; 1885 __le32 total_rxd; 1886} __packed; 1887 1888#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 1889#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 1890#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 1891 1892static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) 1893{ 1894 struct mwl8k_priv *priv = hw->priv; 1895 struct mwl8k_cmd_set_hw_spec *cmd; 1896 int rc; 1897 int i; 1898 1899 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1900 if (cmd == NULL) 1901 return -ENOMEM; 1902 1903 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC); 1904 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1905 1906 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 1907 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 1908 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1909 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1910 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 1911 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | 1912 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | 1913 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON); 1914 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 1915 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 1916 1917 rc = mwl8k_post_cmd(hw, &cmd->header); 1918 kfree(cmd); 1919 1920 return rc; 1921} 1922 1923/* 1924 * CMD_MAC_MULTICAST_ADR. 1925 */ 1926struct mwl8k_cmd_mac_multicast_adr { 1927 struct mwl8k_cmd_pkt header; 1928 __le16 action; 1929 __le16 numaddr; 1930 __u8 addr[0][ETH_ALEN]; 1931}; 1932 1933#define MWL8K_ENABLE_RX_DIRECTED 0x0001 1934#define MWL8K_ENABLE_RX_MULTICAST 0x0002 1935#define MWL8K_ENABLE_RX_ALL_MULTICAST 0x0004 1936#define MWL8K_ENABLE_RX_BROADCAST 0x0008 1937 1938static struct mwl8k_cmd_pkt * 1939__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, 1940 struct netdev_hw_addr_list *mc_list) 1941{ 1942 struct mwl8k_priv *priv = hw->priv; 1943 struct mwl8k_cmd_mac_multicast_adr *cmd; 1944 int size; 1945 int mc_count = 0; 1946 1947 if (mc_list) 1948 mc_count = netdev_hw_addr_list_count(mc_list); 1949 1950 if (allmulti || mc_count > priv->num_mcaddrs) { 1951 allmulti = 1; 1952 mc_count = 0; 1953 } 1954 1955 size = sizeof(*cmd) + mc_count * ETH_ALEN; 1956 1957 cmd = kzalloc(size, GFP_ATOMIC); 1958 if (cmd == NULL) 1959 return NULL; 1960 1961 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); 1962 cmd->header.length = cpu_to_le16(size); 1963 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED | 1964 MWL8K_ENABLE_RX_BROADCAST); 1965 1966 if (allmulti) { 1967 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST); 1968 } else if (mc_count) { 1969 struct netdev_hw_addr *ha; 1970 int i = 0; 1971 1972 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); 1973 cmd->numaddr = cpu_to_le16(mc_count); 1974 netdev_hw_addr_list_for_each(ha, mc_list) { 1975 memcpy(cmd->addr[i], ha->addr, ETH_ALEN); 1976 } 1977 } 1978 1979 return &cmd->header; 1980} 1981 1982/* 1983 * CMD_GET_STAT. 1984 */ 1985struct mwl8k_cmd_get_stat { 1986 struct mwl8k_cmd_pkt header; 1987 __le32 stats[64]; 1988} __packed; 1989 1990#define MWL8K_STAT_ACK_FAILURE 9 1991#define MWL8K_STAT_RTS_FAILURE 12 1992#define MWL8K_STAT_FCS_ERROR 24 1993#define MWL8K_STAT_RTS_SUCCESS 11 1994 1995static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw, 1996 struct ieee80211_low_level_stats *stats) 1997{ 1998 struct mwl8k_cmd_get_stat *cmd; 1999 int rc; 2000 2001 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2002 if (cmd == NULL) 2003 return -ENOMEM; 2004 2005 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT); 2006 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2007 2008 rc = mwl8k_post_cmd(hw, &cmd->header); 2009 if (!rc) { 2010 stats->dot11ACKFailureCount = 2011 le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]); 2012 stats->dot11RTSFailureCount = 2013 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]); 2014 stats->dot11FCSErrorCount = 2015 le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]); 2016 stats->dot11RTSSuccessCount = 2017 le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]); 2018 } 2019 kfree(cmd); 2020 2021 return rc; 2022} 2023 2024/* 2025 * CMD_RADIO_CONTROL. 2026 */ 2027struct mwl8k_cmd_radio_control { 2028 struct mwl8k_cmd_pkt header; 2029 __le16 action; 2030 __le16 control; 2031 __le16 radio_on; 2032} __packed; 2033 2034static int 2035mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force) 2036{ 2037 struct mwl8k_priv *priv = hw->priv; 2038 struct mwl8k_cmd_radio_control *cmd; 2039 int rc; 2040 2041 if (enable == priv->radio_on && !force) 2042 return 0; 2043 2044 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2045 if (cmd == NULL) 2046 return -ENOMEM; 2047 2048 cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL); 2049 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2050 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2051 cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1); 2052 cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000); 2053 2054 rc = mwl8k_post_cmd(hw, &cmd->header); 2055 kfree(cmd); 2056 2057 if (!rc) 2058 priv->radio_on = enable; 2059 2060 return rc; 2061} 2062 2063static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw) 2064{ 2065 return mwl8k_cmd_radio_control(hw, 0, 0); 2066} 2067 2068static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw) 2069{ 2070 return mwl8k_cmd_radio_control(hw, 1, 0); 2071} 2072 2073static int 2074mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) 2075{ 2076 struct mwl8k_priv *priv = hw->priv; 2077 2078 priv->radio_short_preamble = short_preamble; 2079 2080 return mwl8k_cmd_radio_control(hw, 1, 1); 2081} 2082 2083/* 2084 * CMD_RF_TX_POWER. 2085 */ 2086#define MWL8K_TX_POWER_LEVEL_TOTAL 8 2087 2088struct mwl8k_cmd_rf_tx_power { 2089 struct mwl8k_cmd_pkt header; 2090 __le16 action; 2091 __le16 support_level; 2092 __le16 current_level; 2093 __le16 reserved; 2094 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; 2095} __packed; 2096 2097static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) 2098{ 2099 struct mwl8k_cmd_rf_tx_power *cmd; 2100 int rc; 2101 2102 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2103 if (cmd == NULL) 2104 return -ENOMEM; 2105 2106 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER); 2107 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2108 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2109 cmd->support_level = cpu_to_le16(dBm); 2110 2111 rc = mwl8k_post_cmd(hw, &cmd->header); 2112 kfree(cmd); 2113 2114 return rc; 2115} 2116 2117/* 2118 * CMD_RF_ANTENNA. 2119 */ 2120struct mwl8k_cmd_rf_antenna { 2121 struct mwl8k_cmd_pkt header; 2122 __le16 antenna; 2123 __le16 mode; 2124} __packed; 2125 2126#define MWL8K_RF_ANTENNA_RX 1 2127#define MWL8K_RF_ANTENNA_TX 2 2128 2129static int 2130mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask) 2131{ 2132 struct mwl8k_cmd_rf_antenna *cmd; 2133 int rc; 2134 2135 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2136 if (cmd == NULL) 2137 return -ENOMEM; 2138 2139 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA); 2140 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2141 cmd->antenna = cpu_to_le16(antenna); 2142 cmd->mode = cpu_to_le16(mask); 2143 2144 rc = mwl8k_post_cmd(hw, &cmd->header); 2145 kfree(cmd); 2146 2147 return rc; 2148} 2149 2150/* 2151 * CMD_SET_BEACON. 2152 */ 2153struct mwl8k_cmd_set_beacon { 2154 struct mwl8k_cmd_pkt header; 2155 __le16 beacon_len; 2156 __u8 beacon[0]; 2157}; 2158 2159static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, 2160 struct ieee80211_vif *vif, u8 *beacon, int len) 2161{ 2162 struct mwl8k_cmd_set_beacon *cmd; 2163 int rc; 2164 2165 cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL); 2166 if (cmd == NULL) 2167 return -ENOMEM; 2168 2169 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); 2170 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); 2171 cmd->beacon_len = cpu_to_le16(len); 2172 memcpy(cmd->beacon, beacon, len); 2173 2174 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2175 kfree(cmd); 2176 2177 return rc; 2178} 2179 2180/* 2181 * CMD_SET_PRE_SCAN. 2182 */ 2183struct mwl8k_cmd_set_pre_scan { 2184 struct mwl8k_cmd_pkt header; 2185} __packed; 2186 2187static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw) 2188{ 2189 struct mwl8k_cmd_set_pre_scan *cmd; 2190 int rc; 2191 2192 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2193 if (cmd == NULL) 2194 return -ENOMEM; 2195 2196 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN); 2197 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2198 2199 rc = mwl8k_post_cmd(hw, &cmd->header); 2200 kfree(cmd); 2201 2202 return rc; 2203} 2204 2205/* 2206 * CMD_SET_POST_SCAN. 2207 */ 2208struct mwl8k_cmd_set_post_scan { 2209 struct mwl8k_cmd_pkt header; 2210 __le32 isibss; 2211 __u8 bssid[ETH_ALEN]; 2212} __packed; 2213 2214static int 2215mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac) 2216{ 2217 struct mwl8k_cmd_set_post_scan *cmd; 2218 int rc; 2219 2220 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2221 if (cmd == NULL) 2222 return -ENOMEM; 2223 2224 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN); 2225 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2226 cmd->isibss = 0; 2227 memcpy(cmd->bssid, mac, ETH_ALEN); 2228 2229 rc = mwl8k_post_cmd(hw, &cmd->header); 2230 kfree(cmd); 2231 2232 return rc; 2233} 2234 2235/* 2236 * CMD_SET_RF_CHANNEL. 2237 */ 2238struct mwl8k_cmd_set_rf_channel { 2239 struct mwl8k_cmd_pkt header; 2240 __le16 action; 2241 __u8 current_channel; 2242 __le32 channel_flags; 2243} __packed; 2244 2245static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, 2246 struct ieee80211_conf *conf) 2247{ 2248 struct ieee80211_channel *channel = conf->channel; 2249 struct mwl8k_cmd_set_rf_channel *cmd; 2250 int rc; 2251 2252 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2253 if (cmd == NULL) 2254 return -ENOMEM; 2255 2256 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL); 2257 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2258 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2259 cmd->current_channel = channel->hw_value; 2260 2261 if (channel->band == IEEE80211_BAND_2GHZ) 2262 cmd->channel_flags |= cpu_to_le32(0x00000001); 2263 else if (channel->band == IEEE80211_BAND_5GHZ) 2264 cmd->channel_flags |= cpu_to_le32(0x00000004); 2265 2266 if (conf->channel_type == NL80211_CHAN_NO_HT || 2267 conf->channel_type == NL80211_CHAN_HT20) 2268 cmd->channel_flags |= cpu_to_le32(0x00000080); 2269 else if (conf->channel_type == NL80211_CHAN_HT40MINUS) 2270 cmd->channel_flags |= cpu_to_le32(0x000001900); 2271 else if (conf->channel_type == NL80211_CHAN_HT40PLUS) 2272 cmd->channel_flags |= cpu_to_le32(0x000000900); 2273 2274 rc = mwl8k_post_cmd(hw, &cmd->header); 2275 kfree(cmd); 2276 2277 return rc; 2278} 2279 2280/* 2281 * CMD_SET_AID. 2282 */ 2283#define MWL8K_FRAME_PROT_DISABLED 0x00 2284#define MWL8K_FRAME_PROT_11G 0x07 2285#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02 2286#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06 2287 2288struct mwl8k_cmd_update_set_aid { 2289 struct mwl8k_cmd_pkt header; 2290 __le16 aid; 2291 2292 /* AP's MAC address (BSSID) */ 2293 __u8 bssid[ETH_ALEN]; 2294 __le16 protection_mode; 2295 __u8 supp_rates[14]; 2296} __packed; 2297 2298static void legacy_rate_mask_to_array(u8 *rates, u32 mask) 2299{ 2300 int i; 2301 int j; 2302 2303 /* 2304 * Clear nonstandard rates 4 and 13. 2305 */ 2306 mask &= 0x1fef; 2307 2308 for (i = 0, j = 0; i < 14; i++) { 2309 if (mask & (1 << i)) 2310 rates[j++] = mwl8k_rates_24[i].hw_value; 2311 } 2312} 2313 2314static int 2315mwl8k_cmd_set_aid(struct ieee80211_hw *hw, 2316 struct ieee80211_vif *vif, u32 legacy_rate_mask) 2317{ 2318 struct mwl8k_cmd_update_set_aid *cmd; 2319 u16 prot_mode; 2320 int rc; 2321 2322 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2323 if (cmd == NULL) 2324 return -ENOMEM; 2325 2326 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); 2327 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2328 cmd->aid = cpu_to_le16(vif->bss_conf.aid); 2329 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); 2330 2331 if (vif->bss_conf.use_cts_prot) { 2332 prot_mode = MWL8K_FRAME_PROT_11G; 2333 } else { 2334 switch (vif->bss_conf.ht_operation_mode & 2335 IEEE80211_HT_OP_MODE_PROTECTION) { 2336 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: 2337 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY; 2338 break; 2339 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: 2340 prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL; 2341 break; 2342 default: 2343 prot_mode = MWL8K_FRAME_PROT_DISABLED; 2344 break; 2345 } 2346 } 2347 cmd->protection_mode = cpu_to_le16(prot_mode); 2348 2349 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask); 2350 2351 rc = mwl8k_post_cmd(hw, &cmd->header); 2352 kfree(cmd); 2353 2354 return rc; 2355} 2356 2357/* 2358 * CMD_SET_RATE. 2359 */ 2360struct mwl8k_cmd_set_rate { 2361 struct mwl8k_cmd_pkt header; 2362 __u8 legacy_rates[14]; 2363 2364 /* Bitmap for supported MCS codes. */ 2365 __u8 mcs_set[16]; 2366 __u8 reserved[16]; 2367} __packed; 2368 2369static int 2370mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2371 u32 legacy_rate_mask, u8 *mcs_rates) 2372{ 2373 struct mwl8k_cmd_set_rate *cmd; 2374 int rc; 2375 2376 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2377 if (cmd == NULL) 2378 return -ENOMEM; 2379 2380 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); 2381 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2382 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask); 2383 memcpy(cmd->mcs_set, mcs_rates, 16); 2384 2385 rc = mwl8k_post_cmd(hw, &cmd->header); 2386 kfree(cmd); 2387 2388 return rc; 2389} 2390 2391/* 2392 * CMD_FINALIZE_JOIN. 2393 */ 2394#define MWL8K_FJ_BEACON_MAXLEN 128 2395 2396struct mwl8k_cmd_finalize_join { 2397 struct mwl8k_cmd_pkt header; 2398 __le32 sleep_interval; /* Number of beacon periods to sleep */ 2399 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN]; 2400} __packed; 2401 2402static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame, 2403 int framelen, int dtim) 2404{ 2405 struct mwl8k_cmd_finalize_join *cmd; 2406 struct ieee80211_mgmt *payload = frame; 2407 int payload_len; 2408 int rc; 2409 2410 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2411 if (cmd == NULL) 2412 return -ENOMEM; 2413 2414 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); 2415 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2416 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1); 2417 2418 payload_len = framelen - ieee80211_hdrlen(payload->frame_control); 2419 if (payload_len < 0) 2420 payload_len = 0; 2421 else if (payload_len > MWL8K_FJ_BEACON_MAXLEN) 2422 payload_len = MWL8K_FJ_BEACON_MAXLEN; 2423 2424 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len); 2425 2426 rc = mwl8k_post_cmd(hw, &cmd->header); 2427 kfree(cmd); 2428 2429 return rc; 2430} 2431 2432/* 2433 * CMD_SET_RTS_THRESHOLD. 2434 */ 2435struct mwl8k_cmd_set_rts_threshold { 2436 struct mwl8k_cmd_pkt header; 2437 __le16 action; 2438 __le16 threshold; 2439} __packed; 2440 2441static int 2442mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh) 2443{ 2444 struct mwl8k_cmd_set_rts_threshold *cmd; 2445 int rc; 2446 2447 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2448 if (cmd == NULL) 2449 return -ENOMEM; 2450 2451 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); 2452 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2453 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2454 cmd->threshold = cpu_to_le16(rts_thresh); 2455 2456 rc = mwl8k_post_cmd(hw, &cmd->header); 2457 kfree(cmd); 2458 2459 return rc; 2460} 2461 2462/* 2463 * CMD_SET_SLOT. 2464 */ 2465struct mwl8k_cmd_set_slot { 2466 struct mwl8k_cmd_pkt header; 2467 __le16 action; 2468 __u8 short_slot; 2469} __packed; 2470 2471static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time) 2472{ 2473 struct mwl8k_cmd_set_slot *cmd; 2474 int rc; 2475 2476 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2477 if (cmd == NULL) 2478 return -ENOMEM; 2479 2480 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT); 2481 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2482 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2483 cmd->short_slot = short_slot_time; 2484 2485 rc = mwl8k_post_cmd(hw, &cmd->header); 2486 kfree(cmd); 2487 2488 return rc; 2489} 2490 2491/* 2492 * CMD_SET_EDCA_PARAMS. 2493 */ 2494struct mwl8k_cmd_set_edca_params { 2495 struct mwl8k_cmd_pkt header; 2496 2497 /* See MWL8K_SET_EDCA_XXX below */ 2498 __le16 action; 2499 2500 /* TX opportunity in units of 32 us */ 2501 __le16 txop; 2502 2503 union { 2504 struct { 2505 /* Log exponent of max contention period: 0...15 */ 2506 __le32 log_cw_max; 2507 2508 /* Log exponent of min contention period: 0...15 */ 2509 __le32 log_cw_min; 2510 2511 /* Adaptive interframe spacing in units of 32us */ 2512 __u8 aifs; 2513 2514 /* TX queue to configure */ 2515 __u8 txq; 2516 } ap; 2517 struct { 2518 /* Log exponent of max contention period: 0...15 */ 2519 __u8 log_cw_max; 2520 2521 /* Log exponent of min contention period: 0...15 */ 2522 __u8 log_cw_min; 2523 2524 /* Adaptive interframe spacing in units of 32us */ 2525 __u8 aifs; 2526 2527 /* TX queue to configure */ 2528 __u8 txq; 2529 } sta; 2530 }; 2531} __packed; 2532 2533#define MWL8K_SET_EDCA_CW 0x01 2534#define MWL8K_SET_EDCA_TXOP 0x02 2535#define MWL8K_SET_EDCA_AIFS 0x04 2536 2537#define MWL8K_SET_EDCA_ALL (MWL8K_SET_EDCA_CW | \ 2538 MWL8K_SET_EDCA_TXOP | \ 2539 MWL8K_SET_EDCA_AIFS) 2540 2541static int 2542mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum, 2543 __u16 cw_min, __u16 cw_max, 2544 __u8 aifs, __u16 txop) 2545{ 2546 struct mwl8k_priv *priv = hw->priv; 2547 struct mwl8k_cmd_set_edca_params *cmd; 2548 int rc; 2549 2550 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2551 if (cmd == NULL) 2552 return -ENOMEM; 2553 2554 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); 2555 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2556 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2557 cmd->txop = cpu_to_le16(txop); 2558 if (priv->ap_fw) { 2559 cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1)); 2560 cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1)); 2561 cmd->ap.aifs = aifs; 2562 cmd->ap.txq = qnum; 2563 } else { 2564 cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1); 2565 cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1); 2566 cmd->sta.aifs = aifs; 2567 cmd->sta.txq = qnum; 2568 } 2569 2570 rc = mwl8k_post_cmd(hw, &cmd->header); 2571 kfree(cmd); 2572 2573 return rc; 2574} 2575 2576/* 2577 * CMD_SET_WMM_MODE. 2578 */ 2579struct mwl8k_cmd_set_wmm_mode { 2580 struct mwl8k_cmd_pkt header; 2581 __le16 action; 2582} __packed; 2583 2584static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable) 2585{ 2586 struct mwl8k_priv *priv = hw->priv; 2587 struct mwl8k_cmd_set_wmm_mode *cmd; 2588 int rc; 2589 2590 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2591 if (cmd == NULL) 2592 return -ENOMEM; 2593 2594 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); 2595 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2596 cmd->action = cpu_to_le16(!!enable); 2597 2598 rc = mwl8k_post_cmd(hw, &cmd->header); 2599 kfree(cmd); 2600 2601 if (!rc) 2602 priv->wmm_enabled = enable; 2603 2604 return rc; 2605} 2606 2607/* 2608 * CMD_MIMO_CONFIG. 2609 */ 2610struct mwl8k_cmd_mimo_config { 2611 struct mwl8k_cmd_pkt header; 2612 __le32 action; 2613 __u8 rx_antenna_map; 2614 __u8 tx_antenna_map; 2615} __packed; 2616 2617static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx) 2618{ 2619 struct mwl8k_cmd_mimo_config *cmd; 2620 int rc; 2621 2622 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2623 if (cmd == NULL) 2624 return -ENOMEM; 2625 2626 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG); 2627 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2628 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET); 2629 cmd->rx_antenna_map = rx; 2630 cmd->tx_antenna_map = tx; 2631 2632 rc = mwl8k_post_cmd(hw, &cmd->header); 2633 kfree(cmd); 2634 2635 return rc; 2636} 2637 2638/* 2639 * CMD_USE_FIXED_RATE (STA version). 2640 */ 2641struct mwl8k_cmd_use_fixed_rate_sta { 2642 struct mwl8k_cmd_pkt header; 2643 __le32 action; 2644 __le32 allow_rate_drop; 2645 __le32 num_rates; 2646 struct { 2647 __le32 is_ht_rate; 2648 __le32 enable_retry; 2649 __le32 rate; 2650 __le32 retry_count; 2651 } rate_entry[8]; 2652 __le32 rate_type; 2653 __le32 reserved1; 2654 __le32 reserved2; 2655} __packed; 2656 2657#define MWL8K_USE_AUTO_RATE 0x0002 2658#define MWL8K_UCAST_RATE 0 2659 2660static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw) 2661{ 2662 struct mwl8k_cmd_use_fixed_rate_sta *cmd; 2663 int rc; 2664 2665 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2666 if (cmd == NULL) 2667 return -ENOMEM; 2668 2669 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); 2670 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2671 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); 2672 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE); 2673 2674 rc = mwl8k_post_cmd(hw, &cmd->header); 2675 kfree(cmd); 2676 2677 return rc; 2678} 2679 2680/* 2681 * CMD_USE_FIXED_RATE (AP version). 2682 */ 2683struct mwl8k_cmd_use_fixed_rate_ap { 2684 struct mwl8k_cmd_pkt header; 2685 __le32 action; 2686 __le32 allow_rate_drop; 2687 __le32 num_rates; 2688 struct mwl8k_rate_entry_ap { 2689 __le32 is_ht_rate; 2690 __le32 enable_retry; 2691 __le32 rate; 2692 __le32 retry_count; 2693 } rate_entry[4]; 2694 u8 multicast_rate; 2695 u8 multicast_rate_type; 2696 u8 management_rate; 2697} __packed; 2698 2699static int 2700mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt) 2701{ 2702 struct mwl8k_cmd_use_fixed_rate_ap *cmd; 2703 int rc; 2704 2705 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2706 if (cmd == NULL) 2707 return -ENOMEM; 2708 2709 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); 2710 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2711 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE); 2712 cmd->multicast_rate = mcast; 2713 cmd->management_rate = mgmt; 2714 2715 rc = mwl8k_post_cmd(hw, &cmd->header); 2716 kfree(cmd); 2717 2718 return rc; 2719} 2720 2721/* 2722 * CMD_ENABLE_SNIFFER. 2723 */ 2724struct mwl8k_cmd_enable_sniffer { 2725 struct mwl8k_cmd_pkt header; 2726 __le32 action; 2727} __packed; 2728 2729static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable) 2730{ 2731 struct mwl8k_cmd_enable_sniffer *cmd; 2732 int rc; 2733 2734 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2735 if (cmd == NULL) 2736 return -ENOMEM; 2737 2738 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); 2739 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2740 cmd->action = cpu_to_le32(!!enable); 2741 2742 rc = mwl8k_post_cmd(hw, &cmd->header); 2743 kfree(cmd); 2744 2745 return rc; 2746} 2747 2748/* 2749 * CMD_SET_MAC_ADDR. 2750 */ 2751struct mwl8k_cmd_set_mac_addr { 2752 struct mwl8k_cmd_pkt header; 2753 union { 2754 struct { 2755 __le16 mac_type; 2756 __u8 mac_addr[ETH_ALEN]; 2757 } mbss; 2758 __u8 mac_addr[ETH_ALEN]; 2759 }; 2760} __packed; 2761 2762#define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0 2763#define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1 2764#define MWL8K_MAC_TYPE_PRIMARY_AP 2 2765#define MWL8K_MAC_TYPE_SECONDARY_AP 3 2766 2767static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, 2768 struct ieee80211_vif *vif, u8 *mac) 2769{ 2770 struct mwl8k_priv *priv = hw->priv; 2771 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 2772 struct mwl8k_cmd_set_mac_addr *cmd; 2773 int mac_type; 2774 int rc; 2775 2776 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP; 2777 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) { 2778 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported)) 2779 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT; 2780 else 2781 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT; 2782 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) { 2783 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported)) 2784 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP; 2785 else 2786 mac_type = MWL8K_MAC_TYPE_SECONDARY_AP; 2787 } 2788 2789 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2790 if (cmd == NULL) 2791 return -ENOMEM; 2792 2793 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); 2794 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2795 if (priv->ap_fw) { 2796 cmd->mbss.mac_type = cpu_to_le16(mac_type); 2797 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN); 2798 } else { 2799 memcpy(cmd->mac_addr, mac, ETH_ALEN); 2800 } 2801 2802 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2803 kfree(cmd); 2804 2805 return rc; 2806} 2807 2808/* 2809 * CMD_SET_RATEADAPT_MODE. 2810 */ 2811struct mwl8k_cmd_set_rate_adapt_mode { 2812 struct mwl8k_cmd_pkt header; 2813 __le16 action; 2814 __le16 mode; 2815} __packed; 2816 2817static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode) 2818{ 2819 struct mwl8k_cmd_set_rate_adapt_mode *cmd; 2820 int rc; 2821 2822 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2823 if (cmd == NULL) 2824 return -ENOMEM; 2825 2826 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE); 2827 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2828 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2829 cmd->mode = cpu_to_le16(mode); 2830 2831 rc = mwl8k_post_cmd(hw, &cmd->header); 2832 kfree(cmd); 2833 2834 return rc; 2835} 2836 2837/* 2838 * CMD_BSS_START. 2839 */ 2840struct mwl8k_cmd_bss_start { 2841 struct mwl8k_cmd_pkt header; 2842 __le32 enable; 2843} __packed; 2844 2845static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, 2846 struct ieee80211_vif *vif, int enable) 2847{ 2848 struct mwl8k_cmd_bss_start *cmd; 2849 int rc; 2850 2851 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2852 if (cmd == NULL) 2853 return -ENOMEM; 2854 2855 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START); 2856 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2857 cmd->enable = cpu_to_le32(enable); 2858 2859 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2860 kfree(cmd); 2861 2862 return rc; 2863} 2864 2865/* 2866 * CMD_SET_NEW_STN. 2867 */ 2868struct mwl8k_cmd_set_new_stn { 2869 struct mwl8k_cmd_pkt header; 2870 __le16 aid; 2871 __u8 mac_addr[6]; 2872 __le16 stn_id; 2873 __le16 action; 2874 __le16 rsvd; 2875 __le32 legacy_rates; 2876 __u8 ht_rates[4]; 2877 __le16 cap_info; 2878 __le16 ht_capabilities_info; 2879 __u8 mac_ht_param_info; 2880 __u8 rev; 2881 __u8 control_channel; 2882 __u8 add_channel; 2883 __le16 op_mode; 2884 __le16 stbc; 2885 __u8 add_qos_info; 2886 __u8 is_qos_sta; 2887 __le32 fw_sta_ptr; 2888} __packed; 2889 2890#define MWL8K_STA_ACTION_ADD 0 2891#define MWL8K_STA_ACTION_REMOVE 2 2892 2893static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, 2894 struct ieee80211_vif *vif, 2895 struct ieee80211_sta *sta) 2896{ 2897 struct mwl8k_cmd_set_new_stn *cmd; 2898 u32 rates; 2899 int rc; 2900 2901 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2902 if (cmd == NULL) 2903 return -ENOMEM; 2904 2905 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); 2906 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2907 cmd->aid = cpu_to_le16(sta->aid); 2908 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); 2909 cmd->stn_id = cpu_to_le16(sta->aid); 2910 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); 2911 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) 2912 rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; 2913 else 2914 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; 2915 cmd->legacy_rates = cpu_to_le32(rates); 2916 if (sta->ht_cap.ht_supported) { 2917 cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0]; 2918 cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1]; 2919 cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2]; 2920 cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3]; 2921 cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap); 2922 cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) | 2923 ((sta->ht_cap.ampdu_density & 7) << 2); 2924 cmd->is_qos_sta = 1; 2925 } 2926 2927 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2928 kfree(cmd); 2929 2930 return rc; 2931} 2932 2933static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw, 2934 struct ieee80211_vif *vif) 2935{ 2936 struct mwl8k_cmd_set_new_stn *cmd; 2937 int rc; 2938 2939 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2940 if (cmd == NULL) 2941 return -ENOMEM; 2942 2943 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); 2944 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2945 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN); 2946 2947 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2948 kfree(cmd); 2949 2950 return rc; 2951} 2952 2953static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw, 2954 struct ieee80211_vif *vif, u8 *addr) 2955{ 2956 struct mwl8k_cmd_set_new_stn *cmd; 2957 int rc; 2958 2959 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2960 if (cmd == NULL) 2961 return -ENOMEM; 2962 2963 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN); 2964 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2965 memcpy(cmd->mac_addr, addr, ETH_ALEN); 2966 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE); 2967 2968 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 2969 kfree(cmd); 2970 2971 return rc; 2972} 2973 2974/* 2975 * CMD_UPDATE_STADB. 2976 */ 2977struct ewc_ht_info { 2978 __le16 control1; 2979 __le16 control2; 2980 __le16 control3; 2981} __packed; 2982 2983struct peer_capability_info { 2984 /* Peer type - AP vs. STA. */ 2985 __u8 peer_type; 2986 2987 /* Basic 802.11 capabilities from assoc resp. */ 2988 __le16 basic_caps; 2989 2990 /* Set if peer supports 802.11n high throughput (HT). */ 2991 __u8 ht_support; 2992 2993 /* Valid if HT is supported. */ 2994 __le16 ht_caps; 2995 __u8 extended_ht_caps; 2996 struct ewc_ht_info ewc_info; 2997 2998 /* Legacy rate table. Intersection of our rates and peer rates. */ 2999 __u8 legacy_rates[12]; 3000 3001 /* HT rate table. Intersection of our rates and peer rates. */ 3002 __u8 ht_rates[16]; 3003 __u8 pad[16]; 3004 3005 /* If set, interoperability mode, no proprietary extensions. */ 3006 __u8 interop; 3007 __u8 pad2; 3008 __u8 station_id; 3009 __le16 amsdu_enabled; 3010} __packed; 3011 3012struct mwl8k_cmd_update_stadb { 3013 struct mwl8k_cmd_pkt header; 3014 3015 /* See STADB_ACTION_TYPE */ 3016 __le32 action; 3017 3018 /* Peer MAC address */ 3019 __u8 peer_addr[ETH_ALEN]; 3020 3021 __le32 reserved; 3022 3023 /* Peer info - valid during add/update. */ 3024 struct peer_capability_info peer_info; 3025} __packed; 3026 3027#define MWL8K_STA_DB_MODIFY_ENTRY 1 3028#define MWL8K_STA_DB_DEL_ENTRY 2 3029 3030/* Peer Entry flags - used to define the type of the peer node */ 3031#define MWL8K_PEER_TYPE_ACCESSPOINT 2 3032 3033static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, 3034 struct ieee80211_vif *vif, 3035 struct ieee80211_sta *sta) 3036{ 3037 struct mwl8k_cmd_update_stadb *cmd; 3038 struct peer_capability_info *p; 3039 u32 rates; 3040 int rc; 3041 3042 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3043 if (cmd == NULL) 3044 return -ENOMEM; 3045 3046 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); 3047 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 3048 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); 3049 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN); 3050 3051 p = &cmd->peer_info; 3052 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; 3053 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); 3054 p->ht_support = sta->ht_cap.ht_supported; 3055 p->ht_caps = cpu_to_le16(sta->ht_cap.cap); 3056 p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | 3057 ((sta->ht_cap.ampdu_density & 7) << 2); 3058 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) 3059 rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; 3060 else 3061 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; 3062 legacy_rate_mask_to_array(p->legacy_rates, rates); 3063 memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16); 3064 p->interop = 1; 3065 p->amsdu_enabled = 0; 3066 3067 rc = mwl8k_post_cmd(hw, &cmd->header); 3068 kfree(cmd); 3069 3070 return rc ? rc : p->station_id; 3071} 3072 3073static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw, 3074 struct ieee80211_vif *vif, u8 *addr) 3075{ 3076 struct mwl8k_cmd_update_stadb *cmd; 3077 int rc; 3078 3079 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3080 if (cmd == NULL) 3081 return -ENOMEM; 3082 3083 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); 3084 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 3085 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY); 3086 memcpy(cmd->peer_addr, addr, ETH_ALEN); 3087 3088 rc = mwl8k_post_cmd(hw, &cmd->header); 3089 kfree(cmd); 3090 3091 return rc; 3092} 3093 3094 3095/* 3096 * Interrupt handling. 3097 */ 3098static irqreturn_t mwl8k_interrupt(int irq, void *dev_id) 3099{ 3100 struct ieee80211_hw *hw = dev_id; 3101 struct mwl8k_priv *priv = hw->priv; 3102 u32 status; 3103 3104 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3105 if (!status) 3106 return IRQ_NONE; 3107 3108 if (status & MWL8K_A2H_INT_TX_DONE) { 3109 status &= ~MWL8K_A2H_INT_TX_DONE; 3110 tasklet_schedule(&priv->poll_tx_task); 3111 } 3112 3113 if (status & MWL8K_A2H_INT_RX_READY) { 3114 status &= ~MWL8K_A2H_INT_RX_READY; 3115 tasklet_schedule(&priv->poll_rx_task); 3116 } 3117 3118 if (status) 3119 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3120 3121 if (status & MWL8K_A2H_INT_OPC_DONE) { 3122 if (priv->hostcmd_wait != NULL) 3123 complete(priv->hostcmd_wait); 3124 } 3125 3126 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) { 3127 if (!mutex_is_locked(&priv->fw_mutex) && 3128 priv->radio_on && priv->pending_tx_pkts) 3129 mwl8k_tx_start(priv); 3130 } 3131 3132 return IRQ_HANDLED; 3133} 3134 3135static void mwl8k_tx_poll(unsigned long data) 3136{ 3137 struct ieee80211_hw *hw = (struct ieee80211_hw *)data; 3138 struct mwl8k_priv *priv = hw->priv; 3139 int limit; 3140 int i; 3141 3142 limit = 32; 3143 3144 spin_lock_bh(&priv->tx_lock); 3145 3146 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3147 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); 3148 3149 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { 3150 complete(priv->tx_wait); 3151 priv->tx_wait = NULL; 3152 } 3153 3154 spin_unlock_bh(&priv->tx_lock); 3155 3156 if (limit) { 3157 writel(~MWL8K_A2H_INT_TX_DONE, 3158 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3159 } else { 3160 tasklet_schedule(&priv->poll_tx_task); 3161 } 3162} 3163 3164static void mwl8k_rx_poll(unsigned long data) 3165{ 3166 struct ieee80211_hw *hw = (struct ieee80211_hw *)data; 3167 struct mwl8k_priv *priv = hw->priv; 3168 int limit; 3169 3170 limit = 32; 3171 limit -= rxq_process(hw, 0, limit); 3172 limit -= rxq_refill(hw, 0, limit); 3173 3174 if (limit) { 3175 writel(~MWL8K_A2H_INT_RX_READY, 3176 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3177 } else { 3178 tasklet_schedule(&priv->poll_rx_task); 3179 } 3180} 3181 3182 3183/* 3184 * Core driver operations. 3185 */ 3186static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 3187{ 3188 struct mwl8k_priv *priv = hw->priv; 3189 int index = skb_get_queue_mapping(skb); 3190 int rc; 3191 3192 if (!priv->radio_on) { 3193 wiphy_debug(hw->wiphy, 3194 "dropped TX frame since radio disabled\n"); 3195 dev_kfree_skb(skb); 3196 return NETDEV_TX_OK; 3197 } 3198 3199 rc = mwl8k_txq_xmit(hw, index, skb); 3200 3201 return rc; 3202} 3203 3204static int mwl8k_start(struct ieee80211_hw *hw) 3205{ 3206 struct mwl8k_priv *priv = hw->priv; 3207 int rc; 3208 3209 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 3210 IRQF_SHARED, MWL8K_NAME, hw); 3211 if (rc) { 3212 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); 3213 return -EIO; 3214 } 3215 3216 /* Enable TX reclaim and RX tasklets. */ 3217 tasklet_enable(&priv->poll_tx_task); 3218 tasklet_enable(&priv->poll_rx_task); 3219 3220 /* Enable interrupts */ 3221 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3222 3223 rc = mwl8k_fw_lock(hw); 3224 if (!rc) { 3225 rc = mwl8k_cmd_radio_enable(hw); 3226 3227 if (!priv->ap_fw) { 3228 if (!rc) 3229 rc = mwl8k_cmd_enable_sniffer(hw, 0); 3230 3231 if (!rc) 3232 rc = mwl8k_cmd_set_pre_scan(hw); 3233 3234 if (!rc) 3235 rc = mwl8k_cmd_set_post_scan(hw, 3236 "\x00\x00\x00\x00\x00\x00"); 3237 } 3238 3239 if (!rc) 3240 rc = mwl8k_cmd_set_rateadapt_mode(hw, 0); 3241 3242 if (!rc) 3243 rc = mwl8k_cmd_set_wmm_mode(hw, 0); 3244 3245 mwl8k_fw_unlock(hw); 3246 } 3247 3248 if (rc) { 3249 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3250 free_irq(priv->pdev->irq, hw); 3251 tasklet_disable(&priv->poll_tx_task); 3252 tasklet_disable(&priv->poll_rx_task); 3253 } 3254 3255 return rc; 3256} 3257 3258static void mwl8k_stop(struct ieee80211_hw *hw) 3259{ 3260 struct mwl8k_priv *priv = hw->priv; 3261 int i; 3262 3263 mwl8k_cmd_radio_disable(hw); 3264 3265 ieee80211_stop_queues(hw); 3266 3267 /* Disable interrupts */ 3268 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3269 free_irq(priv->pdev->irq, hw); 3270 3271 /* Stop finalize join worker */ 3272 cancel_work_sync(&priv->finalize_join_worker); 3273 if (priv->beacon_skb != NULL) 3274 dev_kfree_skb(priv->beacon_skb); 3275 3276 /* Stop TX reclaim and RX tasklets. */ 3277 tasklet_disable(&priv->poll_tx_task); 3278 tasklet_disable(&priv->poll_rx_task); 3279 3280 /* Return all skbs to mac80211 */ 3281 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3282 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 3283} 3284 3285static int mwl8k_add_interface(struct ieee80211_hw *hw, 3286 struct ieee80211_vif *vif) 3287{ 3288 struct mwl8k_priv *priv = hw->priv; 3289 struct mwl8k_vif *mwl8k_vif; 3290 u32 macids_supported; 3291 int macid; 3292 3293 /* 3294 * Reject interface creation if sniffer mode is active, as 3295 * STA operation is mutually exclusive with hardware sniffer 3296 * mode. (Sniffer mode is only used on STA firmware.) 3297 */ 3298 if (priv->sniffer_enabled) { 3299 wiphy_info(hw->wiphy, 3300 "unable to create STA interface because sniffer mode is enabled\n"); 3301 return -EINVAL; 3302 } 3303 3304 3305 switch (vif->type) { 3306 case NL80211_IFTYPE_AP: 3307 macids_supported = priv->ap_macids_supported; 3308 break; 3309 case NL80211_IFTYPE_STATION: 3310 macids_supported = priv->sta_macids_supported; 3311 break; 3312 default: 3313 return -EINVAL; 3314 } 3315 3316 macid = ffs(macids_supported & ~priv->macids_used); 3317 if (!macid--) 3318 return -EBUSY; 3319 3320 /* Setup driver private area. */ 3321 mwl8k_vif = MWL8K_VIF(vif); 3322 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif)); 3323 mwl8k_vif->vif = vif; 3324 mwl8k_vif->macid = macid; 3325 mwl8k_vif->seqno = 0; 3326 3327 /* Set the mac address. */ 3328 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); 3329 3330 if (priv->ap_fw) 3331 mwl8k_cmd_set_new_stn_add_self(hw, vif); 3332 3333 priv->macids_used |= 1 << mwl8k_vif->macid; 3334 list_add_tail(&mwl8k_vif->list, &priv->vif_list); 3335 3336 return 0; 3337} 3338 3339static void mwl8k_remove_interface(struct ieee80211_hw *hw, 3340 struct ieee80211_vif *vif) 3341{ 3342 struct mwl8k_priv *priv = hw->priv; 3343 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 3344 3345 if (priv->ap_fw) 3346 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); 3347 3348 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00"); 3349 3350 priv->macids_used &= ~(1 << mwl8k_vif->macid); 3351 list_del(&mwl8k_vif->list); 3352} 3353 3354static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 3355{ 3356 struct ieee80211_conf *conf = &hw->conf; 3357 struct mwl8k_priv *priv = hw->priv; 3358 int rc; 3359 3360 if (conf->flags & IEEE80211_CONF_IDLE) { 3361 mwl8k_cmd_radio_disable(hw); 3362 return 0; 3363 } 3364 3365 rc = mwl8k_fw_lock(hw); 3366 if (rc) 3367 return rc; 3368 3369 rc = mwl8k_cmd_radio_enable(hw); 3370 if (rc) 3371 goto out; 3372 3373 rc = mwl8k_cmd_set_rf_channel(hw, conf); 3374 if (rc) 3375 goto out; 3376 3377 if (conf->power_level > 18) 3378 conf->power_level = 18; 3379 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); 3380 if (rc) 3381 goto out; 3382 3383 if (priv->ap_fw) { 3384 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7); 3385 if (!rc) 3386 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); 3387 } else { 3388 rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7); 3389 } 3390 3391out: 3392 mwl8k_fw_unlock(hw); 3393 3394 return rc; 3395} 3396 3397static void 3398mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3399 struct ieee80211_bss_conf *info, u32 changed) 3400{ 3401 struct mwl8k_priv *priv = hw->priv; 3402 u32 ap_legacy_rates; 3403 u8 ap_mcs_rates[16]; 3404 int rc; 3405 3406 if (mwl8k_fw_lock(hw)) 3407 return; 3408 3409 /* 3410 * No need to capture a beacon if we're no longer associated. 3411 */ 3412 if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc) 3413 priv->capture_beacon = false; 3414 3415 /* 3416 * Get the AP's legacy and MCS rates. 3417 */ 3418 if (vif->bss_conf.assoc) { 3419 struct ieee80211_sta *ap; 3420 3421 rcu_read_lock(); 3422 3423 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); 3424 if (ap == NULL) { 3425 rcu_read_unlock(); 3426 goto out; 3427 } 3428 3429 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) { 3430 ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; 3431 } else { 3432 ap_legacy_rates = 3433 ap->supp_rates[IEEE80211_BAND_5GHZ] << 5; 3434 } 3435 memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16); 3436 3437 rcu_read_unlock(); 3438 } 3439 3440 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) { 3441 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates); 3442 if (rc) 3443 goto out; 3444 3445 rc = mwl8k_cmd_use_fixed_rate_sta(hw); 3446 if (rc) 3447 goto out; 3448 } 3449 3450 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 3451 rc = mwl8k_set_radio_preamble(hw, 3452 vif->bss_conf.use_short_preamble); 3453 if (rc) 3454 goto out; 3455 } 3456 3457 if (changed & BSS_CHANGED_ERP_SLOT) { 3458 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); 3459 if (rc) 3460 goto out; 3461 } 3462 3463 if (vif->bss_conf.assoc && 3464 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT | 3465 BSS_CHANGED_HT))) { 3466 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates); 3467 if (rc) 3468 goto out; 3469 } 3470 3471 if (vif->bss_conf.assoc && 3472 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) { 3473 /* 3474 * Finalize the join. Tell rx handler to process 3475 * next beacon from our BSSID. 3476 */ 3477 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN); 3478 priv->capture_beacon = true; 3479 } 3480 3481out: 3482 mwl8k_fw_unlock(hw); 3483} 3484 3485static void 3486mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3487 struct ieee80211_bss_conf *info, u32 changed) 3488{ 3489 int rc; 3490 3491 if (mwl8k_fw_lock(hw)) 3492 return; 3493 3494 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 3495 rc = mwl8k_set_radio_preamble(hw, 3496 vif->bss_conf.use_short_preamble); 3497 if (rc) 3498 goto out; 3499 } 3500 3501 if (changed & BSS_CHANGED_BASIC_RATES) { 3502 int idx; 3503 int rate; 3504 3505 /* 3506 * Use lowest supported basic rate for multicasts 3507 * and management frames (such as probe responses -- 3508 * beacons will always go out at 1 Mb/s). 3509 */ 3510 idx = ffs(vif->bss_conf.basic_rates); 3511 if (idx) 3512 idx--; 3513 3514 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) 3515 rate = mwl8k_rates_24[idx].hw_value; 3516 else 3517 rate = mwl8k_rates_50[idx].hw_value; 3518 3519 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate); 3520 } 3521 3522 if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) { 3523 struct sk_buff *skb; 3524 3525 skb = ieee80211_beacon_get(hw, vif); 3526 if (skb != NULL) { 3527 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len); 3528 kfree_skb(skb); 3529 } 3530 } 3531 3532 if (changed & BSS_CHANGED_BEACON_ENABLED) 3533 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon); 3534 3535out: 3536 mwl8k_fw_unlock(hw); 3537} 3538 3539static void 3540mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3541 struct ieee80211_bss_conf *info, u32 changed) 3542{ 3543 struct mwl8k_priv *priv = hw->priv; 3544 3545 if (!priv->ap_fw) 3546 mwl8k_bss_info_changed_sta(hw, vif, info, changed); 3547 else 3548 mwl8k_bss_info_changed_ap(hw, vif, info, changed); 3549} 3550 3551static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 3552 struct netdev_hw_addr_list *mc_list) 3553{ 3554 struct mwl8k_cmd_pkt *cmd; 3555 3556 /* 3557 * Synthesize and return a command packet that programs the 3558 * hardware multicast address filter. At this point we don't 3559 * know whether FIF_ALLMULTI is being requested, but if it is, 3560 * we'll end up throwing this packet away and creating a new 3561 * one in mwl8k_configure_filter(). 3562 */ 3563 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_list); 3564 3565 return (unsigned long)cmd; 3566} 3567 3568static int 3569mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw, 3570 unsigned int changed_flags, 3571 unsigned int *total_flags) 3572{ 3573 struct mwl8k_priv *priv = hw->priv; 3574 3575 /* 3576 * Hardware sniffer mode is mutually exclusive with STA 3577 * operation, so refuse to enable sniffer mode if a STA 3578 * interface is active. 3579 */ 3580 if (!list_empty(&priv->vif_list)) { 3581 if (net_ratelimit()) 3582 wiphy_info(hw->wiphy, 3583 "not enabling sniffer mode because STA interface is active\n"); 3584 return 0; 3585 } 3586 3587 if (!priv->sniffer_enabled) { 3588 if (mwl8k_cmd_enable_sniffer(hw, 1)) 3589 return 0; 3590 priv->sniffer_enabled = true; 3591 } 3592 3593 *total_flags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI | 3594 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL | 3595 FIF_OTHER_BSS; 3596 3597 return 1; 3598} 3599 3600static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv) 3601{ 3602 if (!list_empty(&priv->vif_list)) 3603 return list_entry(priv->vif_list.next, struct mwl8k_vif, list); 3604 3605 return NULL; 3606} 3607 3608static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3609 unsigned int changed_flags, 3610 unsigned int *total_flags, 3611 u64 multicast) 3612{ 3613 struct mwl8k_priv *priv = hw->priv; 3614 struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast; 3615 3616 /* 3617 * AP firmware doesn't allow fine-grained control over 3618 * the receive filter. 3619 */ 3620 if (priv->ap_fw) { 3621 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; 3622 kfree(cmd); 3623 return; 3624 } 3625 3626 /* 3627 * Enable hardware sniffer mode if FIF_CONTROL or 3628 * FIF_OTHER_BSS is requested. 3629 */ 3630 if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) && 3631 mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) { 3632 kfree(cmd); 3633 return; 3634 } 3635 3636 /* Clear unsupported feature flags */ 3637 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; 3638 3639 if (mwl8k_fw_lock(hw)) { 3640 kfree(cmd); 3641 return; 3642 } 3643 3644 if (priv->sniffer_enabled) { 3645 mwl8k_cmd_enable_sniffer(hw, 0); 3646 priv->sniffer_enabled = false; 3647 } 3648 3649 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 3650 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { 3651 /* 3652 * Disable the BSS filter. 3653 */ 3654 mwl8k_cmd_set_pre_scan(hw); 3655 } else { 3656 struct mwl8k_vif *mwl8k_vif; 3657 const u8 *bssid; 3658 3659 /* 3660 * Enable the BSS filter. 3661 * 3662 * If there is an active STA interface, use that 3663 * interface's BSSID, otherwise use a dummy one 3664 * (where the OUI part needs to be nonzero for 3665 * the BSSID to be accepted by POST_SCAN). 3666 */ 3667 mwl8k_vif = mwl8k_first_vif(priv); 3668 if (mwl8k_vif != NULL) 3669 bssid = mwl8k_vif->vif->bss_conf.bssid; 3670 else 3671 bssid = "\x01\x00\x00\x00\x00\x00"; 3672 3673 mwl8k_cmd_set_post_scan(hw, bssid); 3674 } 3675 } 3676 3677 /* 3678 * If FIF_ALLMULTI is being requested, throw away the command 3679 * packet that ->prepare_multicast() built and replace it with 3680 * a command packet that enables reception of all multicast 3681 * packets. 3682 */ 3683 if (*total_flags & FIF_ALLMULTI) { 3684 kfree(cmd); 3685 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, NULL); 3686 } 3687 3688 if (cmd != NULL) { 3689 mwl8k_post_cmd(hw, cmd); 3690 kfree(cmd); 3691 } 3692 3693 mwl8k_fw_unlock(hw); 3694} 3695 3696static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3697{ 3698 return mwl8k_cmd_set_rts_threshold(hw, value); 3699} 3700 3701static int mwl8k_sta_remove(struct ieee80211_hw *hw, 3702 struct ieee80211_vif *vif, 3703 struct ieee80211_sta *sta) 3704{ 3705 struct mwl8k_priv *priv = hw->priv; 3706 3707 if (priv->ap_fw) 3708 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr); 3709 else 3710 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr); 3711} 3712 3713static int mwl8k_sta_add(struct ieee80211_hw *hw, 3714 struct ieee80211_vif *vif, 3715 struct ieee80211_sta *sta) 3716{ 3717 struct mwl8k_priv *priv = hw->priv; 3718 int ret; 3719 3720 if (!priv->ap_fw) { 3721 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); 3722 if (ret >= 0) { 3723 MWL8K_STA(sta)->peer_id = ret; 3724 return 0; 3725 } 3726 3727 return ret; 3728 } 3729 3730 return mwl8k_cmd_set_new_stn_add(hw, vif, sta); 3731} 3732 3733static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3734 const struct ieee80211_tx_queue_params *params) 3735{ 3736 struct mwl8k_priv *priv = hw->priv; 3737 int rc; 3738 3739 rc = mwl8k_fw_lock(hw); 3740 if (!rc) { 3741 if (!priv->wmm_enabled) 3742 rc = mwl8k_cmd_set_wmm_mode(hw, 1); 3743 3744 if (!rc) 3745 rc = mwl8k_cmd_set_edca_params(hw, queue, 3746 params->cw_min, 3747 params->cw_max, 3748 params->aifs, 3749 params->txop); 3750 3751 mwl8k_fw_unlock(hw); 3752 } 3753 3754 return rc; 3755} 3756 3757static int mwl8k_get_stats(struct ieee80211_hw *hw, 3758 struct ieee80211_low_level_stats *stats) 3759{ 3760 return mwl8k_cmd_get_stat(hw, stats); 3761} 3762 3763static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, 3764 struct survey_info *survey) 3765{ 3766 struct mwl8k_priv *priv = hw->priv; 3767 struct ieee80211_conf *conf = &hw->conf; 3768 3769 if (idx != 0) 3770 return -ENOENT; 3771 3772 survey->channel = conf->channel; 3773 survey->filled = SURVEY_INFO_NOISE_DBM; 3774 survey->noise = priv->noise; 3775 3776 return 0; 3777} 3778 3779static int 3780mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3781 enum ieee80211_ampdu_mlme_action action, 3782 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3783{ 3784 switch (action) { 3785 case IEEE80211_AMPDU_RX_START: 3786 case IEEE80211_AMPDU_RX_STOP: 3787 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 3788 return -ENOTSUPP; 3789 return 0; 3790 default: 3791 return -ENOTSUPP; 3792 } 3793} 3794 3795static const struct ieee80211_ops mwl8k_ops = { 3796 .tx = mwl8k_tx, 3797 .start = mwl8k_start, 3798 .stop = mwl8k_stop, 3799 .add_interface = mwl8k_add_interface, 3800 .remove_interface = mwl8k_remove_interface, 3801 .config = mwl8k_config, 3802 .bss_info_changed = mwl8k_bss_info_changed, 3803 .prepare_multicast = mwl8k_prepare_multicast, 3804 .configure_filter = mwl8k_configure_filter, 3805 .set_rts_threshold = mwl8k_set_rts_threshold, 3806 .sta_add = mwl8k_sta_add, 3807 .sta_remove = mwl8k_sta_remove, 3808 .conf_tx = mwl8k_conf_tx, 3809 .get_stats = mwl8k_get_stats, 3810 .get_survey = mwl8k_get_survey, 3811 .ampdu_action = mwl8k_ampdu_action, 3812}; 3813 3814static void mwl8k_finalize_join_worker(struct work_struct *work) 3815{ 3816 struct mwl8k_priv *priv = 3817 container_of(work, struct mwl8k_priv, finalize_join_worker); 3818 struct sk_buff *skb = priv->beacon_skb; 3819 struct ieee80211_mgmt *mgmt = (void *)skb->data; 3820 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); 3821 const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM, 3822 mgmt->u.beacon.variable, len); 3823 int dtim_period = 1; 3824 3825 if (tim && tim[1] >= 2) 3826 dtim_period = tim[3]; 3827 3828 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); 3829 3830 dev_kfree_skb(skb); 3831 priv->beacon_skb = NULL; 3832} 3833 3834enum { 3835 MWL8363 = 0, 3836 MWL8687, 3837 MWL8366, 3838}; 3839 3840static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { 3841 [MWL8363] = { 3842 .part_name = "88w8363", 3843 .helper_image = "mwl8k/helper_8363.fw", 3844 .fw_image = "mwl8k/fmimage_8363.fw", 3845 }, 3846 [MWL8687] = { 3847 .part_name = "88w8687", 3848 .helper_image = "mwl8k/helper_8687.fw", 3849 .fw_image = "mwl8k/fmimage_8687.fw", 3850 }, 3851 [MWL8366] = { 3852 .part_name = "88w8366", 3853 .helper_image = "mwl8k/helper_8366.fw", 3854 .fw_image = "mwl8k/fmimage_8366.fw", 3855 .ap_rxd_ops = &rxd_8366_ap_ops, 3856 }, 3857}; 3858 3859MODULE_FIRMWARE("mwl8k/helper_8363.fw"); 3860MODULE_FIRMWARE("mwl8k/fmimage_8363.fw"); 3861MODULE_FIRMWARE("mwl8k/helper_8687.fw"); 3862MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); 3863MODULE_FIRMWARE("mwl8k/helper_8366.fw"); 3864MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); 3865 3866static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { 3867 { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, 3868 { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, 3869 { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, 3870 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, 3871 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, }, 3872 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, }, 3873 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, }, 3874 { }, 3875}; 3876MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); 3877 3878static int __devinit mwl8k_probe(struct pci_dev *pdev, 3879 const struct pci_device_id *id) 3880{ 3881 static int printed_version = 0; 3882 struct ieee80211_hw *hw; 3883 struct mwl8k_priv *priv; 3884 int rc; 3885 int i; 3886 3887 if (!printed_version) { 3888 printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION); 3889 printed_version = 1; 3890 } 3891 3892 3893 rc = pci_enable_device(pdev); 3894 if (rc) { 3895 printk(KERN_ERR "%s: Cannot enable new PCI device\n", 3896 MWL8K_NAME); 3897 return rc; 3898 } 3899 3900 rc = pci_request_regions(pdev, MWL8K_NAME); 3901 if (rc) { 3902 printk(KERN_ERR "%s: Cannot obtain PCI resources\n", 3903 MWL8K_NAME); 3904 goto err_disable_device; 3905 } 3906 3907 pci_set_master(pdev); 3908 3909 3910 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); 3911 if (hw == NULL) { 3912 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); 3913 rc = -ENOMEM; 3914 goto err_free_reg; 3915 } 3916 3917 SET_IEEE80211_DEV(hw, &pdev->dev); 3918 pci_set_drvdata(pdev, hw); 3919 3920 priv = hw->priv; 3921 priv->hw = hw; 3922 priv->pdev = pdev; 3923 priv->device_info = &mwl8k_info_tbl[id->driver_data]; 3924 3925 3926 priv->sram = pci_iomap(pdev, 0, 0x10000); 3927 if (priv->sram == NULL) { 3928 wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); 3929 goto err_iounmap; 3930 } 3931 3932 /* 3933 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. 3934 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. 3935 */ 3936 priv->regs = pci_iomap(pdev, 1, 0x10000); 3937 if (priv->regs == NULL) { 3938 priv->regs = pci_iomap(pdev, 2, 0x10000); 3939 if (priv->regs == NULL) { 3940 wiphy_err(hw->wiphy, "Cannot map device registers\n"); 3941 goto err_iounmap; 3942 } 3943 } 3944 3945 3946 /* Reset firmware and hardware */ 3947 mwl8k_hw_reset(priv); 3948 3949 /* Ask userland hotplug daemon for the device firmware */ 3950 rc = mwl8k_request_firmware(priv); 3951 if (rc) { 3952 wiphy_err(hw->wiphy, "Firmware files not found\n"); 3953 goto err_stop_firmware; 3954 } 3955 3956 /* Load firmware into hardware */ 3957 rc = mwl8k_load_firmware(hw); 3958 if (rc) { 3959 wiphy_err(hw->wiphy, "Cannot start firmware\n"); 3960 goto err_stop_firmware; 3961 } 3962 3963 /* Reclaim memory once firmware is successfully loaded */ 3964 mwl8k_release_firmware(priv); 3965 3966 3967 if (priv->ap_fw) { 3968 priv->rxd_ops = priv->device_info->ap_rxd_ops; 3969 if (priv->rxd_ops == NULL) { 3970 wiphy_err(hw->wiphy, 3971 "Driver does not have AP firmware image support for this hardware\n"); 3972 goto err_stop_firmware; 3973 } 3974 } else { 3975 priv->rxd_ops = &rxd_sta_ops; 3976 } 3977 3978 priv->sniffer_enabled = false; 3979 priv->wmm_enabled = false; 3980 priv->pending_tx_pkts = 0; 3981 3982 3983 /* 3984 * Extra headroom is the size of the required DMA header 3985 * minus the size of the smallest 802.11 frame (CTS frame). 3986 */ 3987 hw->extra_tx_headroom = 3988 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); 3989 3990 hw->channel_change_time = 10; 3991 3992 hw->queues = MWL8K_TX_QUEUES; 3993 3994 /* Set rssi values to dBm */ 3995 hw->flags |= IEEE80211_HW_SIGNAL_DBM; 3996 hw->vif_data_size = sizeof(struct mwl8k_vif); 3997 hw->sta_data_size = sizeof(struct mwl8k_sta); 3998 3999 priv->macids_used = 0; 4000 INIT_LIST_HEAD(&priv->vif_list); 4001 4002 /* Set default radio state and preamble */ 4003 priv->radio_on = 0; 4004 priv->radio_short_preamble = 0; 4005 4006 /* Finalize join worker */ 4007 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 4008 4009 /* TX reclaim and RX tasklets. */ 4010 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); 4011 tasklet_disable(&priv->poll_tx_task); 4012 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw); 4013 tasklet_disable(&priv->poll_rx_task); 4014 4015 /* Power management cookie */ 4016 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); 4017 if (priv->cookie == NULL) 4018 goto err_stop_firmware; 4019 4020 rc = mwl8k_rxq_init(hw, 0); 4021 if (rc) 4022 goto err_free_cookie; 4023 rxq_refill(hw, 0, INT_MAX); 4024 4025 mutex_init(&priv->fw_mutex); 4026 priv->fw_mutex_owner = NULL; 4027 priv->fw_mutex_depth = 0; 4028 priv->hostcmd_wait = NULL; 4029 4030 spin_lock_init(&priv->tx_lock); 4031 4032 priv->tx_wait = NULL; 4033 4034 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 4035 rc = mwl8k_txq_init(hw, i); 4036 if (rc) 4037 goto err_free_queues; 4038 } 4039 4040 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4041 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4042 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, 4043 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 4044 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 4045 4046 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 4047 IRQF_SHARED, MWL8K_NAME, hw); 4048 if (rc) { 4049 wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); 4050 goto err_free_queues; 4051 } 4052 4053 /* 4054 * Temporarily enable interrupts. Initial firmware host 4055 * commands use interrupts and avoid polling. Disable 4056 * interrupts when done. 4057 */ 4058 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4059 4060 /* Get config data, mac addrs etc */ 4061 if (priv->ap_fw) { 4062 rc = mwl8k_cmd_get_hw_spec_ap(hw); 4063 if (!rc) 4064 rc = mwl8k_cmd_set_hw_spec(hw); 4065 } else { 4066 rc = mwl8k_cmd_get_hw_spec_sta(hw); 4067 } 4068 if (rc) { 4069 wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); 4070 goto err_free_irq; 4071 } 4072 4073 hw->wiphy->interface_modes = 0; 4074 if (priv->ap_macids_supported) 4075 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); 4076 if (priv->sta_macids_supported) 4077 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); 4078 4079 4080 /* Turn radio off */ 4081 rc = mwl8k_cmd_radio_disable(hw); 4082 if (rc) { 4083 wiphy_err(hw->wiphy, "Cannot disable\n"); 4084 goto err_free_irq; 4085 } 4086 4087 /* Clear MAC address */ 4088 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); 4089 if (rc) { 4090 wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); 4091 goto err_free_irq; 4092 } 4093 4094 /* Disable interrupts */ 4095 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4096 free_irq(priv->pdev->irq, hw); 4097 4098 rc = ieee80211_register_hw(hw); 4099 if (rc) { 4100 wiphy_err(hw->wiphy, "Cannot register device\n"); 4101 goto err_free_queues; 4102 } 4103 4104 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", 4105 priv->device_info->part_name, 4106 priv->hw_rev, hw->wiphy->perm_addr, 4107 priv->ap_fw ? "AP" : "STA", 4108 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, 4109 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); 4110 4111 return 0; 4112 4113err_free_irq: 4114 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4115 free_irq(priv->pdev->irq, hw); 4116 4117err_free_queues: 4118 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4119 mwl8k_txq_deinit(hw, i); 4120 mwl8k_rxq_deinit(hw, 0); 4121 4122err_free_cookie: 4123 if (priv->cookie != NULL) 4124 pci_free_consistent(priv->pdev, 4, 4125 priv->cookie, priv->cookie_dma); 4126 4127err_stop_firmware: 4128 mwl8k_hw_reset(priv); 4129 mwl8k_release_firmware(priv); 4130 4131err_iounmap: 4132 if (priv->regs != NULL) 4133 pci_iounmap(pdev, priv->regs); 4134 4135 if (priv->sram != NULL) 4136 pci_iounmap(pdev, priv->sram); 4137 4138 pci_set_drvdata(pdev, NULL); 4139 ieee80211_free_hw(hw); 4140 4141err_free_reg: 4142 pci_release_regions(pdev); 4143 4144err_disable_device: 4145 pci_disable_device(pdev); 4146 4147 return rc; 4148} 4149 4150static void __devexit mwl8k_shutdown(struct pci_dev *pdev) 4151{ 4152 printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__); 4153} 4154 4155static void __devexit mwl8k_remove(struct pci_dev *pdev) 4156{ 4157 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 4158 struct mwl8k_priv *priv; 4159 int i; 4160 4161 if (hw == NULL) 4162 return; 4163 priv = hw->priv; 4164 4165 ieee80211_stop_queues(hw); 4166 4167 ieee80211_unregister_hw(hw); 4168 4169 /* Remove TX reclaim and RX tasklets. */ 4170 tasklet_kill(&priv->poll_tx_task); 4171 tasklet_kill(&priv->poll_rx_task); 4172 4173 /* Stop hardware */ 4174 mwl8k_hw_reset(priv); 4175 4176 /* Return all skbs to mac80211 */ 4177 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4178 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 4179 4180 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4181 mwl8k_txq_deinit(hw, i); 4182 4183 mwl8k_rxq_deinit(hw, 0); 4184 4185 pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma); 4186 4187 pci_iounmap(pdev, priv->regs); 4188 pci_iounmap(pdev, priv->sram); 4189 pci_set_drvdata(pdev, NULL); 4190 ieee80211_free_hw(hw); 4191 pci_release_regions(pdev); 4192 pci_disable_device(pdev); 4193} 4194 4195static struct pci_driver mwl8k_driver = { 4196 .name = MWL8K_NAME, 4197 .id_table = mwl8k_pci_id_table, 4198 .probe = mwl8k_probe, 4199 .remove = __devexit_p(mwl8k_remove), 4200 .shutdown = __devexit_p(mwl8k_shutdown), 4201}; 4202 4203static int __init mwl8k_init(void) 4204{ 4205 return pci_register_driver(&mwl8k_driver); 4206} 4207 4208static void __exit mwl8k_exit(void) 4209{ 4210 pci_unregister_driver(&mwl8k_driver); 4211} 4212 4213module_init(mwl8k_init); 4214module_exit(mwl8k_exit); 4215 4216MODULE_DESCRIPTION(MWL8K_DESC); 4217MODULE_VERSION(MWL8K_VERSION); 4218MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>"); 4219MODULE_LICENSE("GPL"); 4220