1*7ac9a364SKalle Valo /****************************************************************************** 2*7ac9a364SKalle Valo * 3*7ac9a364SKalle Valo * GPL LICENSE SUMMARY 4*7ac9a364SKalle Valo * 5*7ac9a364SKalle Valo * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 6*7ac9a364SKalle Valo * 7*7ac9a364SKalle Valo * This program is free software; you can redistribute it and/or modify 8*7ac9a364SKalle Valo * it under the terms of version 2 of the GNU General Public License as 9*7ac9a364SKalle Valo * published by the Free Software Foundation. 10*7ac9a364SKalle Valo * 11*7ac9a364SKalle Valo * This program is distributed in the hope that it will be useful, but 12*7ac9a364SKalle Valo * WITHOUT ANY WARRANTY; without even the implied warranty of 13*7ac9a364SKalle Valo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*7ac9a364SKalle Valo * General Public License for more details. 15*7ac9a364SKalle Valo * 16*7ac9a364SKalle Valo * You should have received a copy of the GNU General Public License 17*7ac9a364SKalle Valo * along with this program; if not, write to the Free Software 18*7ac9a364SKalle Valo * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 19*7ac9a364SKalle Valo * USA 20*7ac9a364SKalle Valo * 21*7ac9a364SKalle Valo * The full GNU General Public License is included in this distribution 22*7ac9a364SKalle Valo * in the file called LICENSE.GPL. 23*7ac9a364SKalle Valo * 24*7ac9a364SKalle Valo * Contact Information: 25*7ac9a364SKalle Valo * Intel Linux Wireless <ilw@linux.intel.com> 26*7ac9a364SKalle Valo * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27*7ac9a364SKalle Valo *****************************************************************************/ 28*7ac9a364SKalle Valo 29*7ac9a364SKalle Valo #include <linux/kernel.h> 30*7ac9a364SKalle Valo #include <linux/module.h> 31*7ac9a364SKalle Valo #include <linux/etherdevice.h> 32*7ac9a364SKalle Valo #include <linux/sched.h> 33*7ac9a364SKalle Valo #include <linux/slab.h> 34*7ac9a364SKalle Valo #include <linux/types.h> 35*7ac9a364SKalle Valo #include <linux/lockdep.h> 36*7ac9a364SKalle Valo #include <linux/pci.h> 37*7ac9a364SKalle Valo #include <linux/dma-mapping.h> 38*7ac9a364SKalle Valo #include <linux/delay.h> 39*7ac9a364SKalle Valo #include <linux/skbuff.h> 40*7ac9a364SKalle Valo #include <net/mac80211.h> 41*7ac9a364SKalle Valo 42*7ac9a364SKalle Valo #include "common.h" 43*7ac9a364SKalle Valo 44*7ac9a364SKalle Valo int 45*7ac9a364SKalle Valo _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout) 46*7ac9a364SKalle Valo { 47*7ac9a364SKalle Valo const int interval = 10; /* microseconds */ 48*7ac9a364SKalle Valo int t = 0; 49*7ac9a364SKalle Valo 50*7ac9a364SKalle Valo do { 51*7ac9a364SKalle Valo if ((_il_rd(il, addr) & mask) == (bits & mask)) 52*7ac9a364SKalle Valo return t; 53*7ac9a364SKalle Valo udelay(interval); 54*7ac9a364SKalle Valo t += interval; 55*7ac9a364SKalle Valo } while (t < timeout); 56*7ac9a364SKalle Valo 57*7ac9a364SKalle Valo return -ETIMEDOUT; 58*7ac9a364SKalle Valo } 59*7ac9a364SKalle Valo EXPORT_SYMBOL(_il_poll_bit); 60*7ac9a364SKalle Valo 61*7ac9a364SKalle Valo void 62*7ac9a364SKalle Valo il_set_bit(struct il_priv *p, u32 r, u32 m) 63*7ac9a364SKalle Valo { 64*7ac9a364SKalle Valo unsigned long reg_flags; 65*7ac9a364SKalle Valo 66*7ac9a364SKalle Valo spin_lock_irqsave(&p->reg_lock, reg_flags); 67*7ac9a364SKalle Valo _il_set_bit(p, r, m); 68*7ac9a364SKalle Valo spin_unlock_irqrestore(&p->reg_lock, reg_flags); 69*7ac9a364SKalle Valo } 70*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_bit); 71*7ac9a364SKalle Valo 72*7ac9a364SKalle Valo void 73*7ac9a364SKalle Valo il_clear_bit(struct il_priv *p, u32 r, u32 m) 74*7ac9a364SKalle Valo { 75*7ac9a364SKalle Valo unsigned long reg_flags; 76*7ac9a364SKalle Valo 77*7ac9a364SKalle Valo spin_lock_irqsave(&p->reg_lock, reg_flags); 78*7ac9a364SKalle Valo _il_clear_bit(p, r, m); 79*7ac9a364SKalle Valo spin_unlock_irqrestore(&p->reg_lock, reg_flags); 80*7ac9a364SKalle Valo } 81*7ac9a364SKalle Valo EXPORT_SYMBOL(il_clear_bit); 82*7ac9a364SKalle Valo 83*7ac9a364SKalle Valo bool 84*7ac9a364SKalle Valo _il_grab_nic_access(struct il_priv *il) 85*7ac9a364SKalle Valo { 86*7ac9a364SKalle Valo int ret; 87*7ac9a364SKalle Valo u32 val; 88*7ac9a364SKalle Valo 89*7ac9a364SKalle Valo /* this bit wakes up the NIC */ 90*7ac9a364SKalle Valo _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 91*7ac9a364SKalle Valo 92*7ac9a364SKalle Valo /* 93*7ac9a364SKalle Valo * These bits say the device is running, and should keep running for 94*7ac9a364SKalle Valo * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), 95*7ac9a364SKalle Valo * but they do not indicate that embedded SRAM is restored yet; 96*7ac9a364SKalle Valo * 3945 and 4965 have volatile SRAM, and must save/restore contents 97*7ac9a364SKalle Valo * to/from host DRAM when sleeping/waking for power-saving. 98*7ac9a364SKalle Valo * Each direction takes approximately 1/4 millisecond; with this 99*7ac9a364SKalle Valo * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a 100*7ac9a364SKalle Valo * series of register accesses are expected (e.g. reading Event Log), 101*7ac9a364SKalle Valo * to keep device from sleeping. 102*7ac9a364SKalle Valo * 103*7ac9a364SKalle Valo * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that 104*7ac9a364SKalle Valo * SRAM is okay/restored. We don't check that here because this call 105*7ac9a364SKalle Valo * is just for hardware register access; but GP1 MAC_SLEEP check is a 106*7ac9a364SKalle Valo * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). 107*7ac9a364SKalle Valo * 108*7ac9a364SKalle Valo */ 109*7ac9a364SKalle Valo ret = 110*7ac9a364SKalle Valo _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, 111*7ac9a364SKalle Valo (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 112*7ac9a364SKalle Valo CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); 113*7ac9a364SKalle Valo if (unlikely(ret < 0)) { 114*7ac9a364SKalle Valo val = _il_rd(il, CSR_GP_CNTRL); 115*7ac9a364SKalle Valo WARN_ONCE(1, "Timeout waiting for ucode processor access " 116*7ac9a364SKalle Valo "(CSR_GP_CNTRL 0x%08x)\n", val); 117*7ac9a364SKalle Valo _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); 118*7ac9a364SKalle Valo return false; 119*7ac9a364SKalle Valo } 120*7ac9a364SKalle Valo 121*7ac9a364SKalle Valo return true; 122*7ac9a364SKalle Valo } 123*7ac9a364SKalle Valo EXPORT_SYMBOL_GPL(_il_grab_nic_access); 124*7ac9a364SKalle Valo 125*7ac9a364SKalle Valo int 126*7ac9a364SKalle Valo il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout) 127*7ac9a364SKalle Valo { 128*7ac9a364SKalle Valo const int interval = 10; /* microseconds */ 129*7ac9a364SKalle Valo int t = 0; 130*7ac9a364SKalle Valo 131*7ac9a364SKalle Valo do { 132*7ac9a364SKalle Valo if ((il_rd(il, addr) & mask) == mask) 133*7ac9a364SKalle Valo return t; 134*7ac9a364SKalle Valo udelay(interval); 135*7ac9a364SKalle Valo t += interval; 136*7ac9a364SKalle Valo } while (t < timeout); 137*7ac9a364SKalle Valo 138*7ac9a364SKalle Valo return -ETIMEDOUT; 139*7ac9a364SKalle Valo } 140*7ac9a364SKalle Valo EXPORT_SYMBOL(il_poll_bit); 141*7ac9a364SKalle Valo 142*7ac9a364SKalle Valo u32 143*7ac9a364SKalle Valo il_rd_prph(struct il_priv *il, u32 reg) 144*7ac9a364SKalle Valo { 145*7ac9a364SKalle Valo unsigned long reg_flags; 146*7ac9a364SKalle Valo u32 val; 147*7ac9a364SKalle Valo 148*7ac9a364SKalle Valo spin_lock_irqsave(&il->reg_lock, reg_flags); 149*7ac9a364SKalle Valo _il_grab_nic_access(il); 150*7ac9a364SKalle Valo val = _il_rd_prph(il, reg); 151*7ac9a364SKalle Valo _il_release_nic_access(il); 152*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->reg_lock, reg_flags); 153*7ac9a364SKalle Valo return val; 154*7ac9a364SKalle Valo } 155*7ac9a364SKalle Valo EXPORT_SYMBOL(il_rd_prph); 156*7ac9a364SKalle Valo 157*7ac9a364SKalle Valo void 158*7ac9a364SKalle Valo il_wr_prph(struct il_priv *il, u32 addr, u32 val) 159*7ac9a364SKalle Valo { 160*7ac9a364SKalle Valo unsigned long reg_flags; 161*7ac9a364SKalle Valo 162*7ac9a364SKalle Valo spin_lock_irqsave(&il->reg_lock, reg_flags); 163*7ac9a364SKalle Valo if (likely(_il_grab_nic_access(il))) { 164*7ac9a364SKalle Valo _il_wr_prph(il, addr, val); 165*7ac9a364SKalle Valo _il_release_nic_access(il); 166*7ac9a364SKalle Valo } 167*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->reg_lock, reg_flags); 168*7ac9a364SKalle Valo } 169*7ac9a364SKalle Valo EXPORT_SYMBOL(il_wr_prph); 170*7ac9a364SKalle Valo 171*7ac9a364SKalle Valo u32 172*7ac9a364SKalle Valo il_read_targ_mem(struct il_priv *il, u32 addr) 173*7ac9a364SKalle Valo { 174*7ac9a364SKalle Valo unsigned long reg_flags; 175*7ac9a364SKalle Valo u32 value; 176*7ac9a364SKalle Valo 177*7ac9a364SKalle Valo spin_lock_irqsave(&il->reg_lock, reg_flags); 178*7ac9a364SKalle Valo _il_grab_nic_access(il); 179*7ac9a364SKalle Valo 180*7ac9a364SKalle Valo _il_wr(il, HBUS_TARG_MEM_RADDR, addr); 181*7ac9a364SKalle Valo value = _il_rd(il, HBUS_TARG_MEM_RDAT); 182*7ac9a364SKalle Valo 183*7ac9a364SKalle Valo _il_release_nic_access(il); 184*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->reg_lock, reg_flags); 185*7ac9a364SKalle Valo return value; 186*7ac9a364SKalle Valo } 187*7ac9a364SKalle Valo EXPORT_SYMBOL(il_read_targ_mem); 188*7ac9a364SKalle Valo 189*7ac9a364SKalle Valo void 190*7ac9a364SKalle Valo il_write_targ_mem(struct il_priv *il, u32 addr, u32 val) 191*7ac9a364SKalle Valo { 192*7ac9a364SKalle Valo unsigned long reg_flags; 193*7ac9a364SKalle Valo 194*7ac9a364SKalle Valo spin_lock_irqsave(&il->reg_lock, reg_flags); 195*7ac9a364SKalle Valo if (likely(_il_grab_nic_access(il))) { 196*7ac9a364SKalle Valo _il_wr(il, HBUS_TARG_MEM_WADDR, addr); 197*7ac9a364SKalle Valo _il_wr(il, HBUS_TARG_MEM_WDAT, val); 198*7ac9a364SKalle Valo _il_release_nic_access(il); 199*7ac9a364SKalle Valo } 200*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->reg_lock, reg_flags); 201*7ac9a364SKalle Valo } 202*7ac9a364SKalle Valo EXPORT_SYMBOL(il_write_targ_mem); 203*7ac9a364SKalle Valo 204*7ac9a364SKalle Valo const char * 205*7ac9a364SKalle Valo il_get_cmd_string(u8 cmd) 206*7ac9a364SKalle Valo { 207*7ac9a364SKalle Valo switch (cmd) { 208*7ac9a364SKalle Valo IL_CMD(N_ALIVE); 209*7ac9a364SKalle Valo IL_CMD(N_ERROR); 210*7ac9a364SKalle Valo IL_CMD(C_RXON); 211*7ac9a364SKalle Valo IL_CMD(C_RXON_ASSOC); 212*7ac9a364SKalle Valo IL_CMD(C_QOS_PARAM); 213*7ac9a364SKalle Valo IL_CMD(C_RXON_TIMING); 214*7ac9a364SKalle Valo IL_CMD(C_ADD_STA); 215*7ac9a364SKalle Valo IL_CMD(C_REM_STA); 216*7ac9a364SKalle Valo IL_CMD(C_WEPKEY); 217*7ac9a364SKalle Valo IL_CMD(N_3945_RX); 218*7ac9a364SKalle Valo IL_CMD(C_TX); 219*7ac9a364SKalle Valo IL_CMD(C_RATE_SCALE); 220*7ac9a364SKalle Valo IL_CMD(C_LEDS); 221*7ac9a364SKalle Valo IL_CMD(C_TX_LINK_QUALITY_CMD); 222*7ac9a364SKalle Valo IL_CMD(C_CHANNEL_SWITCH); 223*7ac9a364SKalle Valo IL_CMD(N_CHANNEL_SWITCH); 224*7ac9a364SKalle Valo IL_CMD(C_SPECTRUM_MEASUREMENT); 225*7ac9a364SKalle Valo IL_CMD(N_SPECTRUM_MEASUREMENT); 226*7ac9a364SKalle Valo IL_CMD(C_POWER_TBL); 227*7ac9a364SKalle Valo IL_CMD(N_PM_SLEEP); 228*7ac9a364SKalle Valo IL_CMD(N_PM_DEBUG_STATS); 229*7ac9a364SKalle Valo IL_CMD(C_SCAN); 230*7ac9a364SKalle Valo IL_CMD(C_SCAN_ABORT); 231*7ac9a364SKalle Valo IL_CMD(N_SCAN_START); 232*7ac9a364SKalle Valo IL_CMD(N_SCAN_RESULTS); 233*7ac9a364SKalle Valo IL_CMD(N_SCAN_COMPLETE); 234*7ac9a364SKalle Valo IL_CMD(N_BEACON); 235*7ac9a364SKalle Valo IL_CMD(C_TX_BEACON); 236*7ac9a364SKalle Valo IL_CMD(C_TX_PWR_TBL); 237*7ac9a364SKalle Valo IL_CMD(C_BT_CONFIG); 238*7ac9a364SKalle Valo IL_CMD(C_STATS); 239*7ac9a364SKalle Valo IL_CMD(N_STATS); 240*7ac9a364SKalle Valo IL_CMD(N_CARD_STATE); 241*7ac9a364SKalle Valo IL_CMD(N_MISSED_BEACONS); 242*7ac9a364SKalle Valo IL_CMD(C_CT_KILL_CONFIG); 243*7ac9a364SKalle Valo IL_CMD(C_SENSITIVITY); 244*7ac9a364SKalle Valo IL_CMD(C_PHY_CALIBRATION); 245*7ac9a364SKalle Valo IL_CMD(N_RX_PHY); 246*7ac9a364SKalle Valo IL_CMD(N_RX_MPDU); 247*7ac9a364SKalle Valo IL_CMD(N_RX); 248*7ac9a364SKalle Valo IL_CMD(N_COMPRESSED_BA); 249*7ac9a364SKalle Valo default: 250*7ac9a364SKalle Valo return "UNKNOWN"; 251*7ac9a364SKalle Valo 252*7ac9a364SKalle Valo } 253*7ac9a364SKalle Valo } 254*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_cmd_string); 255*7ac9a364SKalle Valo 256*7ac9a364SKalle Valo #define HOST_COMPLETE_TIMEOUT (HZ / 2) 257*7ac9a364SKalle Valo 258*7ac9a364SKalle Valo static void 259*7ac9a364SKalle Valo il_generic_cmd_callback(struct il_priv *il, struct il_device_cmd *cmd, 260*7ac9a364SKalle Valo struct il_rx_pkt *pkt) 261*7ac9a364SKalle Valo { 262*7ac9a364SKalle Valo if (pkt->hdr.flags & IL_CMD_FAILED_MSK) { 263*7ac9a364SKalle Valo IL_ERR("Bad return from %s (0x%08X)\n", 264*7ac9a364SKalle Valo il_get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); 265*7ac9a364SKalle Valo return; 266*7ac9a364SKalle Valo } 267*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 268*7ac9a364SKalle Valo switch (cmd->hdr.cmd) { 269*7ac9a364SKalle Valo case C_TX_LINK_QUALITY_CMD: 270*7ac9a364SKalle Valo case C_SENSITIVITY: 271*7ac9a364SKalle Valo D_HC_DUMP("back from %s (0x%08X)\n", 272*7ac9a364SKalle Valo il_get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); 273*7ac9a364SKalle Valo break; 274*7ac9a364SKalle Valo default: 275*7ac9a364SKalle Valo D_HC("back from %s (0x%08X)\n", il_get_cmd_string(cmd->hdr.cmd), 276*7ac9a364SKalle Valo pkt->hdr.flags); 277*7ac9a364SKalle Valo } 278*7ac9a364SKalle Valo #endif 279*7ac9a364SKalle Valo } 280*7ac9a364SKalle Valo 281*7ac9a364SKalle Valo static int 282*7ac9a364SKalle Valo il_send_cmd_async(struct il_priv *il, struct il_host_cmd *cmd) 283*7ac9a364SKalle Valo { 284*7ac9a364SKalle Valo int ret; 285*7ac9a364SKalle Valo 286*7ac9a364SKalle Valo BUG_ON(!(cmd->flags & CMD_ASYNC)); 287*7ac9a364SKalle Valo 288*7ac9a364SKalle Valo /* An asynchronous command can not expect an SKB to be set. */ 289*7ac9a364SKalle Valo BUG_ON(cmd->flags & CMD_WANT_SKB); 290*7ac9a364SKalle Valo 291*7ac9a364SKalle Valo /* Assign a generic callback if one is not provided */ 292*7ac9a364SKalle Valo if (!cmd->callback) 293*7ac9a364SKalle Valo cmd->callback = il_generic_cmd_callback; 294*7ac9a364SKalle Valo 295*7ac9a364SKalle Valo if (test_bit(S_EXIT_PENDING, &il->status)) 296*7ac9a364SKalle Valo return -EBUSY; 297*7ac9a364SKalle Valo 298*7ac9a364SKalle Valo ret = il_enqueue_hcmd(il, cmd); 299*7ac9a364SKalle Valo if (ret < 0) { 300*7ac9a364SKalle Valo IL_ERR("Error sending %s: enqueue_hcmd failed: %d\n", 301*7ac9a364SKalle Valo il_get_cmd_string(cmd->id), ret); 302*7ac9a364SKalle Valo return ret; 303*7ac9a364SKalle Valo } 304*7ac9a364SKalle Valo return 0; 305*7ac9a364SKalle Valo } 306*7ac9a364SKalle Valo 307*7ac9a364SKalle Valo int 308*7ac9a364SKalle Valo il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd) 309*7ac9a364SKalle Valo { 310*7ac9a364SKalle Valo int cmd_idx; 311*7ac9a364SKalle Valo int ret; 312*7ac9a364SKalle Valo 313*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 314*7ac9a364SKalle Valo 315*7ac9a364SKalle Valo BUG_ON(cmd->flags & CMD_ASYNC); 316*7ac9a364SKalle Valo 317*7ac9a364SKalle Valo /* A synchronous command can not have a callback set. */ 318*7ac9a364SKalle Valo BUG_ON(cmd->callback); 319*7ac9a364SKalle Valo 320*7ac9a364SKalle Valo D_INFO("Attempting to send sync command %s\n", 321*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 322*7ac9a364SKalle Valo 323*7ac9a364SKalle Valo set_bit(S_HCMD_ACTIVE, &il->status); 324*7ac9a364SKalle Valo D_INFO("Setting HCMD_ACTIVE for command %s\n", 325*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 326*7ac9a364SKalle Valo 327*7ac9a364SKalle Valo cmd_idx = il_enqueue_hcmd(il, cmd); 328*7ac9a364SKalle Valo if (cmd_idx < 0) { 329*7ac9a364SKalle Valo ret = cmd_idx; 330*7ac9a364SKalle Valo IL_ERR("Error sending %s: enqueue_hcmd failed: %d\n", 331*7ac9a364SKalle Valo il_get_cmd_string(cmd->id), ret); 332*7ac9a364SKalle Valo goto out; 333*7ac9a364SKalle Valo } 334*7ac9a364SKalle Valo 335*7ac9a364SKalle Valo ret = wait_event_timeout(il->wait_command_queue, 336*7ac9a364SKalle Valo !test_bit(S_HCMD_ACTIVE, &il->status), 337*7ac9a364SKalle Valo HOST_COMPLETE_TIMEOUT); 338*7ac9a364SKalle Valo if (!ret) { 339*7ac9a364SKalle Valo if (test_bit(S_HCMD_ACTIVE, &il->status)) { 340*7ac9a364SKalle Valo IL_ERR("Error sending %s: time out after %dms.\n", 341*7ac9a364SKalle Valo il_get_cmd_string(cmd->id), 342*7ac9a364SKalle Valo jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 343*7ac9a364SKalle Valo 344*7ac9a364SKalle Valo clear_bit(S_HCMD_ACTIVE, &il->status); 345*7ac9a364SKalle Valo D_INFO("Clearing HCMD_ACTIVE for command %s\n", 346*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 347*7ac9a364SKalle Valo ret = -ETIMEDOUT; 348*7ac9a364SKalle Valo goto cancel; 349*7ac9a364SKalle Valo } 350*7ac9a364SKalle Valo } 351*7ac9a364SKalle Valo 352*7ac9a364SKalle Valo if (test_bit(S_RFKILL, &il->status)) { 353*7ac9a364SKalle Valo IL_ERR("Command %s aborted: RF KILL Switch\n", 354*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 355*7ac9a364SKalle Valo ret = -ECANCELED; 356*7ac9a364SKalle Valo goto fail; 357*7ac9a364SKalle Valo } 358*7ac9a364SKalle Valo if (test_bit(S_FW_ERROR, &il->status)) { 359*7ac9a364SKalle Valo IL_ERR("Command %s failed: FW Error\n", 360*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 361*7ac9a364SKalle Valo ret = -EIO; 362*7ac9a364SKalle Valo goto fail; 363*7ac9a364SKalle Valo } 364*7ac9a364SKalle Valo if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { 365*7ac9a364SKalle Valo IL_ERR("Error: Response NULL in '%s'\n", 366*7ac9a364SKalle Valo il_get_cmd_string(cmd->id)); 367*7ac9a364SKalle Valo ret = -EIO; 368*7ac9a364SKalle Valo goto cancel; 369*7ac9a364SKalle Valo } 370*7ac9a364SKalle Valo 371*7ac9a364SKalle Valo ret = 0; 372*7ac9a364SKalle Valo goto out; 373*7ac9a364SKalle Valo 374*7ac9a364SKalle Valo cancel: 375*7ac9a364SKalle Valo if (cmd->flags & CMD_WANT_SKB) { 376*7ac9a364SKalle Valo /* 377*7ac9a364SKalle Valo * Cancel the CMD_WANT_SKB flag for the cmd in the 378*7ac9a364SKalle Valo * TX cmd queue. Otherwise in case the cmd comes 379*7ac9a364SKalle Valo * in later, it will possibly set an invalid 380*7ac9a364SKalle Valo * address (cmd->meta.source). 381*7ac9a364SKalle Valo */ 382*7ac9a364SKalle Valo il->txq[il->cmd_queue].meta[cmd_idx].flags &= ~CMD_WANT_SKB; 383*7ac9a364SKalle Valo } 384*7ac9a364SKalle Valo fail: 385*7ac9a364SKalle Valo if (cmd->reply_page) { 386*7ac9a364SKalle Valo il_free_pages(il, cmd->reply_page); 387*7ac9a364SKalle Valo cmd->reply_page = 0; 388*7ac9a364SKalle Valo } 389*7ac9a364SKalle Valo out: 390*7ac9a364SKalle Valo return ret; 391*7ac9a364SKalle Valo } 392*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_cmd_sync); 393*7ac9a364SKalle Valo 394*7ac9a364SKalle Valo int 395*7ac9a364SKalle Valo il_send_cmd(struct il_priv *il, struct il_host_cmd *cmd) 396*7ac9a364SKalle Valo { 397*7ac9a364SKalle Valo if (cmd->flags & CMD_ASYNC) 398*7ac9a364SKalle Valo return il_send_cmd_async(il, cmd); 399*7ac9a364SKalle Valo 400*7ac9a364SKalle Valo return il_send_cmd_sync(il, cmd); 401*7ac9a364SKalle Valo } 402*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_cmd); 403*7ac9a364SKalle Valo 404*7ac9a364SKalle Valo int 405*7ac9a364SKalle Valo il_send_cmd_pdu(struct il_priv *il, u8 id, u16 len, const void *data) 406*7ac9a364SKalle Valo { 407*7ac9a364SKalle Valo struct il_host_cmd cmd = { 408*7ac9a364SKalle Valo .id = id, 409*7ac9a364SKalle Valo .len = len, 410*7ac9a364SKalle Valo .data = data, 411*7ac9a364SKalle Valo }; 412*7ac9a364SKalle Valo 413*7ac9a364SKalle Valo return il_send_cmd_sync(il, &cmd); 414*7ac9a364SKalle Valo } 415*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_cmd_pdu); 416*7ac9a364SKalle Valo 417*7ac9a364SKalle Valo int 418*7ac9a364SKalle Valo il_send_cmd_pdu_async(struct il_priv *il, u8 id, u16 len, const void *data, 419*7ac9a364SKalle Valo void (*callback) (struct il_priv *il, 420*7ac9a364SKalle Valo struct il_device_cmd *cmd, 421*7ac9a364SKalle Valo struct il_rx_pkt *pkt)) 422*7ac9a364SKalle Valo { 423*7ac9a364SKalle Valo struct il_host_cmd cmd = { 424*7ac9a364SKalle Valo .id = id, 425*7ac9a364SKalle Valo .len = len, 426*7ac9a364SKalle Valo .data = data, 427*7ac9a364SKalle Valo }; 428*7ac9a364SKalle Valo 429*7ac9a364SKalle Valo cmd.flags |= CMD_ASYNC; 430*7ac9a364SKalle Valo cmd.callback = callback; 431*7ac9a364SKalle Valo 432*7ac9a364SKalle Valo return il_send_cmd_async(il, &cmd); 433*7ac9a364SKalle Valo } 434*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_cmd_pdu_async); 435*7ac9a364SKalle Valo 436*7ac9a364SKalle Valo /* default: IL_LED_BLINK(0) using blinking idx table */ 437*7ac9a364SKalle Valo static int led_mode; 438*7ac9a364SKalle Valo module_param(led_mode, int, S_IRUGO); 439*7ac9a364SKalle Valo MODULE_PARM_DESC(led_mode, 440*7ac9a364SKalle Valo "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); 441*7ac9a364SKalle Valo 442*7ac9a364SKalle Valo /* Throughput OFF time(ms) ON time (ms) 443*7ac9a364SKalle Valo * >300 25 25 444*7ac9a364SKalle Valo * >200 to 300 40 40 445*7ac9a364SKalle Valo * >100 to 200 55 55 446*7ac9a364SKalle Valo * >70 to 100 65 65 447*7ac9a364SKalle Valo * >50 to 70 75 75 448*7ac9a364SKalle Valo * >20 to 50 85 85 449*7ac9a364SKalle Valo * >10 to 20 95 95 450*7ac9a364SKalle Valo * >5 to 10 110 110 451*7ac9a364SKalle Valo * >1 to 5 130 130 452*7ac9a364SKalle Valo * >0 to 1 167 167 453*7ac9a364SKalle Valo * <=0 SOLID ON 454*7ac9a364SKalle Valo */ 455*7ac9a364SKalle Valo static const struct ieee80211_tpt_blink il_blink[] = { 456*7ac9a364SKalle Valo {.throughput = 0, .blink_time = 334}, 457*7ac9a364SKalle Valo {.throughput = 1 * 1024 - 1, .blink_time = 260}, 458*7ac9a364SKalle Valo {.throughput = 5 * 1024 - 1, .blink_time = 220}, 459*7ac9a364SKalle Valo {.throughput = 10 * 1024 - 1, .blink_time = 190}, 460*7ac9a364SKalle Valo {.throughput = 20 * 1024 - 1, .blink_time = 170}, 461*7ac9a364SKalle Valo {.throughput = 50 * 1024 - 1, .blink_time = 150}, 462*7ac9a364SKalle Valo {.throughput = 70 * 1024 - 1, .blink_time = 130}, 463*7ac9a364SKalle Valo {.throughput = 100 * 1024 - 1, .blink_time = 110}, 464*7ac9a364SKalle Valo {.throughput = 200 * 1024 - 1, .blink_time = 80}, 465*7ac9a364SKalle Valo {.throughput = 300 * 1024 - 1, .blink_time = 50}, 466*7ac9a364SKalle Valo }; 467*7ac9a364SKalle Valo 468*7ac9a364SKalle Valo /* 469*7ac9a364SKalle Valo * Adjust led blink rate to compensate on a MAC Clock difference on every HW 470*7ac9a364SKalle Valo * Led blink rate analysis showed an average deviation of 0% on 3945, 471*7ac9a364SKalle Valo * 5% on 4965 HW. 472*7ac9a364SKalle Valo * Need to compensate on the led on/off time per HW according to the deviation 473*7ac9a364SKalle Valo * to achieve the desired led frequency 474*7ac9a364SKalle Valo * The calculation is: (100-averageDeviation)/100 * blinkTime 475*7ac9a364SKalle Valo * For code efficiency the calculation will be: 476*7ac9a364SKalle Valo * compensation = (100 - averageDeviation) * 64 / 100 477*7ac9a364SKalle Valo * NewBlinkTime = (compensation * BlinkTime) / 64 478*7ac9a364SKalle Valo */ 479*7ac9a364SKalle Valo static inline u8 480*7ac9a364SKalle Valo il_blink_compensation(struct il_priv *il, u8 time, u16 compensation) 481*7ac9a364SKalle Valo { 482*7ac9a364SKalle Valo if (!compensation) { 483*7ac9a364SKalle Valo IL_ERR("undefined blink compensation: " 484*7ac9a364SKalle Valo "use pre-defined blinking time\n"); 485*7ac9a364SKalle Valo return time; 486*7ac9a364SKalle Valo } 487*7ac9a364SKalle Valo 488*7ac9a364SKalle Valo return (u8) ((time * compensation) >> 6); 489*7ac9a364SKalle Valo } 490*7ac9a364SKalle Valo 491*7ac9a364SKalle Valo /* Set led pattern command */ 492*7ac9a364SKalle Valo static int 493*7ac9a364SKalle Valo il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off) 494*7ac9a364SKalle Valo { 495*7ac9a364SKalle Valo struct il_led_cmd led_cmd = { 496*7ac9a364SKalle Valo .id = IL_LED_LINK, 497*7ac9a364SKalle Valo .interval = IL_DEF_LED_INTRVL 498*7ac9a364SKalle Valo }; 499*7ac9a364SKalle Valo int ret; 500*7ac9a364SKalle Valo 501*7ac9a364SKalle Valo if (!test_bit(S_READY, &il->status)) 502*7ac9a364SKalle Valo return -EBUSY; 503*7ac9a364SKalle Valo 504*7ac9a364SKalle Valo if (il->blink_on == on && il->blink_off == off) 505*7ac9a364SKalle Valo return 0; 506*7ac9a364SKalle Valo 507*7ac9a364SKalle Valo if (off == 0) { 508*7ac9a364SKalle Valo /* led is SOLID_ON */ 509*7ac9a364SKalle Valo on = IL_LED_SOLID; 510*7ac9a364SKalle Valo } 511*7ac9a364SKalle Valo 512*7ac9a364SKalle Valo D_LED("Led blink time compensation=%u\n", 513*7ac9a364SKalle Valo il->cfg->led_compensation); 514*7ac9a364SKalle Valo led_cmd.on = 515*7ac9a364SKalle Valo il_blink_compensation(il, on, 516*7ac9a364SKalle Valo il->cfg->led_compensation); 517*7ac9a364SKalle Valo led_cmd.off = 518*7ac9a364SKalle Valo il_blink_compensation(il, off, 519*7ac9a364SKalle Valo il->cfg->led_compensation); 520*7ac9a364SKalle Valo 521*7ac9a364SKalle Valo ret = il->ops->send_led_cmd(il, &led_cmd); 522*7ac9a364SKalle Valo if (!ret) { 523*7ac9a364SKalle Valo il->blink_on = on; 524*7ac9a364SKalle Valo il->blink_off = off; 525*7ac9a364SKalle Valo } 526*7ac9a364SKalle Valo return ret; 527*7ac9a364SKalle Valo } 528*7ac9a364SKalle Valo 529*7ac9a364SKalle Valo static void 530*7ac9a364SKalle Valo il_led_brightness_set(struct led_classdev *led_cdev, 531*7ac9a364SKalle Valo enum led_brightness brightness) 532*7ac9a364SKalle Valo { 533*7ac9a364SKalle Valo struct il_priv *il = container_of(led_cdev, struct il_priv, led); 534*7ac9a364SKalle Valo unsigned long on = 0; 535*7ac9a364SKalle Valo 536*7ac9a364SKalle Valo if (brightness > 0) 537*7ac9a364SKalle Valo on = IL_LED_SOLID; 538*7ac9a364SKalle Valo 539*7ac9a364SKalle Valo il_led_cmd(il, on, 0); 540*7ac9a364SKalle Valo } 541*7ac9a364SKalle Valo 542*7ac9a364SKalle Valo static int 543*7ac9a364SKalle Valo il_led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, 544*7ac9a364SKalle Valo unsigned long *delay_off) 545*7ac9a364SKalle Valo { 546*7ac9a364SKalle Valo struct il_priv *il = container_of(led_cdev, struct il_priv, led); 547*7ac9a364SKalle Valo 548*7ac9a364SKalle Valo return il_led_cmd(il, *delay_on, *delay_off); 549*7ac9a364SKalle Valo } 550*7ac9a364SKalle Valo 551*7ac9a364SKalle Valo void 552*7ac9a364SKalle Valo il_leds_init(struct il_priv *il) 553*7ac9a364SKalle Valo { 554*7ac9a364SKalle Valo int mode = led_mode; 555*7ac9a364SKalle Valo int ret; 556*7ac9a364SKalle Valo 557*7ac9a364SKalle Valo if (mode == IL_LED_DEFAULT) 558*7ac9a364SKalle Valo mode = il->cfg->led_mode; 559*7ac9a364SKalle Valo 560*7ac9a364SKalle Valo il->led.name = 561*7ac9a364SKalle Valo kasprintf(GFP_KERNEL, "%s-led", wiphy_name(il->hw->wiphy)); 562*7ac9a364SKalle Valo il->led.brightness_set = il_led_brightness_set; 563*7ac9a364SKalle Valo il->led.blink_set = il_led_blink_set; 564*7ac9a364SKalle Valo il->led.max_brightness = 1; 565*7ac9a364SKalle Valo 566*7ac9a364SKalle Valo switch (mode) { 567*7ac9a364SKalle Valo case IL_LED_DEFAULT: 568*7ac9a364SKalle Valo WARN_ON(1); 569*7ac9a364SKalle Valo break; 570*7ac9a364SKalle Valo case IL_LED_BLINK: 571*7ac9a364SKalle Valo il->led.default_trigger = 572*7ac9a364SKalle Valo ieee80211_create_tpt_led_trigger(il->hw, 573*7ac9a364SKalle Valo IEEE80211_TPT_LEDTRIG_FL_CONNECTED, 574*7ac9a364SKalle Valo il_blink, 575*7ac9a364SKalle Valo ARRAY_SIZE(il_blink)); 576*7ac9a364SKalle Valo break; 577*7ac9a364SKalle Valo case IL_LED_RF_STATE: 578*7ac9a364SKalle Valo il->led.default_trigger = ieee80211_get_radio_led_name(il->hw); 579*7ac9a364SKalle Valo break; 580*7ac9a364SKalle Valo } 581*7ac9a364SKalle Valo 582*7ac9a364SKalle Valo ret = led_classdev_register(&il->pci_dev->dev, &il->led); 583*7ac9a364SKalle Valo if (ret) { 584*7ac9a364SKalle Valo kfree(il->led.name); 585*7ac9a364SKalle Valo return; 586*7ac9a364SKalle Valo } 587*7ac9a364SKalle Valo 588*7ac9a364SKalle Valo il->led_registered = true; 589*7ac9a364SKalle Valo } 590*7ac9a364SKalle Valo EXPORT_SYMBOL(il_leds_init); 591*7ac9a364SKalle Valo 592*7ac9a364SKalle Valo void 593*7ac9a364SKalle Valo il_leds_exit(struct il_priv *il) 594*7ac9a364SKalle Valo { 595*7ac9a364SKalle Valo if (!il->led_registered) 596*7ac9a364SKalle Valo return; 597*7ac9a364SKalle Valo 598*7ac9a364SKalle Valo led_classdev_unregister(&il->led); 599*7ac9a364SKalle Valo kfree(il->led.name); 600*7ac9a364SKalle Valo } 601*7ac9a364SKalle Valo EXPORT_SYMBOL(il_leds_exit); 602*7ac9a364SKalle Valo 603*7ac9a364SKalle Valo /************************** EEPROM BANDS **************************** 604*7ac9a364SKalle Valo * 605*7ac9a364SKalle Valo * The il_eeprom_band definitions below provide the mapping from the 606*7ac9a364SKalle Valo * EEPROM contents to the specific channel number supported for each 607*7ac9a364SKalle Valo * band. 608*7ac9a364SKalle Valo * 609*7ac9a364SKalle Valo * For example, il_priv->eeprom.band_3_channels[4] from the band_3 610*7ac9a364SKalle Valo * definition below maps to physical channel 42 in the 5.2GHz spectrum. 611*7ac9a364SKalle Valo * The specific geography and calibration information for that channel 612*7ac9a364SKalle Valo * is contained in the eeprom map itself. 613*7ac9a364SKalle Valo * 614*7ac9a364SKalle Valo * During init, we copy the eeprom information and channel map 615*7ac9a364SKalle Valo * information into il->channel_info_24/52 and il->channel_map_24/52 616*7ac9a364SKalle Valo * 617*7ac9a364SKalle Valo * channel_map_24/52 provides the idx in the channel_info array for a 618*7ac9a364SKalle Valo * given channel. We have to have two separate maps as there is channel 619*7ac9a364SKalle Valo * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and 620*7ac9a364SKalle Valo * band_2 621*7ac9a364SKalle Valo * 622*7ac9a364SKalle Valo * A value of 0xff stored in the channel_map indicates that the channel 623*7ac9a364SKalle Valo * is not supported by the hardware at all. 624*7ac9a364SKalle Valo * 625*7ac9a364SKalle Valo * A value of 0xfe in the channel_map indicates that the channel is not 626*7ac9a364SKalle Valo * valid for Tx with the current hardware. This means that 627*7ac9a364SKalle Valo * while the system can tune and receive on a given channel, it may not 628*7ac9a364SKalle Valo * be able to associate or transmit any frames on that 629*7ac9a364SKalle Valo * channel. There is no corresponding channel information for that 630*7ac9a364SKalle Valo * entry. 631*7ac9a364SKalle Valo * 632*7ac9a364SKalle Valo *********************************************************************/ 633*7ac9a364SKalle Valo 634*7ac9a364SKalle Valo /* 2.4 GHz */ 635*7ac9a364SKalle Valo const u8 il_eeprom_band_1[14] = { 636*7ac9a364SKalle Valo 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 637*7ac9a364SKalle Valo }; 638*7ac9a364SKalle Valo 639*7ac9a364SKalle Valo /* 5.2 GHz bands */ 640*7ac9a364SKalle Valo static const u8 il_eeprom_band_2[] = { /* 4915-5080MHz */ 641*7ac9a364SKalle Valo 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 642*7ac9a364SKalle Valo }; 643*7ac9a364SKalle Valo 644*7ac9a364SKalle Valo static const u8 il_eeprom_band_3[] = { /* 5170-5320MHz */ 645*7ac9a364SKalle Valo 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 646*7ac9a364SKalle Valo }; 647*7ac9a364SKalle Valo 648*7ac9a364SKalle Valo static const u8 il_eeprom_band_4[] = { /* 5500-5700MHz */ 649*7ac9a364SKalle Valo 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 650*7ac9a364SKalle Valo }; 651*7ac9a364SKalle Valo 652*7ac9a364SKalle Valo static const u8 il_eeprom_band_5[] = { /* 5725-5825MHz */ 653*7ac9a364SKalle Valo 145, 149, 153, 157, 161, 165 654*7ac9a364SKalle Valo }; 655*7ac9a364SKalle Valo 656*7ac9a364SKalle Valo static const u8 il_eeprom_band_6[] = { /* 2.4 ht40 channel */ 657*7ac9a364SKalle Valo 1, 2, 3, 4, 5, 6, 7 658*7ac9a364SKalle Valo }; 659*7ac9a364SKalle Valo 660*7ac9a364SKalle Valo static const u8 il_eeprom_band_7[] = { /* 5.2 ht40 channel */ 661*7ac9a364SKalle Valo 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 662*7ac9a364SKalle Valo }; 663*7ac9a364SKalle Valo 664*7ac9a364SKalle Valo /****************************************************************************** 665*7ac9a364SKalle Valo * 666*7ac9a364SKalle Valo * EEPROM related functions 667*7ac9a364SKalle Valo * 668*7ac9a364SKalle Valo ******************************************************************************/ 669*7ac9a364SKalle Valo 670*7ac9a364SKalle Valo static int 671*7ac9a364SKalle Valo il_eeprom_verify_signature(struct il_priv *il) 672*7ac9a364SKalle Valo { 673*7ac9a364SKalle Valo u32 gp = _il_rd(il, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; 674*7ac9a364SKalle Valo int ret = 0; 675*7ac9a364SKalle Valo 676*7ac9a364SKalle Valo D_EEPROM("EEPROM signature=0x%08x\n", gp); 677*7ac9a364SKalle Valo switch (gp) { 678*7ac9a364SKalle Valo case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: 679*7ac9a364SKalle Valo case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: 680*7ac9a364SKalle Valo break; 681*7ac9a364SKalle Valo default: 682*7ac9a364SKalle Valo IL_ERR("bad EEPROM signature," "EEPROM_GP=0x%08x\n", gp); 683*7ac9a364SKalle Valo ret = -ENOENT; 684*7ac9a364SKalle Valo break; 685*7ac9a364SKalle Valo } 686*7ac9a364SKalle Valo return ret; 687*7ac9a364SKalle Valo } 688*7ac9a364SKalle Valo 689*7ac9a364SKalle Valo const u8 * 690*7ac9a364SKalle Valo il_eeprom_query_addr(const struct il_priv *il, size_t offset) 691*7ac9a364SKalle Valo { 692*7ac9a364SKalle Valo BUG_ON(offset >= il->cfg->eeprom_size); 693*7ac9a364SKalle Valo return &il->eeprom[offset]; 694*7ac9a364SKalle Valo } 695*7ac9a364SKalle Valo EXPORT_SYMBOL(il_eeprom_query_addr); 696*7ac9a364SKalle Valo 697*7ac9a364SKalle Valo u16 698*7ac9a364SKalle Valo il_eeprom_query16(const struct il_priv *il, size_t offset) 699*7ac9a364SKalle Valo { 700*7ac9a364SKalle Valo if (!il->eeprom) 701*7ac9a364SKalle Valo return 0; 702*7ac9a364SKalle Valo return (u16) il->eeprom[offset] | ((u16) il->eeprom[offset + 1] << 8); 703*7ac9a364SKalle Valo } 704*7ac9a364SKalle Valo EXPORT_SYMBOL(il_eeprom_query16); 705*7ac9a364SKalle Valo 706*7ac9a364SKalle Valo /** 707*7ac9a364SKalle Valo * il_eeprom_init - read EEPROM contents 708*7ac9a364SKalle Valo * 709*7ac9a364SKalle Valo * Load the EEPROM contents from adapter into il->eeprom 710*7ac9a364SKalle Valo * 711*7ac9a364SKalle Valo * NOTE: This routine uses the non-debug IO access functions. 712*7ac9a364SKalle Valo */ 713*7ac9a364SKalle Valo int 714*7ac9a364SKalle Valo il_eeprom_init(struct il_priv *il) 715*7ac9a364SKalle Valo { 716*7ac9a364SKalle Valo __le16 *e; 717*7ac9a364SKalle Valo u32 gp = _il_rd(il, CSR_EEPROM_GP); 718*7ac9a364SKalle Valo int sz; 719*7ac9a364SKalle Valo int ret; 720*7ac9a364SKalle Valo u16 addr; 721*7ac9a364SKalle Valo 722*7ac9a364SKalle Valo /* allocate eeprom */ 723*7ac9a364SKalle Valo sz = il->cfg->eeprom_size; 724*7ac9a364SKalle Valo D_EEPROM("NVM size = %d\n", sz); 725*7ac9a364SKalle Valo il->eeprom = kzalloc(sz, GFP_KERNEL); 726*7ac9a364SKalle Valo if (!il->eeprom) { 727*7ac9a364SKalle Valo ret = -ENOMEM; 728*7ac9a364SKalle Valo goto alloc_err; 729*7ac9a364SKalle Valo } 730*7ac9a364SKalle Valo e = (__le16 *) il->eeprom; 731*7ac9a364SKalle Valo 732*7ac9a364SKalle Valo il->ops->apm_init(il); 733*7ac9a364SKalle Valo 734*7ac9a364SKalle Valo ret = il_eeprom_verify_signature(il); 735*7ac9a364SKalle Valo if (ret < 0) { 736*7ac9a364SKalle Valo IL_ERR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); 737*7ac9a364SKalle Valo ret = -ENOENT; 738*7ac9a364SKalle Valo goto err; 739*7ac9a364SKalle Valo } 740*7ac9a364SKalle Valo 741*7ac9a364SKalle Valo /* Make sure driver (instead of uCode) is allowed to read EEPROM */ 742*7ac9a364SKalle Valo ret = il->ops->eeprom_acquire_semaphore(il); 743*7ac9a364SKalle Valo if (ret < 0) { 744*7ac9a364SKalle Valo IL_ERR("Failed to acquire EEPROM semaphore.\n"); 745*7ac9a364SKalle Valo ret = -ENOENT; 746*7ac9a364SKalle Valo goto err; 747*7ac9a364SKalle Valo } 748*7ac9a364SKalle Valo 749*7ac9a364SKalle Valo /* eeprom is an array of 16bit values */ 750*7ac9a364SKalle Valo for (addr = 0; addr < sz; addr += sizeof(u16)) { 751*7ac9a364SKalle Valo u32 r; 752*7ac9a364SKalle Valo 753*7ac9a364SKalle Valo _il_wr(il, CSR_EEPROM_REG, 754*7ac9a364SKalle Valo CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 755*7ac9a364SKalle Valo 756*7ac9a364SKalle Valo ret = 757*7ac9a364SKalle Valo _il_poll_bit(il, CSR_EEPROM_REG, 758*7ac9a364SKalle Valo CSR_EEPROM_REG_READ_VALID_MSK, 759*7ac9a364SKalle Valo CSR_EEPROM_REG_READ_VALID_MSK, 760*7ac9a364SKalle Valo IL_EEPROM_ACCESS_TIMEOUT); 761*7ac9a364SKalle Valo if (ret < 0) { 762*7ac9a364SKalle Valo IL_ERR("Time out reading EEPROM[%d]\n", addr); 763*7ac9a364SKalle Valo goto done; 764*7ac9a364SKalle Valo } 765*7ac9a364SKalle Valo r = _il_rd(il, CSR_EEPROM_REG); 766*7ac9a364SKalle Valo e[addr / 2] = cpu_to_le16(r >> 16); 767*7ac9a364SKalle Valo } 768*7ac9a364SKalle Valo 769*7ac9a364SKalle Valo D_EEPROM("NVM Type: %s, version: 0x%x\n", "EEPROM", 770*7ac9a364SKalle Valo il_eeprom_query16(il, EEPROM_VERSION)); 771*7ac9a364SKalle Valo 772*7ac9a364SKalle Valo ret = 0; 773*7ac9a364SKalle Valo done: 774*7ac9a364SKalle Valo il->ops->eeprom_release_semaphore(il); 775*7ac9a364SKalle Valo 776*7ac9a364SKalle Valo err: 777*7ac9a364SKalle Valo if (ret) 778*7ac9a364SKalle Valo il_eeprom_free(il); 779*7ac9a364SKalle Valo /* Reset chip to save power until we load uCode during "up". */ 780*7ac9a364SKalle Valo il_apm_stop(il); 781*7ac9a364SKalle Valo alloc_err: 782*7ac9a364SKalle Valo return ret; 783*7ac9a364SKalle Valo } 784*7ac9a364SKalle Valo EXPORT_SYMBOL(il_eeprom_init); 785*7ac9a364SKalle Valo 786*7ac9a364SKalle Valo void 787*7ac9a364SKalle Valo il_eeprom_free(struct il_priv *il) 788*7ac9a364SKalle Valo { 789*7ac9a364SKalle Valo kfree(il->eeprom); 790*7ac9a364SKalle Valo il->eeprom = NULL; 791*7ac9a364SKalle Valo } 792*7ac9a364SKalle Valo EXPORT_SYMBOL(il_eeprom_free); 793*7ac9a364SKalle Valo 794*7ac9a364SKalle Valo static void 795*7ac9a364SKalle Valo il_init_band_reference(const struct il_priv *il, int eep_band, 796*7ac9a364SKalle Valo int *eeprom_ch_count, 797*7ac9a364SKalle Valo const struct il_eeprom_channel **eeprom_ch_info, 798*7ac9a364SKalle Valo const u8 **eeprom_ch_idx) 799*7ac9a364SKalle Valo { 800*7ac9a364SKalle Valo u32 offset = il->cfg->regulatory_bands[eep_band - 1]; 801*7ac9a364SKalle Valo 802*7ac9a364SKalle Valo switch (eep_band) { 803*7ac9a364SKalle Valo case 1: /* 2.4GHz band */ 804*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1); 805*7ac9a364SKalle Valo *eeprom_ch_info = 806*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 807*7ac9a364SKalle Valo offset); 808*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_1; 809*7ac9a364SKalle Valo break; 810*7ac9a364SKalle Valo case 2: /* 4.9GHz band */ 811*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_2); 812*7ac9a364SKalle Valo *eeprom_ch_info = 813*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 814*7ac9a364SKalle Valo offset); 815*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_2; 816*7ac9a364SKalle Valo break; 817*7ac9a364SKalle Valo case 3: /* 5.2GHz band */ 818*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_3); 819*7ac9a364SKalle Valo *eeprom_ch_info = 820*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 821*7ac9a364SKalle Valo offset); 822*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_3; 823*7ac9a364SKalle Valo break; 824*7ac9a364SKalle Valo case 4: /* 5.5GHz band */ 825*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_4); 826*7ac9a364SKalle Valo *eeprom_ch_info = 827*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 828*7ac9a364SKalle Valo offset); 829*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_4; 830*7ac9a364SKalle Valo break; 831*7ac9a364SKalle Valo case 5: /* 5.7GHz band */ 832*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_5); 833*7ac9a364SKalle Valo *eeprom_ch_info = 834*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 835*7ac9a364SKalle Valo offset); 836*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_5; 837*7ac9a364SKalle Valo break; 838*7ac9a364SKalle Valo case 6: /* 2.4GHz ht40 channels */ 839*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_6); 840*7ac9a364SKalle Valo *eeprom_ch_info = 841*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 842*7ac9a364SKalle Valo offset); 843*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_6; 844*7ac9a364SKalle Valo break; 845*7ac9a364SKalle Valo case 7: /* 5 GHz ht40 channels */ 846*7ac9a364SKalle Valo *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_7); 847*7ac9a364SKalle Valo *eeprom_ch_info = 848*7ac9a364SKalle Valo (struct il_eeprom_channel *)il_eeprom_query_addr(il, 849*7ac9a364SKalle Valo offset); 850*7ac9a364SKalle Valo *eeprom_ch_idx = il_eeprom_band_7; 851*7ac9a364SKalle Valo break; 852*7ac9a364SKalle Valo default: 853*7ac9a364SKalle Valo BUG(); 854*7ac9a364SKalle Valo } 855*7ac9a364SKalle Valo } 856*7ac9a364SKalle Valo 857*7ac9a364SKalle Valo #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ 858*7ac9a364SKalle Valo ? # x " " : "") 859*7ac9a364SKalle Valo /** 860*7ac9a364SKalle Valo * il_mod_ht40_chan_info - Copy ht40 channel info into driver's il. 861*7ac9a364SKalle Valo * 862*7ac9a364SKalle Valo * Does not set up a command, or touch hardware. 863*7ac9a364SKalle Valo */ 864*7ac9a364SKalle Valo static int 865*7ac9a364SKalle Valo il_mod_ht40_chan_info(struct il_priv *il, enum ieee80211_band band, u16 channel, 866*7ac9a364SKalle Valo const struct il_eeprom_channel *eeprom_ch, 867*7ac9a364SKalle Valo u8 clear_ht40_extension_channel) 868*7ac9a364SKalle Valo { 869*7ac9a364SKalle Valo struct il_channel_info *ch_info; 870*7ac9a364SKalle Valo 871*7ac9a364SKalle Valo ch_info = 872*7ac9a364SKalle Valo (struct il_channel_info *)il_get_channel_info(il, band, channel); 873*7ac9a364SKalle Valo 874*7ac9a364SKalle Valo if (!il_is_channel_valid(ch_info)) 875*7ac9a364SKalle Valo return -1; 876*7ac9a364SKalle Valo 877*7ac9a364SKalle Valo D_EEPROM("HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" 878*7ac9a364SKalle Valo " Ad-Hoc %ssupported\n", ch_info->channel, 879*7ac9a364SKalle Valo il_is_channel_a_band(ch_info) ? "5.2" : "2.4", 880*7ac9a364SKalle Valo CHECK_AND_PRINT(IBSS), CHECK_AND_PRINT(ACTIVE), 881*7ac9a364SKalle Valo CHECK_AND_PRINT(RADAR), CHECK_AND_PRINT(WIDE), 882*7ac9a364SKalle Valo CHECK_AND_PRINT(DFS), eeprom_ch->flags, 883*7ac9a364SKalle Valo eeprom_ch->max_power_avg, 884*7ac9a364SKalle Valo ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) && 885*7ac9a364SKalle Valo !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? "" : "not "); 886*7ac9a364SKalle Valo 887*7ac9a364SKalle Valo ch_info->ht40_eeprom = *eeprom_ch; 888*7ac9a364SKalle Valo ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; 889*7ac9a364SKalle Valo ch_info->ht40_flags = eeprom_ch->flags; 890*7ac9a364SKalle Valo if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) 891*7ac9a364SKalle Valo ch_info->ht40_extension_channel &= 892*7ac9a364SKalle Valo ~clear_ht40_extension_channel; 893*7ac9a364SKalle Valo 894*7ac9a364SKalle Valo return 0; 895*7ac9a364SKalle Valo } 896*7ac9a364SKalle Valo 897*7ac9a364SKalle Valo #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ 898*7ac9a364SKalle Valo ? # x " " : "") 899*7ac9a364SKalle Valo 900*7ac9a364SKalle Valo /** 901*7ac9a364SKalle Valo * il_init_channel_map - Set up driver's info for all possible channels 902*7ac9a364SKalle Valo */ 903*7ac9a364SKalle Valo int 904*7ac9a364SKalle Valo il_init_channel_map(struct il_priv *il) 905*7ac9a364SKalle Valo { 906*7ac9a364SKalle Valo int eeprom_ch_count = 0; 907*7ac9a364SKalle Valo const u8 *eeprom_ch_idx = NULL; 908*7ac9a364SKalle Valo const struct il_eeprom_channel *eeprom_ch_info = NULL; 909*7ac9a364SKalle Valo int band, ch; 910*7ac9a364SKalle Valo struct il_channel_info *ch_info; 911*7ac9a364SKalle Valo 912*7ac9a364SKalle Valo if (il->channel_count) { 913*7ac9a364SKalle Valo D_EEPROM("Channel map already initialized.\n"); 914*7ac9a364SKalle Valo return 0; 915*7ac9a364SKalle Valo } 916*7ac9a364SKalle Valo 917*7ac9a364SKalle Valo D_EEPROM("Initializing regulatory info from EEPROM\n"); 918*7ac9a364SKalle Valo 919*7ac9a364SKalle Valo il->channel_count = 920*7ac9a364SKalle Valo ARRAY_SIZE(il_eeprom_band_1) + ARRAY_SIZE(il_eeprom_band_2) + 921*7ac9a364SKalle Valo ARRAY_SIZE(il_eeprom_band_3) + ARRAY_SIZE(il_eeprom_band_4) + 922*7ac9a364SKalle Valo ARRAY_SIZE(il_eeprom_band_5); 923*7ac9a364SKalle Valo 924*7ac9a364SKalle Valo D_EEPROM("Parsing data for %d channels.\n", il->channel_count); 925*7ac9a364SKalle Valo 926*7ac9a364SKalle Valo il->channel_info = 927*7ac9a364SKalle Valo kzalloc(sizeof(struct il_channel_info) * il->channel_count, 928*7ac9a364SKalle Valo GFP_KERNEL); 929*7ac9a364SKalle Valo if (!il->channel_info) { 930*7ac9a364SKalle Valo IL_ERR("Could not allocate channel_info\n"); 931*7ac9a364SKalle Valo il->channel_count = 0; 932*7ac9a364SKalle Valo return -ENOMEM; 933*7ac9a364SKalle Valo } 934*7ac9a364SKalle Valo 935*7ac9a364SKalle Valo ch_info = il->channel_info; 936*7ac9a364SKalle Valo 937*7ac9a364SKalle Valo /* Loop through the 5 EEPROM bands adding them in order to the 938*7ac9a364SKalle Valo * channel map we maintain (that contains additional information than 939*7ac9a364SKalle Valo * what just in the EEPROM) */ 940*7ac9a364SKalle Valo for (band = 1; band <= 5; band++) { 941*7ac9a364SKalle Valo 942*7ac9a364SKalle Valo il_init_band_reference(il, band, &eeprom_ch_count, 943*7ac9a364SKalle Valo &eeprom_ch_info, &eeprom_ch_idx); 944*7ac9a364SKalle Valo 945*7ac9a364SKalle Valo /* Loop through each band adding each of the channels */ 946*7ac9a364SKalle Valo for (ch = 0; ch < eeprom_ch_count; ch++) { 947*7ac9a364SKalle Valo ch_info->channel = eeprom_ch_idx[ch]; 948*7ac9a364SKalle Valo ch_info->band = 949*7ac9a364SKalle Valo (band == 950*7ac9a364SKalle Valo 1) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 951*7ac9a364SKalle Valo 952*7ac9a364SKalle Valo /* permanently store EEPROM's channel regulatory flags 953*7ac9a364SKalle Valo * and max power in channel info database. */ 954*7ac9a364SKalle Valo ch_info->eeprom = eeprom_ch_info[ch]; 955*7ac9a364SKalle Valo 956*7ac9a364SKalle Valo /* Copy the run-time flags so they are there even on 957*7ac9a364SKalle Valo * invalid channels */ 958*7ac9a364SKalle Valo ch_info->flags = eeprom_ch_info[ch].flags; 959*7ac9a364SKalle Valo /* First write that ht40 is not enabled, and then enable 960*7ac9a364SKalle Valo * one by one */ 961*7ac9a364SKalle Valo ch_info->ht40_extension_channel = 962*7ac9a364SKalle Valo IEEE80211_CHAN_NO_HT40; 963*7ac9a364SKalle Valo 964*7ac9a364SKalle Valo if (!(il_is_channel_valid(ch_info))) { 965*7ac9a364SKalle Valo D_EEPROM("Ch. %d Flags %x [%sGHz] - " 966*7ac9a364SKalle Valo "No traffic\n", ch_info->channel, 967*7ac9a364SKalle Valo ch_info->flags, 968*7ac9a364SKalle Valo il_is_channel_a_band(ch_info) ? "5.2" : 969*7ac9a364SKalle Valo "2.4"); 970*7ac9a364SKalle Valo ch_info++; 971*7ac9a364SKalle Valo continue; 972*7ac9a364SKalle Valo } 973*7ac9a364SKalle Valo 974*7ac9a364SKalle Valo /* Initialize regulatory-based run-time data */ 975*7ac9a364SKalle Valo ch_info->max_power_avg = ch_info->curr_txpow = 976*7ac9a364SKalle Valo eeprom_ch_info[ch].max_power_avg; 977*7ac9a364SKalle Valo ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 978*7ac9a364SKalle Valo ch_info->min_power = 0; 979*7ac9a364SKalle Valo 980*7ac9a364SKalle Valo D_EEPROM("Ch. %d [%sGHz] " "%s%s%s%s%s%s(0x%02x %ddBm):" 981*7ac9a364SKalle Valo " Ad-Hoc %ssupported\n", ch_info->channel, 982*7ac9a364SKalle Valo il_is_channel_a_band(ch_info) ? "5.2" : "2.4", 983*7ac9a364SKalle Valo CHECK_AND_PRINT_I(VALID), 984*7ac9a364SKalle Valo CHECK_AND_PRINT_I(IBSS), 985*7ac9a364SKalle Valo CHECK_AND_PRINT_I(ACTIVE), 986*7ac9a364SKalle Valo CHECK_AND_PRINT_I(RADAR), 987*7ac9a364SKalle Valo CHECK_AND_PRINT_I(WIDE), 988*7ac9a364SKalle Valo CHECK_AND_PRINT_I(DFS), 989*7ac9a364SKalle Valo eeprom_ch_info[ch].flags, 990*7ac9a364SKalle Valo eeprom_ch_info[ch].max_power_avg, 991*7ac9a364SKalle Valo ((eeprom_ch_info[ch]. 992*7ac9a364SKalle Valo flags & EEPROM_CHANNEL_IBSS) && 993*7ac9a364SKalle Valo !(eeprom_ch_info[ch]. 994*7ac9a364SKalle Valo flags & EEPROM_CHANNEL_RADAR)) ? "" : 995*7ac9a364SKalle Valo "not "); 996*7ac9a364SKalle Valo 997*7ac9a364SKalle Valo ch_info++; 998*7ac9a364SKalle Valo } 999*7ac9a364SKalle Valo } 1000*7ac9a364SKalle Valo 1001*7ac9a364SKalle Valo /* Check if we do have HT40 channels */ 1002*7ac9a364SKalle Valo if (il->cfg->regulatory_bands[5] == EEPROM_REGULATORY_BAND_NO_HT40 && 1003*7ac9a364SKalle Valo il->cfg->regulatory_bands[6] == EEPROM_REGULATORY_BAND_NO_HT40) 1004*7ac9a364SKalle Valo return 0; 1005*7ac9a364SKalle Valo 1006*7ac9a364SKalle Valo /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ 1007*7ac9a364SKalle Valo for (band = 6; band <= 7; band++) { 1008*7ac9a364SKalle Valo enum ieee80211_band ieeeband; 1009*7ac9a364SKalle Valo 1010*7ac9a364SKalle Valo il_init_band_reference(il, band, &eeprom_ch_count, 1011*7ac9a364SKalle Valo &eeprom_ch_info, &eeprom_ch_idx); 1012*7ac9a364SKalle Valo 1013*7ac9a364SKalle Valo /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ 1014*7ac9a364SKalle Valo ieeeband = 1015*7ac9a364SKalle Valo (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 1016*7ac9a364SKalle Valo 1017*7ac9a364SKalle Valo /* Loop through each band adding each of the channels */ 1018*7ac9a364SKalle Valo for (ch = 0; ch < eeprom_ch_count; ch++) { 1019*7ac9a364SKalle Valo /* Set up driver's info for lower half */ 1020*7ac9a364SKalle Valo il_mod_ht40_chan_info(il, ieeeband, eeprom_ch_idx[ch], 1021*7ac9a364SKalle Valo &eeprom_ch_info[ch], 1022*7ac9a364SKalle Valo IEEE80211_CHAN_NO_HT40PLUS); 1023*7ac9a364SKalle Valo 1024*7ac9a364SKalle Valo /* Set up driver's info for upper half */ 1025*7ac9a364SKalle Valo il_mod_ht40_chan_info(il, ieeeband, 1026*7ac9a364SKalle Valo eeprom_ch_idx[ch] + 4, 1027*7ac9a364SKalle Valo &eeprom_ch_info[ch], 1028*7ac9a364SKalle Valo IEEE80211_CHAN_NO_HT40MINUS); 1029*7ac9a364SKalle Valo } 1030*7ac9a364SKalle Valo } 1031*7ac9a364SKalle Valo 1032*7ac9a364SKalle Valo return 0; 1033*7ac9a364SKalle Valo } 1034*7ac9a364SKalle Valo EXPORT_SYMBOL(il_init_channel_map); 1035*7ac9a364SKalle Valo 1036*7ac9a364SKalle Valo /* 1037*7ac9a364SKalle Valo * il_free_channel_map - undo allocations in il_init_channel_map 1038*7ac9a364SKalle Valo */ 1039*7ac9a364SKalle Valo void 1040*7ac9a364SKalle Valo il_free_channel_map(struct il_priv *il) 1041*7ac9a364SKalle Valo { 1042*7ac9a364SKalle Valo kfree(il->channel_info); 1043*7ac9a364SKalle Valo il->channel_count = 0; 1044*7ac9a364SKalle Valo } 1045*7ac9a364SKalle Valo EXPORT_SYMBOL(il_free_channel_map); 1046*7ac9a364SKalle Valo 1047*7ac9a364SKalle Valo /** 1048*7ac9a364SKalle Valo * il_get_channel_info - Find driver's ilate channel info 1049*7ac9a364SKalle Valo * 1050*7ac9a364SKalle Valo * Based on band and channel number. 1051*7ac9a364SKalle Valo */ 1052*7ac9a364SKalle Valo const struct il_channel_info * 1053*7ac9a364SKalle Valo il_get_channel_info(const struct il_priv *il, enum ieee80211_band band, 1054*7ac9a364SKalle Valo u16 channel) 1055*7ac9a364SKalle Valo { 1056*7ac9a364SKalle Valo int i; 1057*7ac9a364SKalle Valo 1058*7ac9a364SKalle Valo switch (band) { 1059*7ac9a364SKalle Valo case IEEE80211_BAND_5GHZ: 1060*7ac9a364SKalle Valo for (i = 14; i < il->channel_count; i++) { 1061*7ac9a364SKalle Valo if (il->channel_info[i].channel == channel) 1062*7ac9a364SKalle Valo return &il->channel_info[i]; 1063*7ac9a364SKalle Valo } 1064*7ac9a364SKalle Valo break; 1065*7ac9a364SKalle Valo case IEEE80211_BAND_2GHZ: 1066*7ac9a364SKalle Valo if (channel >= 1 && channel <= 14) 1067*7ac9a364SKalle Valo return &il->channel_info[channel - 1]; 1068*7ac9a364SKalle Valo break; 1069*7ac9a364SKalle Valo default: 1070*7ac9a364SKalle Valo BUG(); 1071*7ac9a364SKalle Valo } 1072*7ac9a364SKalle Valo 1073*7ac9a364SKalle Valo return NULL; 1074*7ac9a364SKalle Valo } 1075*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_channel_info); 1076*7ac9a364SKalle Valo 1077*7ac9a364SKalle Valo /* 1078*7ac9a364SKalle Valo * Setting power level allows the card to go to sleep when not busy. 1079*7ac9a364SKalle Valo * 1080*7ac9a364SKalle Valo * We calculate a sleep command based on the required latency, which 1081*7ac9a364SKalle Valo * we get from mac80211. 1082*7ac9a364SKalle Valo */ 1083*7ac9a364SKalle Valo 1084*7ac9a364SKalle Valo #define SLP_VEC(X0, X1, X2, X3, X4) { \ 1085*7ac9a364SKalle Valo cpu_to_le32(X0), \ 1086*7ac9a364SKalle Valo cpu_to_le32(X1), \ 1087*7ac9a364SKalle Valo cpu_to_le32(X2), \ 1088*7ac9a364SKalle Valo cpu_to_le32(X3), \ 1089*7ac9a364SKalle Valo cpu_to_le32(X4) \ 1090*7ac9a364SKalle Valo } 1091*7ac9a364SKalle Valo 1092*7ac9a364SKalle Valo static void 1093*7ac9a364SKalle Valo il_build_powertable_cmd(struct il_priv *il, struct il_powertable_cmd *cmd) 1094*7ac9a364SKalle Valo { 1095*7ac9a364SKalle Valo const __le32 interval[3][IL_POWER_VEC_SIZE] = { 1096*7ac9a364SKalle Valo SLP_VEC(2, 2, 4, 6, 0xFF), 1097*7ac9a364SKalle Valo SLP_VEC(2, 4, 7, 10, 10), 1098*7ac9a364SKalle Valo SLP_VEC(4, 7, 10, 10, 0xFF) 1099*7ac9a364SKalle Valo }; 1100*7ac9a364SKalle Valo int i, dtim_period, no_dtim; 1101*7ac9a364SKalle Valo u32 max_sleep; 1102*7ac9a364SKalle Valo bool skip; 1103*7ac9a364SKalle Valo 1104*7ac9a364SKalle Valo memset(cmd, 0, sizeof(*cmd)); 1105*7ac9a364SKalle Valo 1106*7ac9a364SKalle Valo if (il->power_data.pci_pm) 1107*7ac9a364SKalle Valo cmd->flags |= IL_POWER_PCI_PM_MSK; 1108*7ac9a364SKalle Valo 1109*7ac9a364SKalle Valo /* if no Power Save, we are done */ 1110*7ac9a364SKalle Valo if (il->power_data.ps_disabled) 1111*7ac9a364SKalle Valo return; 1112*7ac9a364SKalle Valo 1113*7ac9a364SKalle Valo cmd->flags = IL_POWER_DRIVER_ALLOW_SLEEP_MSK; 1114*7ac9a364SKalle Valo cmd->keep_alive_seconds = 0; 1115*7ac9a364SKalle Valo cmd->debug_flags = 0; 1116*7ac9a364SKalle Valo cmd->rx_data_timeout = cpu_to_le32(25 * 1024); 1117*7ac9a364SKalle Valo cmd->tx_data_timeout = cpu_to_le32(25 * 1024); 1118*7ac9a364SKalle Valo cmd->keep_alive_beacons = 0; 1119*7ac9a364SKalle Valo 1120*7ac9a364SKalle Valo dtim_period = il->vif ? il->vif->bss_conf.dtim_period : 0; 1121*7ac9a364SKalle Valo 1122*7ac9a364SKalle Valo if (dtim_period <= 2) { 1123*7ac9a364SKalle Valo memcpy(cmd->sleep_interval, interval[0], sizeof(interval[0])); 1124*7ac9a364SKalle Valo no_dtim = 2; 1125*7ac9a364SKalle Valo } else if (dtim_period <= 10) { 1126*7ac9a364SKalle Valo memcpy(cmd->sleep_interval, interval[1], sizeof(interval[1])); 1127*7ac9a364SKalle Valo no_dtim = 2; 1128*7ac9a364SKalle Valo } else { 1129*7ac9a364SKalle Valo memcpy(cmd->sleep_interval, interval[2], sizeof(interval[2])); 1130*7ac9a364SKalle Valo no_dtim = 0; 1131*7ac9a364SKalle Valo } 1132*7ac9a364SKalle Valo 1133*7ac9a364SKalle Valo if (dtim_period == 0) { 1134*7ac9a364SKalle Valo dtim_period = 1; 1135*7ac9a364SKalle Valo skip = false; 1136*7ac9a364SKalle Valo } else { 1137*7ac9a364SKalle Valo skip = !!no_dtim; 1138*7ac9a364SKalle Valo } 1139*7ac9a364SKalle Valo 1140*7ac9a364SKalle Valo if (skip) { 1141*7ac9a364SKalle Valo __le32 tmp = cmd->sleep_interval[IL_POWER_VEC_SIZE - 1]; 1142*7ac9a364SKalle Valo 1143*7ac9a364SKalle Valo max_sleep = le32_to_cpu(tmp); 1144*7ac9a364SKalle Valo if (max_sleep == 0xFF) 1145*7ac9a364SKalle Valo max_sleep = dtim_period * (skip + 1); 1146*7ac9a364SKalle Valo else if (max_sleep > dtim_period) 1147*7ac9a364SKalle Valo max_sleep = (max_sleep / dtim_period) * dtim_period; 1148*7ac9a364SKalle Valo cmd->flags |= IL_POWER_SLEEP_OVER_DTIM_MSK; 1149*7ac9a364SKalle Valo } else { 1150*7ac9a364SKalle Valo max_sleep = dtim_period; 1151*7ac9a364SKalle Valo cmd->flags &= ~IL_POWER_SLEEP_OVER_DTIM_MSK; 1152*7ac9a364SKalle Valo } 1153*7ac9a364SKalle Valo 1154*7ac9a364SKalle Valo for (i = 0; i < IL_POWER_VEC_SIZE; i++) 1155*7ac9a364SKalle Valo if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) 1156*7ac9a364SKalle Valo cmd->sleep_interval[i] = cpu_to_le32(max_sleep); 1157*7ac9a364SKalle Valo } 1158*7ac9a364SKalle Valo 1159*7ac9a364SKalle Valo static int 1160*7ac9a364SKalle Valo il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd) 1161*7ac9a364SKalle Valo { 1162*7ac9a364SKalle Valo D_POWER("Sending power/sleep command\n"); 1163*7ac9a364SKalle Valo D_POWER("Flags value = 0x%08X\n", cmd->flags); 1164*7ac9a364SKalle Valo D_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); 1165*7ac9a364SKalle Valo D_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout)); 1166*7ac9a364SKalle Valo D_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n", 1167*7ac9a364SKalle Valo le32_to_cpu(cmd->sleep_interval[0]), 1168*7ac9a364SKalle Valo le32_to_cpu(cmd->sleep_interval[1]), 1169*7ac9a364SKalle Valo le32_to_cpu(cmd->sleep_interval[2]), 1170*7ac9a364SKalle Valo le32_to_cpu(cmd->sleep_interval[3]), 1171*7ac9a364SKalle Valo le32_to_cpu(cmd->sleep_interval[4])); 1172*7ac9a364SKalle Valo 1173*7ac9a364SKalle Valo return il_send_cmd_pdu(il, C_POWER_TBL, 1174*7ac9a364SKalle Valo sizeof(struct il_powertable_cmd), cmd); 1175*7ac9a364SKalle Valo } 1176*7ac9a364SKalle Valo 1177*7ac9a364SKalle Valo static int 1178*7ac9a364SKalle Valo il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force) 1179*7ac9a364SKalle Valo { 1180*7ac9a364SKalle Valo int ret; 1181*7ac9a364SKalle Valo bool update_chains; 1182*7ac9a364SKalle Valo 1183*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 1184*7ac9a364SKalle Valo 1185*7ac9a364SKalle Valo /* Don't update the RX chain when chain noise calibration is running */ 1186*7ac9a364SKalle Valo update_chains = il->chain_noise_data.state == IL_CHAIN_NOISE_DONE || 1187*7ac9a364SKalle Valo il->chain_noise_data.state == IL_CHAIN_NOISE_ALIVE; 1188*7ac9a364SKalle Valo 1189*7ac9a364SKalle Valo if (!memcmp(&il->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) 1190*7ac9a364SKalle Valo return 0; 1191*7ac9a364SKalle Valo 1192*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) 1193*7ac9a364SKalle Valo return -EIO; 1194*7ac9a364SKalle Valo 1195*7ac9a364SKalle Valo /* scan complete use sleep_power_next, need to be updated */ 1196*7ac9a364SKalle Valo memcpy(&il->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); 1197*7ac9a364SKalle Valo if (test_bit(S_SCANNING, &il->status) && !force) { 1198*7ac9a364SKalle Valo D_INFO("Defer power set mode while scanning\n"); 1199*7ac9a364SKalle Valo return 0; 1200*7ac9a364SKalle Valo } 1201*7ac9a364SKalle Valo 1202*7ac9a364SKalle Valo if (cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK) 1203*7ac9a364SKalle Valo set_bit(S_POWER_PMI, &il->status); 1204*7ac9a364SKalle Valo 1205*7ac9a364SKalle Valo ret = il_set_power(il, cmd); 1206*7ac9a364SKalle Valo if (!ret) { 1207*7ac9a364SKalle Valo if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK)) 1208*7ac9a364SKalle Valo clear_bit(S_POWER_PMI, &il->status); 1209*7ac9a364SKalle Valo 1210*7ac9a364SKalle Valo if (il->ops->update_chain_flags && update_chains) 1211*7ac9a364SKalle Valo il->ops->update_chain_flags(il); 1212*7ac9a364SKalle Valo else if (il->ops->update_chain_flags) 1213*7ac9a364SKalle Valo D_POWER("Cannot update the power, chain noise " 1214*7ac9a364SKalle Valo "calibration running: %d\n", 1215*7ac9a364SKalle Valo il->chain_noise_data.state); 1216*7ac9a364SKalle Valo 1217*7ac9a364SKalle Valo memcpy(&il->power_data.sleep_cmd, cmd, sizeof(*cmd)); 1218*7ac9a364SKalle Valo } else 1219*7ac9a364SKalle Valo IL_ERR("set power fail, ret = %d", ret); 1220*7ac9a364SKalle Valo 1221*7ac9a364SKalle Valo return ret; 1222*7ac9a364SKalle Valo } 1223*7ac9a364SKalle Valo 1224*7ac9a364SKalle Valo int 1225*7ac9a364SKalle Valo il_power_update_mode(struct il_priv *il, bool force) 1226*7ac9a364SKalle Valo { 1227*7ac9a364SKalle Valo struct il_powertable_cmd cmd; 1228*7ac9a364SKalle Valo 1229*7ac9a364SKalle Valo il_build_powertable_cmd(il, &cmd); 1230*7ac9a364SKalle Valo 1231*7ac9a364SKalle Valo return il_power_set_mode(il, &cmd, force); 1232*7ac9a364SKalle Valo } 1233*7ac9a364SKalle Valo EXPORT_SYMBOL(il_power_update_mode); 1234*7ac9a364SKalle Valo 1235*7ac9a364SKalle Valo /* initialize to default */ 1236*7ac9a364SKalle Valo void 1237*7ac9a364SKalle Valo il_power_initialize(struct il_priv *il) 1238*7ac9a364SKalle Valo { 1239*7ac9a364SKalle Valo u16 lctl; 1240*7ac9a364SKalle Valo 1241*7ac9a364SKalle Valo pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); 1242*7ac9a364SKalle Valo il->power_data.pci_pm = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S); 1243*7ac9a364SKalle Valo 1244*7ac9a364SKalle Valo il->power_data.debug_sleep_level_override = -1; 1245*7ac9a364SKalle Valo 1246*7ac9a364SKalle Valo memset(&il->power_data.sleep_cmd, 0, sizeof(il->power_data.sleep_cmd)); 1247*7ac9a364SKalle Valo } 1248*7ac9a364SKalle Valo EXPORT_SYMBOL(il_power_initialize); 1249*7ac9a364SKalle Valo 1250*7ac9a364SKalle Valo /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 1251*7ac9a364SKalle Valo * sending probe req. This should be set long enough to hear probe responses 1252*7ac9a364SKalle Valo * from more than one AP. */ 1253*7ac9a364SKalle Valo #define IL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */ 1254*7ac9a364SKalle Valo #define IL_ACTIVE_DWELL_TIME_52 (20) 1255*7ac9a364SKalle Valo 1256*7ac9a364SKalle Valo #define IL_ACTIVE_DWELL_FACTOR_24GHZ (3) 1257*7ac9a364SKalle Valo #define IL_ACTIVE_DWELL_FACTOR_52GHZ (2) 1258*7ac9a364SKalle Valo 1259*7ac9a364SKalle Valo /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. 1260*7ac9a364SKalle Valo * Must be set longer than active dwell time. 1261*7ac9a364SKalle Valo * For the most reliable scan, set > AP beacon interval (typically 100msec). */ 1262*7ac9a364SKalle Valo #define IL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ 1263*7ac9a364SKalle Valo #define IL_PASSIVE_DWELL_TIME_52 (10) 1264*7ac9a364SKalle Valo #define IL_PASSIVE_DWELL_BASE (100) 1265*7ac9a364SKalle Valo #define IL_CHANNEL_TUNE_TIME 5 1266*7ac9a364SKalle Valo 1267*7ac9a364SKalle Valo static int 1268*7ac9a364SKalle Valo il_send_scan_abort(struct il_priv *il) 1269*7ac9a364SKalle Valo { 1270*7ac9a364SKalle Valo int ret; 1271*7ac9a364SKalle Valo struct il_rx_pkt *pkt; 1272*7ac9a364SKalle Valo struct il_host_cmd cmd = { 1273*7ac9a364SKalle Valo .id = C_SCAN_ABORT, 1274*7ac9a364SKalle Valo .flags = CMD_WANT_SKB, 1275*7ac9a364SKalle Valo }; 1276*7ac9a364SKalle Valo 1277*7ac9a364SKalle Valo /* Exit instantly with error when device is not ready 1278*7ac9a364SKalle Valo * to receive scan abort command or it does not perform 1279*7ac9a364SKalle Valo * hardware scan currently */ 1280*7ac9a364SKalle Valo if (!test_bit(S_READY, &il->status) || 1281*7ac9a364SKalle Valo !test_bit(S_GEO_CONFIGURED, &il->status) || 1282*7ac9a364SKalle Valo !test_bit(S_SCAN_HW, &il->status) || 1283*7ac9a364SKalle Valo test_bit(S_FW_ERROR, &il->status) || 1284*7ac9a364SKalle Valo test_bit(S_EXIT_PENDING, &il->status)) 1285*7ac9a364SKalle Valo return -EIO; 1286*7ac9a364SKalle Valo 1287*7ac9a364SKalle Valo ret = il_send_cmd_sync(il, &cmd); 1288*7ac9a364SKalle Valo if (ret) 1289*7ac9a364SKalle Valo return ret; 1290*7ac9a364SKalle Valo 1291*7ac9a364SKalle Valo pkt = (struct il_rx_pkt *)cmd.reply_page; 1292*7ac9a364SKalle Valo if (pkt->u.status != CAN_ABORT_STATUS) { 1293*7ac9a364SKalle Valo /* The scan abort will return 1 for success or 1294*7ac9a364SKalle Valo * 2 for "failure". A failure condition can be 1295*7ac9a364SKalle Valo * due to simply not being in an active scan which 1296*7ac9a364SKalle Valo * can occur if we send the scan abort before we 1297*7ac9a364SKalle Valo * the microcode has notified us that a scan is 1298*7ac9a364SKalle Valo * completed. */ 1299*7ac9a364SKalle Valo D_SCAN("SCAN_ABORT ret %d.\n", pkt->u.status); 1300*7ac9a364SKalle Valo ret = -EIO; 1301*7ac9a364SKalle Valo } 1302*7ac9a364SKalle Valo 1303*7ac9a364SKalle Valo il_free_pages(il, cmd.reply_page); 1304*7ac9a364SKalle Valo return ret; 1305*7ac9a364SKalle Valo } 1306*7ac9a364SKalle Valo 1307*7ac9a364SKalle Valo static void 1308*7ac9a364SKalle Valo il_complete_scan(struct il_priv *il, bool aborted) 1309*7ac9a364SKalle Valo { 1310*7ac9a364SKalle Valo /* check if scan was requested from mac80211 */ 1311*7ac9a364SKalle Valo if (il->scan_request) { 1312*7ac9a364SKalle Valo D_SCAN("Complete scan in mac80211\n"); 1313*7ac9a364SKalle Valo ieee80211_scan_completed(il->hw, aborted); 1314*7ac9a364SKalle Valo } 1315*7ac9a364SKalle Valo 1316*7ac9a364SKalle Valo il->scan_vif = NULL; 1317*7ac9a364SKalle Valo il->scan_request = NULL; 1318*7ac9a364SKalle Valo } 1319*7ac9a364SKalle Valo 1320*7ac9a364SKalle Valo void 1321*7ac9a364SKalle Valo il_force_scan_end(struct il_priv *il) 1322*7ac9a364SKalle Valo { 1323*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 1324*7ac9a364SKalle Valo 1325*7ac9a364SKalle Valo if (!test_bit(S_SCANNING, &il->status)) { 1326*7ac9a364SKalle Valo D_SCAN("Forcing scan end while not scanning\n"); 1327*7ac9a364SKalle Valo return; 1328*7ac9a364SKalle Valo } 1329*7ac9a364SKalle Valo 1330*7ac9a364SKalle Valo D_SCAN("Forcing scan end\n"); 1331*7ac9a364SKalle Valo clear_bit(S_SCANNING, &il->status); 1332*7ac9a364SKalle Valo clear_bit(S_SCAN_HW, &il->status); 1333*7ac9a364SKalle Valo clear_bit(S_SCAN_ABORTING, &il->status); 1334*7ac9a364SKalle Valo il_complete_scan(il, true); 1335*7ac9a364SKalle Valo } 1336*7ac9a364SKalle Valo 1337*7ac9a364SKalle Valo static void 1338*7ac9a364SKalle Valo il_do_scan_abort(struct il_priv *il) 1339*7ac9a364SKalle Valo { 1340*7ac9a364SKalle Valo int ret; 1341*7ac9a364SKalle Valo 1342*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 1343*7ac9a364SKalle Valo 1344*7ac9a364SKalle Valo if (!test_bit(S_SCANNING, &il->status)) { 1345*7ac9a364SKalle Valo D_SCAN("Not performing scan to abort\n"); 1346*7ac9a364SKalle Valo return; 1347*7ac9a364SKalle Valo } 1348*7ac9a364SKalle Valo 1349*7ac9a364SKalle Valo if (test_and_set_bit(S_SCAN_ABORTING, &il->status)) { 1350*7ac9a364SKalle Valo D_SCAN("Scan abort in progress\n"); 1351*7ac9a364SKalle Valo return; 1352*7ac9a364SKalle Valo } 1353*7ac9a364SKalle Valo 1354*7ac9a364SKalle Valo ret = il_send_scan_abort(il); 1355*7ac9a364SKalle Valo if (ret) { 1356*7ac9a364SKalle Valo D_SCAN("Send scan abort failed %d\n", ret); 1357*7ac9a364SKalle Valo il_force_scan_end(il); 1358*7ac9a364SKalle Valo } else 1359*7ac9a364SKalle Valo D_SCAN("Successfully send scan abort\n"); 1360*7ac9a364SKalle Valo } 1361*7ac9a364SKalle Valo 1362*7ac9a364SKalle Valo /** 1363*7ac9a364SKalle Valo * il_scan_cancel - Cancel any currently executing HW scan 1364*7ac9a364SKalle Valo */ 1365*7ac9a364SKalle Valo int 1366*7ac9a364SKalle Valo il_scan_cancel(struct il_priv *il) 1367*7ac9a364SKalle Valo { 1368*7ac9a364SKalle Valo D_SCAN("Queuing abort scan\n"); 1369*7ac9a364SKalle Valo queue_work(il->workqueue, &il->abort_scan); 1370*7ac9a364SKalle Valo return 0; 1371*7ac9a364SKalle Valo } 1372*7ac9a364SKalle Valo EXPORT_SYMBOL(il_scan_cancel); 1373*7ac9a364SKalle Valo 1374*7ac9a364SKalle Valo /** 1375*7ac9a364SKalle Valo * il_scan_cancel_timeout - Cancel any currently executing HW scan 1376*7ac9a364SKalle Valo * @ms: amount of time to wait (in milliseconds) for scan to abort 1377*7ac9a364SKalle Valo * 1378*7ac9a364SKalle Valo */ 1379*7ac9a364SKalle Valo int 1380*7ac9a364SKalle Valo il_scan_cancel_timeout(struct il_priv *il, unsigned long ms) 1381*7ac9a364SKalle Valo { 1382*7ac9a364SKalle Valo unsigned long timeout = jiffies + msecs_to_jiffies(ms); 1383*7ac9a364SKalle Valo 1384*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 1385*7ac9a364SKalle Valo 1386*7ac9a364SKalle Valo D_SCAN("Scan cancel timeout\n"); 1387*7ac9a364SKalle Valo 1388*7ac9a364SKalle Valo il_do_scan_abort(il); 1389*7ac9a364SKalle Valo 1390*7ac9a364SKalle Valo while (time_before_eq(jiffies, timeout)) { 1391*7ac9a364SKalle Valo if (!test_bit(S_SCAN_HW, &il->status)) 1392*7ac9a364SKalle Valo break; 1393*7ac9a364SKalle Valo msleep(20); 1394*7ac9a364SKalle Valo } 1395*7ac9a364SKalle Valo 1396*7ac9a364SKalle Valo return test_bit(S_SCAN_HW, &il->status); 1397*7ac9a364SKalle Valo } 1398*7ac9a364SKalle Valo EXPORT_SYMBOL(il_scan_cancel_timeout); 1399*7ac9a364SKalle Valo 1400*7ac9a364SKalle Valo /* Service response to C_SCAN (0x80) */ 1401*7ac9a364SKalle Valo static void 1402*7ac9a364SKalle Valo il_hdl_scan(struct il_priv *il, struct il_rx_buf *rxb) 1403*7ac9a364SKalle Valo { 1404*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 1405*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 1406*7ac9a364SKalle Valo struct il_scanreq_notification *notif = 1407*7ac9a364SKalle Valo (struct il_scanreq_notification *)pkt->u.raw; 1408*7ac9a364SKalle Valo 1409*7ac9a364SKalle Valo D_SCAN("Scan request status = 0x%x\n", notif->status); 1410*7ac9a364SKalle Valo #endif 1411*7ac9a364SKalle Valo } 1412*7ac9a364SKalle Valo 1413*7ac9a364SKalle Valo /* Service N_SCAN_START (0x82) */ 1414*7ac9a364SKalle Valo static void 1415*7ac9a364SKalle Valo il_hdl_scan_start(struct il_priv *il, struct il_rx_buf *rxb) 1416*7ac9a364SKalle Valo { 1417*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 1418*7ac9a364SKalle Valo struct il_scanstart_notification *notif = 1419*7ac9a364SKalle Valo (struct il_scanstart_notification *)pkt->u.raw; 1420*7ac9a364SKalle Valo il->scan_start_tsf = le32_to_cpu(notif->tsf_low); 1421*7ac9a364SKalle Valo D_SCAN("Scan start: " "%d [802.11%s] " 1422*7ac9a364SKalle Valo "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", notif->channel, 1423*7ac9a364SKalle Valo notif->band ? "bg" : "a", le32_to_cpu(notif->tsf_high), 1424*7ac9a364SKalle Valo le32_to_cpu(notif->tsf_low), notif->status, notif->beacon_timer); 1425*7ac9a364SKalle Valo } 1426*7ac9a364SKalle Valo 1427*7ac9a364SKalle Valo /* Service N_SCAN_RESULTS (0x83) */ 1428*7ac9a364SKalle Valo static void 1429*7ac9a364SKalle Valo il_hdl_scan_results(struct il_priv *il, struct il_rx_buf *rxb) 1430*7ac9a364SKalle Valo { 1431*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 1432*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 1433*7ac9a364SKalle Valo struct il_scanresults_notification *notif = 1434*7ac9a364SKalle Valo (struct il_scanresults_notification *)pkt->u.raw; 1435*7ac9a364SKalle Valo 1436*7ac9a364SKalle Valo D_SCAN("Scan ch.res: " "%d [802.11%s] " "(TSF: 0x%08X:%08X) - %d " 1437*7ac9a364SKalle Valo "elapsed=%lu usec\n", notif->channel, notif->band ? "bg" : "a", 1438*7ac9a364SKalle Valo le32_to_cpu(notif->tsf_high), le32_to_cpu(notif->tsf_low), 1439*7ac9a364SKalle Valo le32_to_cpu(notif->stats[0]), 1440*7ac9a364SKalle Valo le32_to_cpu(notif->tsf_low) - il->scan_start_tsf); 1441*7ac9a364SKalle Valo #endif 1442*7ac9a364SKalle Valo } 1443*7ac9a364SKalle Valo 1444*7ac9a364SKalle Valo /* Service N_SCAN_COMPLETE (0x84) */ 1445*7ac9a364SKalle Valo static void 1446*7ac9a364SKalle Valo il_hdl_scan_complete(struct il_priv *il, struct il_rx_buf *rxb) 1447*7ac9a364SKalle Valo { 1448*7ac9a364SKalle Valo 1449*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 1450*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 1451*7ac9a364SKalle Valo struct il_scancomplete_notification *scan_notif = (void *)pkt->u.raw; 1452*7ac9a364SKalle Valo #endif 1453*7ac9a364SKalle Valo 1454*7ac9a364SKalle Valo D_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", 1455*7ac9a364SKalle Valo scan_notif->scanned_channels, scan_notif->tsf_low, 1456*7ac9a364SKalle Valo scan_notif->tsf_high, scan_notif->status); 1457*7ac9a364SKalle Valo 1458*7ac9a364SKalle Valo /* The HW is no longer scanning */ 1459*7ac9a364SKalle Valo clear_bit(S_SCAN_HW, &il->status); 1460*7ac9a364SKalle Valo 1461*7ac9a364SKalle Valo D_SCAN("Scan on %sGHz took %dms\n", 1462*7ac9a364SKalle Valo (il->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2", 1463*7ac9a364SKalle Valo jiffies_to_msecs(jiffies - il->scan_start)); 1464*7ac9a364SKalle Valo 1465*7ac9a364SKalle Valo queue_work(il->workqueue, &il->scan_completed); 1466*7ac9a364SKalle Valo } 1467*7ac9a364SKalle Valo 1468*7ac9a364SKalle Valo void 1469*7ac9a364SKalle Valo il_setup_rx_scan_handlers(struct il_priv *il) 1470*7ac9a364SKalle Valo { 1471*7ac9a364SKalle Valo /* scan handlers */ 1472*7ac9a364SKalle Valo il->handlers[C_SCAN] = il_hdl_scan; 1473*7ac9a364SKalle Valo il->handlers[N_SCAN_START] = il_hdl_scan_start; 1474*7ac9a364SKalle Valo il->handlers[N_SCAN_RESULTS] = il_hdl_scan_results; 1475*7ac9a364SKalle Valo il->handlers[N_SCAN_COMPLETE] = il_hdl_scan_complete; 1476*7ac9a364SKalle Valo } 1477*7ac9a364SKalle Valo EXPORT_SYMBOL(il_setup_rx_scan_handlers); 1478*7ac9a364SKalle Valo 1479*7ac9a364SKalle Valo u16 1480*7ac9a364SKalle Valo il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band, 1481*7ac9a364SKalle Valo u8 n_probes) 1482*7ac9a364SKalle Valo { 1483*7ac9a364SKalle Valo if (band == IEEE80211_BAND_5GHZ) 1484*7ac9a364SKalle Valo return IL_ACTIVE_DWELL_TIME_52 + 1485*7ac9a364SKalle Valo IL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1); 1486*7ac9a364SKalle Valo else 1487*7ac9a364SKalle Valo return IL_ACTIVE_DWELL_TIME_24 + 1488*7ac9a364SKalle Valo IL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); 1489*7ac9a364SKalle Valo } 1490*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_active_dwell_time); 1491*7ac9a364SKalle Valo 1492*7ac9a364SKalle Valo u16 1493*7ac9a364SKalle Valo il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band, 1494*7ac9a364SKalle Valo struct ieee80211_vif *vif) 1495*7ac9a364SKalle Valo { 1496*7ac9a364SKalle Valo u16 value; 1497*7ac9a364SKalle Valo 1498*7ac9a364SKalle Valo u16 passive = 1499*7ac9a364SKalle Valo (band == 1500*7ac9a364SKalle Valo IEEE80211_BAND_2GHZ) ? IL_PASSIVE_DWELL_BASE + 1501*7ac9a364SKalle Valo IL_PASSIVE_DWELL_TIME_24 : IL_PASSIVE_DWELL_BASE + 1502*7ac9a364SKalle Valo IL_PASSIVE_DWELL_TIME_52; 1503*7ac9a364SKalle Valo 1504*7ac9a364SKalle Valo if (il_is_any_associated(il)) { 1505*7ac9a364SKalle Valo /* 1506*7ac9a364SKalle Valo * If we're associated, we clamp the maximum passive 1507*7ac9a364SKalle Valo * dwell time to be 98% of the smallest beacon interval 1508*7ac9a364SKalle Valo * (minus 2 * channel tune time) 1509*7ac9a364SKalle Valo */ 1510*7ac9a364SKalle Valo value = il->vif ? il->vif->bss_conf.beacon_int : 0; 1511*7ac9a364SKalle Valo if (value > IL_PASSIVE_DWELL_BASE || !value) 1512*7ac9a364SKalle Valo value = IL_PASSIVE_DWELL_BASE; 1513*7ac9a364SKalle Valo value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2; 1514*7ac9a364SKalle Valo passive = min(value, passive); 1515*7ac9a364SKalle Valo } 1516*7ac9a364SKalle Valo 1517*7ac9a364SKalle Valo return passive; 1518*7ac9a364SKalle Valo } 1519*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_passive_dwell_time); 1520*7ac9a364SKalle Valo 1521*7ac9a364SKalle Valo void 1522*7ac9a364SKalle Valo il_init_scan_params(struct il_priv *il) 1523*7ac9a364SKalle Valo { 1524*7ac9a364SKalle Valo u8 ant_idx = fls(il->hw_params.valid_tx_ant) - 1; 1525*7ac9a364SKalle Valo if (!il->scan_tx_ant[IEEE80211_BAND_5GHZ]) 1526*7ac9a364SKalle Valo il->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; 1527*7ac9a364SKalle Valo if (!il->scan_tx_ant[IEEE80211_BAND_2GHZ]) 1528*7ac9a364SKalle Valo il->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; 1529*7ac9a364SKalle Valo } 1530*7ac9a364SKalle Valo EXPORT_SYMBOL(il_init_scan_params); 1531*7ac9a364SKalle Valo 1532*7ac9a364SKalle Valo static int 1533*7ac9a364SKalle Valo il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif) 1534*7ac9a364SKalle Valo { 1535*7ac9a364SKalle Valo int ret; 1536*7ac9a364SKalle Valo 1537*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 1538*7ac9a364SKalle Valo 1539*7ac9a364SKalle Valo cancel_delayed_work(&il->scan_check); 1540*7ac9a364SKalle Valo 1541*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) { 1542*7ac9a364SKalle Valo IL_WARN("Request scan called when driver not ready.\n"); 1543*7ac9a364SKalle Valo return -EIO; 1544*7ac9a364SKalle Valo } 1545*7ac9a364SKalle Valo 1546*7ac9a364SKalle Valo if (test_bit(S_SCAN_HW, &il->status)) { 1547*7ac9a364SKalle Valo D_SCAN("Multiple concurrent scan requests in parallel.\n"); 1548*7ac9a364SKalle Valo return -EBUSY; 1549*7ac9a364SKalle Valo } 1550*7ac9a364SKalle Valo 1551*7ac9a364SKalle Valo if (test_bit(S_SCAN_ABORTING, &il->status)) { 1552*7ac9a364SKalle Valo D_SCAN("Scan request while abort pending.\n"); 1553*7ac9a364SKalle Valo return -EBUSY; 1554*7ac9a364SKalle Valo } 1555*7ac9a364SKalle Valo 1556*7ac9a364SKalle Valo D_SCAN("Starting scan...\n"); 1557*7ac9a364SKalle Valo 1558*7ac9a364SKalle Valo set_bit(S_SCANNING, &il->status); 1559*7ac9a364SKalle Valo il->scan_start = jiffies; 1560*7ac9a364SKalle Valo 1561*7ac9a364SKalle Valo ret = il->ops->request_scan(il, vif); 1562*7ac9a364SKalle Valo if (ret) { 1563*7ac9a364SKalle Valo clear_bit(S_SCANNING, &il->status); 1564*7ac9a364SKalle Valo return ret; 1565*7ac9a364SKalle Valo } 1566*7ac9a364SKalle Valo 1567*7ac9a364SKalle Valo queue_delayed_work(il->workqueue, &il->scan_check, 1568*7ac9a364SKalle Valo IL_SCAN_CHECK_WATCHDOG); 1569*7ac9a364SKalle Valo 1570*7ac9a364SKalle Valo return 0; 1571*7ac9a364SKalle Valo } 1572*7ac9a364SKalle Valo 1573*7ac9a364SKalle Valo int 1574*7ac9a364SKalle Valo il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1575*7ac9a364SKalle Valo struct ieee80211_scan_request *hw_req) 1576*7ac9a364SKalle Valo { 1577*7ac9a364SKalle Valo struct cfg80211_scan_request *req = &hw_req->req; 1578*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 1579*7ac9a364SKalle Valo int ret; 1580*7ac9a364SKalle Valo 1581*7ac9a364SKalle Valo if (req->n_channels == 0) { 1582*7ac9a364SKalle Valo IL_ERR("Can not scan on no channels.\n"); 1583*7ac9a364SKalle Valo return -EINVAL; 1584*7ac9a364SKalle Valo } 1585*7ac9a364SKalle Valo 1586*7ac9a364SKalle Valo mutex_lock(&il->mutex); 1587*7ac9a364SKalle Valo D_MAC80211("enter\n"); 1588*7ac9a364SKalle Valo 1589*7ac9a364SKalle Valo if (test_bit(S_SCANNING, &il->status)) { 1590*7ac9a364SKalle Valo D_SCAN("Scan already in progress.\n"); 1591*7ac9a364SKalle Valo ret = -EAGAIN; 1592*7ac9a364SKalle Valo goto out_unlock; 1593*7ac9a364SKalle Valo } 1594*7ac9a364SKalle Valo 1595*7ac9a364SKalle Valo /* mac80211 will only ask for one band at a time */ 1596*7ac9a364SKalle Valo il->scan_request = req; 1597*7ac9a364SKalle Valo il->scan_vif = vif; 1598*7ac9a364SKalle Valo il->scan_band = req->channels[0]->band; 1599*7ac9a364SKalle Valo 1600*7ac9a364SKalle Valo ret = il_scan_initiate(il, vif); 1601*7ac9a364SKalle Valo 1602*7ac9a364SKalle Valo out_unlock: 1603*7ac9a364SKalle Valo D_MAC80211("leave ret %d\n", ret); 1604*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 1605*7ac9a364SKalle Valo 1606*7ac9a364SKalle Valo return ret; 1607*7ac9a364SKalle Valo } 1608*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_hw_scan); 1609*7ac9a364SKalle Valo 1610*7ac9a364SKalle Valo static void 1611*7ac9a364SKalle Valo il_bg_scan_check(struct work_struct *data) 1612*7ac9a364SKalle Valo { 1613*7ac9a364SKalle Valo struct il_priv *il = 1614*7ac9a364SKalle Valo container_of(data, struct il_priv, scan_check.work); 1615*7ac9a364SKalle Valo 1616*7ac9a364SKalle Valo D_SCAN("Scan check work\n"); 1617*7ac9a364SKalle Valo 1618*7ac9a364SKalle Valo /* Since we are here firmware does not finish scan and 1619*7ac9a364SKalle Valo * most likely is in bad shape, so we don't bother to 1620*7ac9a364SKalle Valo * send abort command, just force scan complete to mac80211 */ 1621*7ac9a364SKalle Valo mutex_lock(&il->mutex); 1622*7ac9a364SKalle Valo il_force_scan_end(il); 1623*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 1624*7ac9a364SKalle Valo } 1625*7ac9a364SKalle Valo 1626*7ac9a364SKalle Valo /** 1627*7ac9a364SKalle Valo * il_fill_probe_req - fill in all required fields and IE for probe request 1628*7ac9a364SKalle Valo */ 1629*7ac9a364SKalle Valo 1630*7ac9a364SKalle Valo u16 1631*7ac9a364SKalle Valo il_fill_probe_req(struct il_priv *il, struct ieee80211_mgmt *frame, 1632*7ac9a364SKalle Valo const u8 *ta, const u8 *ies, int ie_len, int left) 1633*7ac9a364SKalle Valo { 1634*7ac9a364SKalle Valo int len = 0; 1635*7ac9a364SKalle Valo u8 *pos = NULL; 1636*7ac9a364SKalle Valo 1637*7ac9a364SKalle Valo /* Make sure there is enough space for the probe request, 1638*7ac9a364SKalle Valo * two mandatory IEs and the data */ 1639*7ac9a364SKalle Valo left -= 24; 1640*7ac9a364SKalle Valo if (left < 0) 1641*7ac9a364SKalle Valo return 0; 1642*7ac9a364SKalle Valo 1643*7ac9a364SKalle Valo frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 1644*7ac9a364SKalle Valo eth_broadcast_addr(frame->da); 1645*7ac9a364SKalle Valo memcpy(frame->sa, ta, ETH_ALEN); 1646*7ac9a364SKalle Valo eth_broadcast_addr(frame->bssid); 1647*7ac9a364SKalle Valo frame->seq_ctrl = 0; 1648*7ac9a364SKalle Valo 1649*7ac9a364SKalle Valo len += 24; 1650*7ac9a364SKalle Valo 1651*7ac9a364SKalle Valo /* ...next IE... */ 1652*7ac9a364SKalle Valo pos = &frame->u.probe_req.variable[0]; 1653*7ac9a364SKalle Valo 1654*7ac9a364SKalle Valo /* fill in our indirect SSID IE */ 1655*7ac9a364SKalle Valo left -= 2; 1656*7ac9a364SKalle Valo if (left < 0) 1657*7ac9a364SKalle Valo return 0; 1658*7ac9a364SKalle Valo *pos++ = WLAN_EID_SSID; 1659*7ac9a364SKalle Valo *pos++ = 0; 1660*7ac9a364SKalle Valo 1661*7ac9a364SKalle Valo len += 2; 1662*7ac9a364SKalle Valo 1663*7ac9a364SKalle Valo if (WARN_ON(left < ie_len)) 1664*7ac9a364SKalle Valo return len; 1665*7ac9a364SKalle Valo 1666*7ac9a364SKalle Valo if (ies && ie_len) { 1667*7ac9a364SKalle Valo memcpy(pos, ies, ie_len); 1668*7ac9a364SKalle Valo len += ie_len; 1669*7ac9a364SKalle Valo } 1670*7ac9a364SKalle Valo 1671*7ac9a364SKalle Valo return (u16) len; 1672*7ac9a364SKalle Valo } 1673*7ac9a364SKalle Valo EXPORT_SYMBOL(il_fill_probe_req); 1674*7ac9a364SKalle Valo 1675*7ac9a364SKalle Valo static void 1676*7ac9a364SKalle Valo il_bg_abort_scan(struct work_struct *work) 1677*7ac9a364SKalle Valo { 1678*7ac9a364SKalle Valo struct il_priv *il = container_of(work, struct il_priv, abort_scan); 1679*7ac9a364SKalle Valo 1680*7ac9a364SKalle Valo D_SCAN("Abort scan work\n"); 1681*7ac9a364SKalle Valo 1682*7ac9a364SKalle Valo /* We keep scan_check work queued in case when firmware will not 1683*7ac9a364SKalle Valo * report back scan completed notification */ 1684*7ac9a364SKalle Valo mutex_lock(&il->mutex); 1685*7ac9a364SKalle Valo il_scan_cancel_timeout(il, 200); 1686*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 1687*7ac9a364SKalle Valo } 1688*7ac9a364SKalle Valo 1689*7ac9a364SKalle Valo static void 1690*7ac9a364SKalle Valo il_bg_scan_completed(struct work_struct *work) 1691*7ac9a364SKalle Valo { 1692*7ac9a364SKalle Valo struct il_priv *il = container_of(work, struct il_priv, scan_completed); 1693*7ac9a364SKalle Valo bool aborted; 1694*7ac9a364SKalle Valo 1695*7ac9a364SKalle Valo D_SCAN("Completed scan.\n"); 1696*7ac9a364SKalle Valo 1697*7ac9a364SKalle Valo cancel_delayed_work(&il->scan_check); 1698*7ac9a364SKalle Valo 1699*7ac9a364SKalle Valo mutex_lock(&il->mutex); 1700*7ac9a364SKalle Valo 1701*7ac9a364SKalle Valo aborted = test_and_clear_bit(S_SCAN_ABORTING, &il->status); 1702*7ac9a364SKalle Valo if (aborted) 1703*7ac9a364SKalle Valo D_SCAN("Aborted scan completed.\n"); 1704*7ac9a364SKalle Valo 1705*7ac9a364SKalle Valo if (!test_and_clear_bit(S_SCANNING, &il->status)) { 1706*7ac9a364SKalle Valo D_SCAN("Scan already completed.\n"); 1707*7ac9a364SKalle Valo goto out_settings; 1708*7ac9a364SKalle Valo } 1709*7ac9a364SKalle Valo 1710*7ac9a364SKalle Valo il_complete_scan(il, aborted); 1711*7ac9a364SKalle Valo 1712*7ac9a364SKalle Valo out_settings: 1713*7ac9a364SKalle Valo /* Can we still talk to firmware ? */ 1714*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) 1715*7ac9a364SKalle Valo goto out; 1716*7ac9a364SKalle Valo 1717*7ac9a364SKalle Valo /* 1718*7ac9a364SKalle Valo * We do not commit power settings while scan is pending, 1719*7ac9a364SKalle Valo * do it now if the settings changed. 1720*7ac9a364SKalle Valo */ 1721*7ac9a364SKalle Valo il_power_set_mode(il, &il->power_data.sleep_cmd_next, false); 1722*7ac9a364SKalle Valo il_set_tx_power(il, il->tx_power_next, false); 1723*7ac9a364SKalle Valo 1724*7ac9a364SKalle Valo il->ops->post_scan(il); 1725*7ac9a364SKalle Valo 1726*7ac9a364SKalle Valo out: 1727*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 1728*7ac9a364SKalle Valo } 1729*7ac9a364SKalle Valo 1730*7ac9a364SKalle Valo void 1731*7ac9a364SKalle Valo il_setup_scan_deferred_work(struct il_priv *il) 1732*7ac9a364SKalle Valo { 1733*7ac9a364SKalle Valo INIT_WORK(&il->scan_completed, il_bg_scan_completed); 1734*7ac9a364SKalle Valo INIT_WORK(&il->abort_scan, il_bg_abort_scan); 1735*7ac9a364SKalle Valo INIT_DELAYED_WORK(&il->scan_check, il_bg_scan_check); 1736*7ac9a364SKalle Valo } 1737*7ac9a364SKalle Valo EXPORT_SYMBOL(il_setup_scan_deferred_work); 1738*7ac9a364SKalle Valo 1739*7ac9a364SKalle Valo void 1740*7ac9a364SKalle Valo il_cancel_scan_deferred_work(struct il_priv *il) 1741*7ac9a364SKalle Valo { 1742*7ac9a364SKalle Valo cancel_work_sync(&il->abort_scan); 1743*7ac9a364SKalle Valo cancel_work_sync(&il->scan_completed); 1744*7ac9a364SKalle Valo 1745*7ac9a364SKalle Valo if (cancel_delayed_work_sync(&il->scan_check)) { 1746*7ac9a364SKalle Valo mutex_lock(&il->mutex); 1747*7ac9a364SKalle Valo il_force_scan_end(il); 1748*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 1749*7ac9a364SKalle Valo } 1750*7ac9a364SKalle Valo } 1751*7ac9a364SKalle Valo EXPORT_SYMBOL(il_cancel_scan_deferred_work); 1752*7ac9a364SKalle Valo 1753*7ac9a364SKalle Valo /* il->sta_lock must be held */ 1754*7ac9a364SKalle Valo static void 1755*7ac9a364SKalle Valo il_sta_ucode_activate(struct il_priv *il, u8 sta_id) 1756*7ac9a364SKalle Valo { 1757*7ac9a364SKalle Valo 1758*7ac9a364SKalle Valo if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) 1759*7ac9a364SKalle Valo IL_ERR("ACTIVATE a non DRIVER active station id %u addr %pM\n", 1760*7ac9a364SKalle Valo sta_id, il->stations[sta_id].sta.sta.addr); 1761*7ac9a364SKalle Valo 1762*7ac9a364SKalle Valo if (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) { 1763*7ac9a364SKalle Valo D_ASSOC("STA id %u addr %pM already present" 1764*7ac9a364SKalle Valo " in uCode (according to driver)\n", sta_id, 1765*7ac9a364SKalle Valo il->stations[sta_id].sta.sta.addr); 1766*7ac9a364SKalle Valo } else { 1767*7ac9a364SKalle Valo il->stations[sta_id].used |= IL_STA_UCODE_ACTIVE; 1768*7ac9a364SKalle Valo D_ASSOC("Added STA id %u addr %pM to uCode\n", sta_id, 1769*7ac9a364SKalle Valo il->stations[sta_id].sta.sta.addr); 1770*7ac9a364SKalle Valo } 1771*7ac9a364SKalle Valo } 1772*7ac9a364SKalle Valo 1773*7ac9a364SKalle Valo static int 1774*7ac9a364SKalle Valo il_process_add_sta_resp(struct il_priv *il, struct il_addsta_cmd *addsta, 1775*7ac9a364SKalle Valo struct il_rx_pkt *pkt, bool sync) 1776*7ac9a364SKalle Valo { 1777*7ac9a364SKalle Valo u8 sta_id = addsta->sta.sta_id; 1778*7ac9a364SKalle Valo unsigned long flags; 1779*7ac9a364SKalle Valo int ret = -EIO; 1780*7ac9a364SKalle Valo 1781*7ac9a364SKalle Valo if (pkt->hdr.flags & IL_CMD_FAILED_MSK) { 1782*7ac9a364SKalle Valo IL_ERR("Bad return from C_ADD_STA (0x%08X)\n", pkt->hdr.flags); 1783*7ac9a364SKalle Valo return ret; 1784*7ac9a364SKalle Valo } 1785*7ac9a364SKalle Valo 1786*7ac9a364SKalle Valo D_INFO("Processing response for adding station %u\n", sta_id); 1787*7ac9a364SKalle Valo 1788*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags); 1789*7ac9a364SKalle Valo 1790*7ac9a364SKalle Valo switch (pkt->u.add_sta.status) { 1791*7ac9a364SKalle Valo case ADD_STA_SUCCESS_MSK: 1792*7ac9a364SKalle Valo D_INFO("C_ADD_STA PASSED\n"); 1793*7ac9a364SKalle Valo il_sta_ucode_activate(il, sta_id); 1794*7ac9a364SKalle Valo ret = 0; 1795*7ac9a364SKalle Valo break; 1796*7ac9a364SKalle Valo case ADD_STA_NO_ROOM_IN_TBL: 1797*7ac9a364SKalle Valo IL_ERR("Adding station %d failed, no room in table.\n", sta_id); 1798*7ac9a364SKalle Valo break; 1799*7ac9a364SKalle Valo case ADD_STA_NO_BLOCK_ACK_RESOURCE: 1800*7ac9a364SKalle Valo IL_ERR("Adding station %d failed, no block ack resource.\n", 1801*7ac9a364SKalle Valo sta_id); 1802*7ac9a364SKalle Valo break; 1803*7ac9a364SKalle Valo case ADD_STA_MODIFY_NON_EXIST_STA: 1804*7ac9a364SKalle Valo IL_ERR("Attempting to modify non-existing station %d\n", 1805*7ac9a364SKalle Valo sta_id); 1806*7ac9a364SKalle Valo break; 1807*7ac9a364SKalle Valo default: 1808*7ac9a364SKalle Valo D_ASSOC("Received C_ADD_STA:(0x%08X)\n", pkt->u.add_sta.status); 1809*7ac9a364SKalle Valo break; 1810*7ac9a364SKalle Valo } 1811*7ac9a364SKalle Valo 1812*7ac9a364SKalle Valo D_INFO("%s station id %u addr %pM\n", 1813*7ac9a364SKalle Valo il->stations[sta_id].sta.mode == 1814*7ac9a364SKalle Valo STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", sta_id, 1815*7ac9a364SKalle Valo il->stations[sta_id].sta.sta.addr); 1816*7ac9a364SKalle Valo 1817*7ac9a364SKalle Valo /* 1818*7ac9a364SKalle Valo * XXX: The MAC address in the command buffer is often changed from 1819*7ac9a364SKalle Valo * the original sent to the device. That is, the MAC address 1820*7ac9a364SKalle Valo * written to the command buffer often is not the same MAC address 1821*7ac9a364SKalle Valo * read from the command buffer when the command returns. This 1822*7ac9a364SKalle Valo * issue has not yet been resolved and this debugging is left to 1823*7ac9a364SKalle Valo * observe the problem. 1824*7ac9a364SKalle Valo */ 1825*7ac9a364SKalle Valo D_INFO("%s station according to cmd buffer %pM\n", 1826*7ac9a364SKalle Valo il->stations[sta_id].sta.mode == 1827*7ac9a364SKalle Valo STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", addsta->sta.addr); 1828*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags); 1829*7ac9a364SKalle Valo 1830*7ac9a364SKalle Valo return ret; 1831*7ac9a364SKalle Valo } 1832*7ac9a364SKalle Valo 1833*7ac9a364SKalle Valo static void 1834*7ac9a364SKalle Valo il_add_sta_callback(struct il_priv *il, struct il_device_cmd *cmd, 1835*7ac9a364SKalle Valo struct il_rx_pkt *pkt) 1836*7ac9a364SKalle Valo { 1837*7ac9a364SKalle Valo struct il_addsta_cmd *addsta = (struct il_addsta_cmd *)cmd->cmd.payload; 1838*7ac9a364SKalle Valo 1839*7ac9a364SKalle Valo il_process_add_sta_resp(il, addsta, pkt, false); 1840*7ac9a364SKalle Valo 1841*7ac9a364SKalle Valo } 1842*7ac9a364SKalle Valo 1843*7ac9a364SKalle Valo int 1844*7ac9a364SKalle Valo il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags) 1845*7ac9a364SKalle Valo { 1846*7ac9a364SKalle Valo struct il_rx_pkt *pkt = NULL; 1847*7ac9a364SKalle Valo int ret = 0; 1848*7ac9a364SKalle Valo u8 data[sizeof(*sta)]; 1849*7ac9a364SKalle Valo struct il_host_cmd cmd = { 1850*7ac9a364SKalle Valo .id = C_ADD_STA, 1851*7ac9a364SKalle Valo .flags = flags, 1852*7ac9a364SKalle Valo .data = data, 1853*7ac9a364SKalle Valo }; 1854*7ac9a364SKalle Valo u8 sta_id __maybe_unused = sta->sta.sta_id; 1855*7ac9a364SKalle Valo 1856*7ac9a364SKalle Valo D_INFO("Adding sta %u (%pM) %ssynchronously\n", sta_id, sta->sta.addr, 1857*7ac9a364SKalle Valo flags & CMD_ASYNC ? "a" : ""); 1858*7ac9a364SKalle Valo 1859*7ac9a364SKalle Valo if (flags & CMD_ASYNC) 1860*7ac9a364SKalle Valo cmd.callback = il_add_sta_callback; 1861*7ac9a364SKalle Valo else { 1862*7ac9a364SKalle Valo cmd.flags |= CMD_WANT_SKB; 1863*7ac9a364SKalle Valo might_sleep(); 1864*7ac9a364SKalle Valo } 1865*7ac9a364SKalle Valo 1866*7ac9a364SKalle Valo cmd.len = il->ops->build_addsta_hcmd(sta, data); 1867*7ac9a364SKalle Valo ret = il_send_cmd(il, &cmd); 1868*7ac9a364SKalle Valo 1869*7ac9a364SKalle Valo if (ret || (flags & CMD_ASYNC)) 1870*7ac9a364SKalle Valo return ret; 1871*7ac9a364SKalle Valo 1872*7ac9a364SKalle Valo if (ret == 0) { 1873*7ac9a364SKalle Valo pkt = (struct il_rx_pkt *)cmd.reply_page; 1874*7ac9a364SKalle Valo ret = il_process_add_sta_resp(il, sta, pkt, true); 1875*7ac9a364SKalle Valo } 1876*7ac9a364SKalle Valo il_free_pages(il, cmd.reply_page); 1877*7ac9a364SKalle Valo 1878*7ac9a364SKalle Valo return ret; 1879*7ac9a364SKalle Valo } 1880*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_add_sta); 1881*7ac9a364SKalle Valo 1882*7ac9a364SKalle Valo static void 1883*7ac9a364SKalle Valo il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta) 1884*7ac9a364SKalle Valo { 1885*7ac9a364SKalle Valo struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; 1886*7ac9a364SKalle Valo __le32 sta_flags; 1887*7ac9a364SKalle Valo 1888*7ac9a364SKalle Valo if (!sta || !sta_ht_inf->ht_supported) 1889*7ac9a364SKalle Valo goto done; 1890*7ac9a364SKalle Valo 1891*7ac9a364SKalle Valo D_ASSOC("spatial multiplexing power save mode: %s\n", 1892*7ac9a364SKalle Valo (sta->smps_mode == IEEE80211_SMPS_STATIC) ? "static" : 1893*7ac9a364SKalle Valo (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ? "dynamic" : 1894*7ac9a364SKalle Valo "disabled"); 1895*7ac9a364SKalle Valo 1896*7ac9a364SKalle Valo sta_flags = il->stations[idx].sta.station_flags; 1897*7ac9a364SKalle Valo 1898*7ac9a364SKalle Valo sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); 1899*7ac9a364SKalle Valo 1900*7ac9a364SKalle Valo switch (sta->smps_mode) { 1901*7ac9a364SKalle Valo case IEEE80211_SMPS_STATIC: 1902*7ac9a364SKalle Valo sta_flags |= STA_FLG_MIMO_DIS_MSK; 1903*7ac9a364SKalle Valo break; 1904*7ac9a364SKalle Valo case IEEE80211_SMPS_DYNAMIC: 1905*7ac9a364SKalle Valo sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; 1906*7ac9a364SKalle Valo break; 1907*7ac9a364SKalle Valo case IEEE80211_SMPS_OFF: 1908*7ac9a364SKalle Valo break; 1909*7ac9a364SKalle Valo default: 1910*7ac9a364SKalle Valo IL_WARN("Invalid MIMO PS mode %d\n", sta->smps_mode); 1911*7ac9a364SKalle Valo break; 1912*7ac9a364SKalle Valo } 1913*7ac9a364SKalle Valo 1914*7ac9a364SKalle Valo sta_flags |= 1915*7ac9a364SKalle Valo cpu_to_le32((u32) sta_ht_inf-> 1916*7ac9a364SKalle Valo ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); 1917*7ac9a364SKalle Valo 1918*7ac9a364SKalle Valo sta_flags |= 1919*7ac9a364SKalle Valo cpu_to_le32((u32) sta_ht_inf-> 1920*7ac9a364SKalle Valo ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); 1921*7ac9a364SKalle Valo 1922*7ac9a364SKalle Valo if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) 1923*7ac9a364SKalle Valo sta_flags |= STA_FLG_HT40_EN_MSK; 1924*7ac9a364SKalle Valo else 1925*7ac9a364SKalle Valo sta_flags &= ~STA_FLG_HT40_EN_MSK; 1926*7ac9a364SKalle Valo 1927*7ac9a364SKalle Valo il->stations[idx].sta.station_flags = sta_flags; 1928*7ac9a364SKalle Valo done: 1929*7ac9a364SKalle Valo return; 1930*7ac9a364SKalle Valo } 1931*7ac9a364SKalle Valo 1932*7ac9a364SKalle Valo /** 1933*7ac9a364SKalle Valo * il_prep_station - Prepare station information for addition 1934*7ac9a364SKalle Valo * 1935*7ac9a364SKalle Valo * should be called with sta_lock held 1936*7ac9a364SKalle Valo */ 1937*7ac9a364SKalle Valo u8 1938*7ac9a364SKalle Valo il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, 1939*7ac9a364SKalle Valo struct ieee80211_sta *sta) 1940*7ac9a364SKalle Valo { 1941*7ac9a364SKalle Valo struct il_station_entry *station; 1942*7ac9a364SKalle Valo int i; 1943*7ac9a364SKalle Valo u8 sta_id = IL_INVALID_STATION; 1944*7ac9a364SKalle Valo u16 rate; 1945*7ac9a364SKalle Valo 1946*7ac9a364SKalle Valo if (is_ap) 1947*7ac9a364SKalle Valo sta_id = IL_AP_ID; 1948*7ac9a364SKalle Valo else if (is_broadcast_ether_addr(addr)) 1949*7ac9a364SKalle Valo sta_id = il->hw_params.bcast_id; 1950*7ac9a364SKalle Valo else 1951*7ac9a364SKalle Valo for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { 1952*7ac9a364SKalle Valo if (ether_addr_equal(il->stations[i].sta.sta.addr, 1953*7ac9a364SKalle Valo addr)) { 1954*7ac9a364SKalle Valo sta_id = i; 1955*7ac9a364SKalle Valo break; 1956*7ac9a364SKalle Valo } 1957*7ac9a364SKalle Valo 1958*7ac9a364SKalle Valo if (!il->stations[i].used && 1959*7ac9a364SKalle Valo sta_id == IL_INVALID_STATION) 1960*7ac9a364SKalle Valo sta_id = i; 1961*7ac9a364SKalle Valo } 1962*7ac9a364SKalle Valo 1963*7ac9a364SKalle Valo /* 1964*7ac9a364SKalle Valo * These two conditions have the same outcome, but keep them 1965*7ac9a364SKalle Valo * separate 1966*7ac9a364SKalle Valo */ 1967*7ac9a364SKalle Valo if (unlikely(sta_id == IL_INVALID_STATION)) 1968*7ac9a364SKalle Valo return sta_id; 1969*7ac9a364SKalle Valo 1970*7ac9a364SKalle Valo /* 1971*7ac9a364SKalle Valo * uCode is not able to deal with multiple requests to add a 1972*7ac9a364SKalle Valo * station. Keep track if one is in progress so that we do not send 1973*7ac9a364SKalle Valo * another. 1974*7ac9a364SKalle Valo */ 1975*7ac9a364SKalle Valo if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) { 1976*7ac9a364SKalle Valo D_INFO("STA %d already in process of being added.\n", sta_id); 1977*7ac9a364SKalle Valo return sta_id; 1978*7ac9a364SKalle Valo } 1979*7ac9a364SKalle Valo 1980*7ac9a364SKalle Valo if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && 1981*7ac9a364SKalle Valo (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) && 1982*7ac9a364SKalle Valo ether_addr_equal(il->stations[sta_id].sta.sta.addr, addr)) { 1983*7ac9a364SKalle Valo D_ASSOC("STA %d (%pM) already added, not adding again.\n", 1984*7ac9a364SKalle Valo sta_id, addr); 1985*7ac9a364SKalle Valo return sta_id; 1986*7ac9a364SKalle Valo } 1987*7ac9a364SKalle Valo 1988*7ac9a364SKalle Valo station = &il->stations[sta_id]; 1989*7ac9a364SKalle Valo station->used = IL_STA_DRIVER_ACTIVE; 1990*7ac9a364SKalle Valo D_ASSOC("Add STA to driver ID %d: %pM\n", sta_id, addr); 1991*7ac9a364SKalle Valo il->num_stations++; 1992*7ac9a364SKalle Valo 1993*7ac9a364SKalle Valo /* Set up the C_ADD_STA command to send to device */ 1994*7ac9a364SKalle Valo memset(&station->sta, 0, sizeof(struct il_addsta_cmd)); 1995*7ac9a364SKalle Valo memcpy(station->sta.sta.addr, addr, ETH_ALEN); 1996*7ac9a364SKalle Valo station->sta.mode = 0; 1997*7ac9a364SKalle Valo station->sta.sta.sta_id = sta_id; 1998*7ac9a364SKalle Valo station->sta.station_flags = 0; 1999*7ac9a364SKalle Valo 2000*7ac9a364SKalle Valo /* 2001*7ac9a364SKalle Valo * OK to call unconditionally, since local stations (IBSS BSSID 2002*7ac9a364SKalle Valo * STA and broadcast STA) pass in a NULL sta, and mac80211 2003*7ac9a364SKalle Valo * doesn't allow HT IBSS. 2004*7ac9a364SKalle Valo */ 2005*7ac9a364SKalle Valo il_set_ht_add_station(il, sta_id, sta); 2006*7ac9a364SKalle Valo 2007*7ac9a364SKalle Valo /* 3945 only */ 2008*7ac9a364SKalle Valo rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP; 2009*7ac9a364SKalle Valo /* Turn on both antennas for the station... */ 2010*7ac9a364SKalle Valo station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); 2011*7ac9a364SKalle Valo 2012*7ac9a364SKalle Valo return sta_id; 2013*7ac9a364SKalle Valo 2014*7ac9a364SKalle Valo } 2015*7ac9a364SKalle Valo EXPORT_SYMBOL_GPL(il_prep_station); 2016*7ac9a364SKalle Valo 2017*7ac9a364SKalle Valo #define STA_WAIT_TIMEOUT (HZ/2) 2018*7ac9a364SKalle Valo 2019*7ac9a364SKalle Valo /** 2020*7ac9a364SKalle Valo * il_add_station_common - 2021*7ac9a364SKalle Valo */ 2022*7ac9a364SKalle Valo int 2023*7ac9a364SKalle Valo il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap, 2024*7ac9a364SKalle Valo struct ieee80211_sta *sta, u8 *sta_id_r) 2025*7ac9a364SKalle Valo { 2026*7ac9a364SKalle Valo unsigned long flags_spin; 2027*7ac9a364SKalle Valo int ret = 0; 2028*7ac9a364SKalle Valo u8 sta_id; 2029*7ac9a364SKalle Valo struct il_addsta_cmd sta_cmd; 2030*7ac9a364SKalle Valo 2031*7ac9a364SKalle Valo *sta_id_r = 0; 2032*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2033*7ac9a364SKalle Valo sta_id = il_prep_station(il, addr, is_ap, sta); 2034*7ac9a364SKalle Valo if (sta_id == IL_INVALID_STATION) { 2035*7ac9a364SKalle Valo IL_ERR("Unable to prepare station %pM for addition\n", addr); 2036*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2037*7ac9a364SKalle Valo return -EINVAL; 2038*7ac9a364SKalle Valo } 2039*7ac9a364SKalle Valo 2040*7ac9a364SKalle Valo /* 2041*7ac9a364SKalle Valo * uCode is not able to deal with multiple requests to add a 2042*7ac9a364SKalle Valo * station. Keep track if one is in progress so that we do not send 2043*7ac9a364SKalle Valo * another. 2044*7ac9a364SKalle Valo */ 2045*7ac9a364SKalle Valo if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) { 2046*7ac9a364SKalle Valo D_INFO("STA %d already in process of being added.\n", sta_id); 2047*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2048*7ac9a364SKalle Valo return -EEXIST; 2049*7ac9a364SKalle Valo } 2050*7ac9a364SKalle Valo 2051*7ac9a364SKalle Valo if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && 2052*7ac9a364SKalle Valo (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) { 2053*7ac9a364SKalle Valo D_ASSOC("STA %d (%pM) already added, not adding again.\n", 2054*7ac9a364SKalle Valo sta_id, addr); 2055*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2056*7ac9a364SKalle Valo return -EEXIST; 2057*7ac9a364SKalle Valo } 2058*7ac9a364SKalle Valo 2059*7ac9a364SKalle Valo il->stations[sta_id].used |= IL_STA_UCODE_INPROGRESS; 2060*7ac9a364SKalle Valo memcpy(&sta_cmd, &il->stations[sta_id].sta, 2061*7ac9a364SKalle Valo sizeof(struct il_addsta_cmd)); 2062*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2063*7ac9a364SKalle Valo 2064*7ac9a364SKalle Valo /* Add station to device's station table */ 2065*7ac9a364SKalle Valo ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC); 2066*7ac9a364SKalle Valo if (ret) { 2067*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2068*7ac9a364SKalle Valo IL_ERR("Adding station %pM failed.\n", 2069*7ac9a364SKalle Valo il->stations[sta_id].sta.sta.addr); 2070*7ac9a364SKalle Valo il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE; 2071*7ac9a364SKalle Valo il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS; 2072*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2073*7ac9a364SKalle Valo } 2074*7ac9a364SKalle Valo *sta_id_r = sta_id; 2075*7ac9a364SKalle Valo return ret; 2076*7ac9a364SKalle Valo } 2077*7ac9a364SKalle Valo EXPORT_SYMBOL(il_add_station_common); 2078*7ac9a364SKalle Valo 2079*7ac9a364SKalle Valo /** 2080*7ac9a364SKalle Valo * il_sta_ucode_deactivate - deactivate ucode status for a station 2081*7ac9a364SKalle Valo * 2082*7ac9a364SKalle Valo * il->sta_lock must be held 2083*7ac9a364SKalle Valo */ 2084*7ac9a364SKalle Valo static void 2085*7ac9a364SKalle Valo il_sta_ucode_deactivate(struct il_priv *il, u8 sta_id) 2086*7ac9a364SKalle Valo { 2087*7ac9a364SKalle Valo /* Ucode must be active and driver must be non active */ 2088*7ac9a364SKalle Valo if ((il->stations[sta_id]. 2089*7ac9a364SKalle Valo used & (IL_STA_UCODE_ACTIVE | IL_STA_DRIVER_ACTIVE)) != 2090*7ac9a364SKalle Valo IL_STA_UCODE_ACTIVE) 2091*7ac9a364SKalle Valo IL_ERR("removed non active STA %u\n", sta_id); 2092*7ac9a364SKalle Valo 2093*7ac9a364SKalle Valo il->stations[sta_id].used &= ~IL_STA_UCODE_ACTIVE; 2094*7ac9a364SKalle Valo 2095*7ac9a364SKalle Valo memset(&il->stations[sta_id], 0, sizeof(struct il_station_entry)); 2096*7ac9a364SKalle Valo D_ASSOC("Removed STA %u\n", sta_id); 2097*7ac9a364SKalle Valo } 2098*7ac9a364SKalle Valo 2099*7ac9a364SKalle Valo static int 2100*7ac9a364SKalle Valo il_send_remove_station(struct il_priv *il, const u8 * addr, int sta_id, 2101*7ac9a364SKalle Valo bool temporary) 2102*7ac9a364SKalle Valo { 2103*7ac9a364SKalle Valo struct il_rx_pkt *pkt; 2104*7ac9a364SKalle Valo int ret; 2105*7ac9a364SKalle Valo 2106*7ac9a364SKalle Valo unsigned long flags_spin; 2107*7ac9a364SKalle Valo struct il_rem_sta_cmd rm_sta_cmd; 2108*7ac9a364SKalle Valo 2109*7ac9a364SKalle Valo struct il_host_cmd cmd = { 2110*7ac9a364SKalle Valo .id = C_REM_STA, 2111*7ac9a364SKalle Valo .len = sizeof(struct il_rem_sta_cmd), 2112*7ac9a364SKalle Valo .flags = CMD_SYNC, 2113*7ac9a364SKalle Valo .data = &rm_sta_cmd, 2114*7ac9a364SKalle Valo }; 2115*7ac9a364SKalle Valo 2116*7ac9a364SKalle Valo memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 2117*7ac9a364SKalle Valo rm_sta_cmd.num_sta = 1; 2118*7ac9a364SKalle Valo memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN); 2119*7ac9a364SKalle Valo 2120*7ac9a364SKalle Valo cmd.flags |= CMD_WANT_SKB; 2121*7ac9a364SKalle Valo 2122*7ac9a364SKalle Valo ret = il_send_cmd(il, &cmd); 2123*7ac9a364SKalle Valo 2124*7ac9a364SKalle Valo if (ret) 2125*7ac9a364SKalle Valo return ret; 2126*7ac9a364SKalle Valo 2127*7ac9a364SKalle Valo pkt = (struct il_rx_pkt *)cmd.reply_page; 2128*7ac9a364SKalle Valo if (pkt->hdr.flags & IL_CMD_FAILED_MSK) { 2129*7ac9a364SKalle Valo IL_ERR("Bad return from C_REM_STA (0x%08X)\n", pkt->hdr.flags); 2130*7ac9a364SKalle Valo ret = -EIO; 2131*7ac9a364SKalle Valo } 2132*7ac9a364SKalle Valo 2133*7ac9a364SKalle Valo if (!ret) { 2134*7ac9a364SKalle Valo switch (pkt->u.rem_sta.status) { 2135*7ac9a364SKalle Valo case REM_STA_SUCCESS_MSK: 2136*7ac9a364SKalle Valo if (!temporary) { 2137*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2138*7ac9a364SKalle Valo il_sta_ucode_deactivate(il, sta_id); 2139*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, 2140*7ac9a364SKalle Valo flags_spin); 2141*7ac9a364SKalle Valo } 2142*7ac9a364SKalle Valo D_ASSOC("C_REM_STA PASSED\n"); 2143*7ac9a364SKalle Valo break; 2144*7ac9a364SKalle Valo default: 2145*7ac9a364SKalle Valo ret = -EIO; 2146*7ac9a364SKalle Valo IL_ERR("C_REM_STA failed\n"); 2147*7ac9a364SKalle Valo break; 2148*7ac9a364SKalle Valo } 2149*7ac9a364SKalle Valo } 2150*7ac9a364SKalle Valo il_free_pages(il, cmd.reply_page); 2151*7ac9a364SKalle Valo 2152*7ac9a364SKalle Valo return ret; 2153*7ac9a364SKalle Valo } 2154*7ac9a364SKalle Valo 2155*7ac9a364SKalle Valo /** 2156*7ac9a364SKalle Valo * il_remove_station - Remove driver's knowledge of station. 2157*7ac9a364SKalle Valo */ 2158*7ac9a364SKalle Valo int 2159*7ac9a364SKalle Valo il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr) 2160*7ac9a364SKalle Valo { 2161*7ac9a364SKalle Valo unsigned long flags; 2162*7ac9a364SKalle Valo 2163*7ac9a364SKalle Valo if (!il_is_ready(il)) { 2164*7ac9a364SKalle Valo D_INFO("Unable to remove station %pM, device not ready.\n", 2165*7ac9a364SKalle Valo addr); 2166*7ac9a364SKalle Valo /* 2167*7ac9a364SKalle Valo * It is typical for stations to be removed when we are 2168*7ac9a364SKalle Valo * going down. Return success since device will be down 2169*7ac9a364SKalle Valo * soon anyway 2170*7ac9a364SKalle Valo */ 2171*7ac9a364SKalle Valo return 0; 2172*7ac9a364SKalle Valo } 2173*7ac9a364SKalle Valo 2174*7ac9a364SKalle Valo D_ASSOC("Removing STA from driver:%d %pM\n", sta_id, addr); 2175*7ac9a364SKalle Valo 2176*7ac9a364SKalle Valo if (WARN_ON(sta_id == IL_INVALID_STATION)) 2177*7ac9a364SKalle Valo return -EINVAL; 2178*7ac9a364SKalle Valo 2179*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags); 2180*7ac9a364SKalle Valo 2181*7ac9a364SKalle Valo if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) { 2182*7ac9a364SKalle Valo D_INFO("Removing %pM but non DRIVER active\n", addr); 2183*7ac9a364SKalle Valo goto out_err; 2184*7ac9a364SKalle Valo } 2185*7ac9a364SKalle Valo 2186*7ac9a364SKalle Valo if (!(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) { 2187*7ac9a364SKalle Valo D_INFO("Removing %pM but non UCODE active\n", addr); 2188*7ac9a364SKalle Valo goto out_err; 2189*7ac9a364SKalle Valo } 2190*7ac9a364SKalle Valo 2191*7ac9a364SKalle Valo if (il->stations[sta_id].used & IL_STA_LOCAL) { 2192*7ac9a364SKalle Valo kfree(il->stations[sta_id].lq); 2193*7ac9a364SKalle Valo il->stations[sta_id].lq = NULL; 2194*7ac9a364SKalle Valo } 2195*7ac9a364SKalle Valo 2196*7ac9a364SKalle Valo il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE; 2197*7ac9a364SKalle Valo 2198*7ac9a364SKalle Valo il->num_stations--; 2199*7ac9a364SKalle Valo 2200*7ac9a364SKalle Valo BUG_ON(il->num_stations < 0); 2201*7ac9a364SKalle Valo 2202*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags); 2203*7ac9a364SKalle Valo 2204*7ac9a364SKalle Valo return il_send_remove_station(il, addr, sta_id, false); 2205*7ac9a364SKalle Valo out_err: 2206*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags); 2207*7ac9a364SKalle Valo return -EINVAL; 2208*7ac9a364SKalle Valo } 2209*7ac9a364SKalle Valo EXPORT_SYMBOL_GPL(il_remove_station); 2210*7ac9a364SKalle Valo 2211*7ac9a364SKalle Valo /** 2212*7ac9a364SKalle Valo * il_clear_ucode_stations - clear ucode station table bits 2213*7ac9a364SKalle Valo * 2214*7ac9a364SKalle Valo * This function clears all the bits in the driver indicating 2215*7ac9a364SKalle Valo * which stations are active in the ucode. Call when something 2216*7ac9a364SKalle Valo * other than explicit station management would cause this in 2217*7ac9a364SKalle Valo * the ucode, e.g. unassociated RXON. 2218*7ac9a364SKalle Valo */ 2219*7ac9a364SKalle Valo void 2220*7ac9a364SKalle Valo il_clear_ucode_stations(struct il_priv *il) 2221*7ac9a364SKalle Valo { 2222*7ac9a364SKalle Valo int i; 2223*7ac9a364SKalle Valo unsigned long flags_spin; 2224*7ac9a364SKalle Valo bool cleared = false; 2225*7ac9a364SKalle Valo 2226*7ac9a364SKalle Valo D_INFO("Clearing ucode stations in driver\n"); 2227*7ac9a364SKalle Valo 2228*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2229*7ac9a364SKalle Valo for (i = 0; i < il->hw_params.max_stations; i++) { 2230*7ac9a364SKalle Valo if (il->stations[i].used & IL_STA_UCODE_ACTIVE) { 2231*7ac9a364SKalle Valo D_INFO("Clearing ucode active for station %d\n", i); 2232*7ac9a364SKalle Valo il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; 2233*7ac9a364SKalle Valo cleared = true; 2234*7ac9a364SKalle Valo } 2235*7ac9a364SKalle Valo } 2236*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2237*7ac9a364SKalle Valo 2238*7ac9a364SKalle Valo if (!cleared) 2239*7ac9a364SKalle Valo D_INFO("No active stations found to be cleared\n"); 2240*7ac9a364SKalle Valo } 2241*7ac9a364SKalle Valo EXPORT_SYMBOL(il_clear_ucode_stations); 2242*7ac9a364SKalle Valo 2243*7ac9a364SKalle Valo /** 2244*7ac9a364SKalle Valo * il_restore_stations() - Restore driver known stations to device 2245*7ac9a364SKalle Valo * 2246*7ac9a364SKalle Valo * All stations considered active by driver, but not present in ucode, is 2247*7ac9a364SKalle Valo * restored. 2248*7ac9a364SKalle Valo * 2249*7ac9a364SKalle Valo * Function sleeps. 2250*7ac9a364SKalle Valo */ 2251*7ac9a364SKalle Valo void 2252*7ac9a364SKalle Valo il_restore_stations(struct il_priv *il) 2253*7ac9a364SKalle Valo { 2254*7ac9a364SKalle Valo struct il_addsta_cmd sta_cmd; 2255*7ac9a364SKalle Valo struct il_link_quality_cmd lq; 2256*7ac9a364SKalle Valo unsigned long flags_spin; 2257*7ac9a364SKalle Valo int i; 2258*7ac9a364SKalle Valo bool found = false; 2259*7ac9a364SKalle Valo int ret; 2260*7ac9a364SKalle Valo bool send_lq; 2261*7ac9a364SKalle Valo 2262*7ac9a364SKalle Valo if (!il_is_ready(il)) { 2263*7ac9a364SKalle Valo D_INFO("Not ready yet, not restoring any stations.\n"); 2264*7ac9a364SKalle Valo return; 2265*7ac9a364SKalle Valo } 2266*7ac9a364SKalle Valo 2267*7ac9a364SKalle Valo D_ASSOC("Restoring all known stations ... start.\n"); 2268*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2269*7ac9a364SKalle Valo for (i = 0; i < il->hw_params.max_stations; i++) { 2270*7ac9a364SKalle Valo if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) && 2271*7ac9a364SKalle Valo !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) { 2272*7ac9a364SKalle Valo D_ASSOC("Restoring sta %pM\n", 2273*7ac9a364SKalle Valo il->stations[i].sta.sta.addr); 2274*7ac9a364SKalle Valo il->stations[i].sta.mode = 0; 2275*7ac9a364SKalle Valo il->stations[i].used |= IL_STA_UCODE_INPROGRESS; 2276*7ac9a364SKalle Valo found = true; 2277*7ac9a364SKalle Valo } 2278*7ac9a364SKalle Valo } 2279*7ac9a364SKalle Valo 2280*7ac9a364SKalle Valo for (i = 0; i < il->hw_params.max_stations; i++) { 2281*7ac9a364SKalle Valo if ((il->stations[i].used & IL_STA_UCODE_INPROGRESS)) { 2282*7ac9a364SKalle Valo memcpy(&sta_cmd, &il->stations[i].sta, 2283*7ac9a364SKalle Valo sizeof(struct il_addsta_cmd)); 2284*7ac9a364SKalle Valo send_lq = false; 2285*7ac9a364SKalle Valo if (il->stations[i].lq) { 2286*7ac9a364SKalle Valo memcpy(&lq, il->stations[i].lq, 2287*7ac9a364SKalle Valo sizeof(struct il_link_quality_cmd)); 2288*7ac9a364SKalle Valo send_lq = true; 2289*7ac9a364SKalle Valo } 2290*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2291*7ac9a364SKalle Valo ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC); 2292*7ac9a364SKalle Valo if (ret) { 2293*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2294*7ac9a364SKalle Valo IL_ERR("Adding station %pM failed.\n", 2295*7ac9a364SKalle Valo il->stations[i].sta.sta.addr); 2296*7ac9a364SKalle Valo il->stations[i].used &= ~IL_STA_DRIVER_ACTIVE; 2297*7ac9a364SKalle Valo il->stations[i].used &= 2298*7ac9a364SKalle Valo ~IL_STA_UCODE_INPROGRESS; 2299*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, 2300*7ac9a364SKalle Valo flags_spin); 2301*7ac9a364SKalle Valo } 2302*7ac9a364SKalle Valo /* 2303*7ac9a364SKalle Valo * Rate scaling has already been initialized, send 2304*7ac9a364SKalle Valo * current LQ command 2305*7ac9a364SKalle Valo */ 2306*7ac9a364SKalle Valo if (send_lq) 2307*7ac9a364SKalle Valo il_send_lq_cmd(il, &lq, CMD_SYNC, true); 2308*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2309*7ac9a364SKalle Valo il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS; 2310*7ac9a364SKalle Valo } 2311*7ac9a364SKalle Valo } 2312*7ac9a364SKalle Valo 2313*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2314*7ac9a364SKalle Valo if (!found) 2315*7ac9a364SKalle Valo D_INFO("Restoring all known stations" 2316*7ac9a364SKalle Valo " .... no stations to be restored.\n"); 2317*7ac9a364SKalle Valo else 2318*7ac9a364SKalle Valo D_INFO("Restoring all known stations" " .... complete.\n"); 2319*7ac9a364SKalle Valo } 2320*7ac9a364SKalle Valo EXPORT_SYMBOL(il_restore_stations); 2321*7ac9a364SKalle Valo 2322*7ac9a364SKalle Valo int 2323*7ac9a364SKalle Valo il_get_free_ucode_key_idx(struct il_priv *il) 2324*7ac9a364SKalle Valo { 2325*7ac9a364SKalle Valo int i; 2326*7ac9a364SKalle Valo 2327*7ac9a364SKalle Valo for (i = 0; i < il->sta_key_max_num; i++) 2328*7ac9a364SKalle Valo if (!test_and_set_bit(i, &il->ucode_key_table)) 2329*7ac9a364SKalle Valo return i; 2330*7ac9a364SKalle Valo 2331*7ac9a364SKalle Valo return WEP_INVALID_OFFSET; 2332*7ac9a364SKalle Valo } 2333*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_free_ucode_key_idx); 2334*7ac9a364SKalle Valo 2335*7ac9a364SKalle Valo void 2336*7ac9a364SKalle Valo il_dealloc_bcast_stations(struct il_priv *il) 2337*7ac9a364SKalle Valo { 2338*7ac9a364SKalle Valo unsigned long flags; 2339*7ac9a364SKalle Valo int i; 2340*7ac9a364SKalle Valo 2341*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags); 2342*7ac9a364SKalle Valo for (i = 0; i < il->hw_params.max_stations; i++) { 2343*7ac9a364SKalle Valo if (!(il->stations[i].used & IL_STA_BCAST)) 2344*7ac9a364SKalle Valo continue; 2345*7ac9a364SKalle Valo 2346*7ac9a364SKalle Valo il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; 2347*7ac9a364SKalle Valo il->num_stations--; 2348*7ac9a364SKalle Valo BUG_ON(il->num_stations < 0); 2349*7ac9a364SKalle Valo kfree(il->stations[i].lq); 2350*7ac9a364SKalle Valo il->stations[i].lq = NULL; 2351*7ac9a364SKalle Valo } 2352*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags); 2353*7ac9a364SKalle Valo } 2354*7ac9a364SKalle Valo EXPORT_SYMBOL_GPL(il_dealloc_bcast_stations); 2355*7ac9a364SKalle Valo 2356*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 2357*7ac9a364SKalle Valo static void 2358*7ac9a364SKalle Valo il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq) 2359*7ac9a364SKalle Valo { 2360*7ac9a364SKalle Valo int i; 2361*7ac9a364SKalle Valo D_RATE("lq station id 0x%x\n", lq->sta_id); 2362*7ac9a364SKalle Valo D_RATE("lq ant 0x%X 0x%X\n", lq->general_params.single_stream_ant_msk, 2363*7ac9a364SKalle Valo lq->general_params.dual_stream_ant_msk); 2364*7ac9a364SKalle Valo 2365*7ac9a364SKalle Valo for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) 2366*7ac9a364SKalle Valo D_RATE("lq idx %d 0x%X\n", i, lq->rs_table[i].rate_n_flags); 2367*7ac9a364SKalle Valo } 2368*7ac9a364SKalle Valo #else 2369*7ac9a364SKalle Valo static inline void 2370*7ac9a364SKalle Valo il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq) 2371*7ac9a364SKalle Valo { 2372*7ac9a364SKalle Valo } 2373*7ac9a364SKalle Valo #endif 2374*7ac9a364SKalle Valo 2375*7ac9a364SKalle Valo /** 2376*7ac9a364SKalle Valo * il_is_lq_table_valid() - Test one aspect of LQ cmd for validity 2377*7ac9a364SKalle Valo * 2378*7ac9a364SKalle Valo * It sometimes happens when a HT rate has been in use and we 2379*7ac9a364SKalle Valo * loose connectivity with AP then mac80211 will first tell us that the 2380*7ac9a364SKalle Valo * current channel is not HT anymore before removing the station. In such a 2381*7ac9a364SKalle Valo * scenario the RXON flags will be updated to indicate we are not 2382*7ac9a364SKalle Valo * communicating HT anymore, but the LQ command may still contain HT rates. 2383*7ac9a364SKalle Valo * Test for this to prevent driver from sending LQ command between the time 2384*7ac9a364SKalle Valo * RXON flags are updated and when LQ command is updated. 2385*7ac9a364SKalle Valo */ 2386*7ac9a364SKalle Valo static bool 2387*7ac9a364SKalle Valo il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq) 2388*7ac9a364SKalle Valo { 2389*7ac9a364SKalle Valo int i; 2390*7ac9a364SKalle Valo 2391*7ac9a364SKalle Valo if (il->ht.enabled) 2392*7ac9a364SKalle Valo return true; 2393*7ac9a364SKalle Valo 2394*7ac9a364SKalle Valo D_INFO("Channel %u is not an HT channel\n", il->active.channel); 2395*7ac9a364SKalle Valo for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 2396*7ac9a364SKalle Valo if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { 2397*7ac9a364SKalle Valo D_INFO("idx %d of LQ expects HT channel\n", i); 2398*7ac9a364SKalle Valo return false; 2399*7ac9a364SKalle Valo } 2400*7ac9a364SKalle Valo } 2401*7ac9a364SKalle Valo return true; 2402*7ac9a364SKalle Valo } 2403*7ac9a364SKalle Valo 2404*7ac9a364SKalle Valo /** 2405*7ac9a364SKalle Valo * il_send_lq_cmd() - Send link quality command 2406*7ac9a364SKalle Valo * @init: This command is sent as part of station initialization right 2407*7ac9a364SKalle Valo * after station has been added. 2408*7ac9a364SKalle Valo * 2409*7ac9a364SKalle Valo * The link quality command is sent as the last step of station creation. 2410*7ac9a364SKalle Valo * This is the special case in which init is set and we call a callback in 2411*7ac9a364SKalle Valo * this case to clear the state indicating that station creation is in 2412*7ac9a364SKalle Valo * progress. 2413*7ac9a364SKalle Valo */ 2414*7ac9a364SKalle Valo int 2415*7ac9a364SKalle Valo il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq, 2416*7ac9a364SKalle Valo u8 flags, bool init) 2417*7ac9a364SKalle Valo { 2418*7ac9a364SKalle Valo int ret = 0; 2419*7ac9a364SKalle Valo unsigned long flags_spin; 2420*7ac9a364SKalle Valo 2421*7ac9a364SKalle Valo struct il_host_cmd cmd = { 2422*7ac9a364SKalle Valo .id = C_TX_LINK_QUALITY_CMD, 2423*7ac9a364SKalle Valo .len = sizeof(struct il_link_quality_cmd), 2424*7ac9a364SKalle Valo .flags = flags, 2425*7ac9a364SKalle Valo .data = lq, 2426*7ac9a364SKalle Valo }; 2427*7ac9a364SKalle Valo 2428*7ac9a364SKalle Valo if (WARN_ON(lq->sta_id == IL_INVALID_STATION)) 2429*7ac9a364SKalle Valo return -EINVAL; 2430*7ac9a364SKalle Valo 2431*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2432*7ac9a364SKalle Valo if (!(il->stations[lq->sta_id].used & IL_STA_DRIVER_ACTIVE)) { 2433*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2434*7ac9a364SKalle Valo return -EINVAL; 2435*7ac9a364SKalle Valo } 2436*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2437*7ac9a364SKalle Valo 2438*7ac9a364SKalle Valo il_dump_lq_cmd(il, lq); 2439*7ac9a364SKalle Valo BUG_ON(init && (cmd.flags & CMD_ASYNC)); 2440*7ac9a364SKalle Valo 2441*7ac9a364SKalle Valo if (il_is_lq_table_valid(il, lq)) 2442*7ac9a364SKalle Valo ret = il_send_cmd(il, &cmd); 2443*7ac9a364SKalle Valo else 2444*7ac9a364SKalle Valo ret = -EINVAL; 2445*7ac9a364SKalle Valo 2446*7ac9a364SKalle Valo if (cmd.flags & CMD_ASYNC) 2447*7ac9a364SKalle Valo return ret; 2448*7ac9a364SKalle Valo 2449*7ac9a364SKalle Valo if (init) { 2450*7ac9a364SKalle Valo D_INFO("init LQ command complete," 2451*7ac9a364SKalle Valo " clearing sta addition status for sta %d\n", 2452*7ac9a364SKalle Valo lq->sta_id); 2453*7ac9a364SKalle Valo spin_lock_irqsave(&il->sta_lock, flags_spin); 2454*7ac9a364SKalle Valo il->stations[lq->sta_id].used &= ~IL_STA_UCODE_INPROGRESS; 2455*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->sta_lock, flags_spin); 2456*7ac9a364SKalle Valo } 2457*7ac9a364SKalle Valo return ret; 2458*7ac9a364SKalle Valo } 2459*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_lq_cmd); 2460*7ac9a364SKalle Valo 2461*7ac9a364SKalle Valo int 2462*7ac9a364SKalle Valo il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2463*7ac9a364SKalle Valo struct ieee80211_sta *sta) 2464*7ac9a364SKalle Valo { 2465*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 2466*7ac9a364SKalle Valo struct il_station_priv_common *sta_common = (void *)sta->drv_priv; 2467*7ac9a364SKalle Valo int ret; 2468*7ac9a364SKalle Valo 2469*7ac9a364SKalle Valo mutex_lock(&il->mutex); 2470*7ac9a364SKalle Valo D_MAC80211("enter station %pM\n", sta->addr); 2471*7ac9a364SKalle Valo 2472*7ac9a364SKalle Valo ret = il_remove_station(il, sta_common->sta_id, sta->addr); 2473*7ac9a364SKalle Valo if (ret) 2474*7ac9a364SKalle Valo IL_ERR("Error removing station %pM\n", sta->addr); 2475*7ac9a364SKalle Valo 2476*7ac9a364SKalle Valo D_MAC80211("leave ret %d\n", ret); 2477*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 2478*7ac9a364SKalle Valo 2479*7ac9a364SKalle Valo return ret; 2480*7ac9a364SKalle Valo } 2481*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_sta_remove); 2482*7ac9a364SKalle Valo 2483*7ac9a364SKalle Valo /************************** RX-FUNCTIONS ****************************/ 2484*7ac9a364SKalle Valo /* 2485*7ac9a364SKalle Valo * Rx theory of operation 2486*7ac9a364SKalle Valo * 2487*7ac9a364SKalle Valo * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), 2488*7ac9a364SKalle Valo * each of which point to Receive Buffers to be filled by the NIC. These get 2489*7ac9a364SKalle Valo * used not only for Rx frames, but for any command response or notification 2490*7ac9a364SKalle Valo * from the NIC. The driver and NIC manage the Rx buffers by means 2491*7ac9a364SKalle Valo * of idxes into the circular buffer. 2492*7ac9a364SKalle Valo * 2493*7ac9a364SKalle Valo * Rx Queue Indexes 2494*7ac9a364SKalle Valo * The host/firmware share two idx registers for managing the Rx buffers. 2495*7ac9a364SKalle Valo * 2496*7ac9a364SKalle Valo * The READ idx maps to the first position that the firmware may be writing 2497*7ac9a364SKalle Valo * to -- the driver can read up to (but not including) this position and get 2498*7ac9a364SKalle Valo * good data. 2499*7ac9a364SKalle Valo * The READ idx is managed by the firmware once the card is enabled. 2500*7ac9a364SKalle Valo * 2501*7ac9a364SKalle Valo * The WRITE idx maps to the last position the driver has read from -- the 2502*7ac9a364SKalle Valo * position preceding WRITE is the last slot the firmware can place a packet. 2503*7ac9a364SKalle Valo * 2504*7ac9a364SKalle Valo * The queue is empty (no good data) if WRITE = READ - 1, and is full if 2505*7ac9a364SKalle Valo * WRITE = READ. 2506*7ac9a364SKalle Valo * 2507*7ac9a364SKalle Valo * During initialization, the host sets up the READ queue position to the first 2508*7ac9a364SKalle Valo * IDX position, and WRITE to the last (READ - 1 wrapped) 2509*7ac9a364SKalle Valo * 2510*7ac9a364SKalle Valo * When the firmware places a packet in a buffer, it will advance the READ idx 2511*7ac9a364SKalle Valo * and fire the RX interrupt. The driver can then query the READ idx and 2512*7ac9a364SKalle Valo * process as many packets as possible, moving the WRITE idx forward as it 2513*7ac9a364SKalle Valo * resets the Rx queue buffers with new memory. 2514*7ac9a364SKalle Valo * 2515*7ac9a364SKalle Valo * The management in the driver is as follows: 2516*7ac9a364SKalle Valo * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When 2517*7ac9a364SKalle Valo * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled 2518*7ac9a364SKalle Valo * to replenish the iwl->rxq->rx_free. 2519*7ac9a364SKalle Valo * + In il_rx_replenish (scheduled) if 'processed' != 'read' then the 2520*7ac9a364SKalle Valo * iwl->rxq is replenished and the READ IDX is updated (updating the 2521*7ac9a364SKalle Valo * 'processed' and 'read' driver idxes as well) 2522*7ac9a364SKalle Valo * + A received packet is processed and handed to the kernel network stack, 2523*7ac9a364SKalle Valo * detached from the iwl->rxq. The driver 'processed' idx is updated. 2524*7ac9a364SKalle Valo * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free 2525*7ac9a364SKalle Valo * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ 2526*7ac9a364SKalle Valo * IDX is not incremented and iwl->status(RX_STALLED) is set. If there 2527*7ac9a364SKalle Valo * were enough free buffers and RX_STALLED is set it is cleared. 2528*7ac9a364SKalle Valo * 2529*7ac9a364SKalle Valo * 2530*7ac9a364SKalle Valo * Driver sequence: 2531*7ac9a364SKalle Valo * 2532*7ac9a364SKalle Valo * il_rx_queue_alloc() Allocates rx_free 2533*7ac9a364SKalle Valo * il_rx_replenish() Replenishes rx_free list from rx_used, and calls 2534*7ac9a364SKalle Valo * il_rx_queue_restock 2535*7ac9a364SKalle Valo * il_rx_queue_restock() Moves available buffers from rx_free into Rx 2536*7ac9a364SKalle Valo * queue, updates firmware pointers, and updates 2537*7ac9a364SKalle Valo * the WRITE idx. If insufficient rx_free buffers 2538*7ac9a364SKalle Valo * are available, schedules il_rx_replenish 2539*7ac9a364SKalle Valo * 2540*7ac9a364SKalle Valo * -- enable interrupts -- 2541*7ac9a364SKalle Valo * ISR - il_rx() Detach il_rx_bufs from pool up to the 2542*7ac9a364SKalle Valo * READ IDX, detaching the SKB from the pool. 2543*7ac9a364SKalle Valo * Moves the packet buffer from queue to rx_used. 2544*7ac9a364SKalle Valo * Calls il_rx_queue_restock to refill any empty 2545*7ac9a364SKalle Valo * slots. 2546*7ac9a364SKalle Valo * ... 2547*7ac9a364SKalle Valo * 2548*7ac9a364SKalle Valo */ 2549*7ac9a364SKalle Valo 2550*7ac9a364SKalle Valo /** 2551*7ac9a364SKalle Valo * il_rx_queue_space - Return number of free slots available in queue. 2552*7ac9a364SKalle Valo */ 2553*7ac9a364SKalle Valo int 2554*7ac9a364SKalle Valo il_rx_queue_space(const struct il_rx_queue *q) 2555*7ac9a364SKalle Valo { 2556*7ac9a364SKalle Valo int s = q->read - q->write; 2557*7ac9a364SKalle Valo if (s <= 0) 2558*7ac9a364SKalle Valo s += RX_QUEUE_SIZE; 2559*7ac9a364SKalle Valo /* keep some buffer to not confuse full and empty queue */ 2560*7ac9a364SKalle Valo s -= 2; 2561*7ac9a364SKalle Valo if (s < 0) 2562*7ac9a364SKalle Valo s = 0; 2563*7ac9a364SKalle Valo return s; 2564*7ac9a364SKalle Valo } 2565*7ac9a364SKalle Valo EXPORT_SYMBOL(il_rx_queue_space); 2566*7ac9a364SKalle Valo 2567*7ac9a364SKalle Valo /** 2568*7ac9a364SKalle Valo * il_rx_queue_update_write_ptr - Update the write pointer for the RX queue 2569*7ac9a364SKalle Valo */ 2570*7ac9a364SKalle Valo void 2571*7ac9a364SKalle Valo il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q) 2572*7ac9a364SKalle Valo { 2573*7ac9a364SKalle Valo unsigned long flags; 2574*7ac9a364SKalle Valo u32 rx_wrt_ptr_reg = il->hw_params.rx_wrt_ptr_reg; 2575*7ac9a364SKalle Valo u32 reg; 2576*7ac9a364SKalle Valo 2577*7ac9a364SKalle Valo spin_lock_irqsave(&q->lock, flags); 2578*7ac9a364SKalle Valo 2579*7ac9a364SKalle Valo if (q->need_update == 0) 2580*7ac9a364SKalle Valo goto exit_unlock; 2581*7ac9a364SKalle Valo 2582*7ac9a364SKalle Valo /* If power-saving is in use, make sure device is awake */ 2583*7ac9a364SKalle Valo if (test_bit(S_POWER_PMI, &il->status)) { 2584*7ac9a364SKalle Valo reg = _il_rd(il, CSR_UCODE_DRV_GP1); 2585*7ac9a364SKalle Valo 2586*7ac9a364SKalle Valo if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 2587*7ac9a364SKalle Valo D_INFO("Rx queue requesting wakeup," " GP1 = 0x%x\n", 2588*7ac9a364SKalle Valo reg); 2589*7ac9a364SKalle Valo il_set_bit(il, CSR_GP_CNTRL, 2590*7ac9a364SKalle Valo CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2591*7ac9a364SKalle Valo goto exit_unlock; 2592*7ac9a364SKalle Valo } 2593*7ac9a364SKalle Valo 2594*7ac9a364SKalle Valo q->write_actual = (q->write & ~0x7); 2595*7ac9a364SKalle Valo il_wr(il, rx_wrt_ptr_reg, q->write_actual); 2596*7ac9a364SKalle Valo 2597*7ac9a364SKalle Valo /* Else device is assumed to be awake */ 2598*7ac9a364SKalle Valo } else { 2599*7ac9a364SKalle Valo /* Device expects a multiple of 8 */ 2600*7ac9a364SKalle Valo q->write_actual = (q->write & ~0x7); 2601*7ac9a364SKalle Valo il_wr(il, rx_wrt_ptr_reg, q->write_actual); 2602*7ac9a364SKalle Valo } 2603*7ac9a364SKalle Valo 2604*7ac9a364SKalle Valo q->need_update = 0; 2605*7ac9a364SKalle Valo 2606*7ac9a364SKalle Valo exit_unlock: 2607*7ac9a364SKalle Valo spin_unlock_irqrestore(&q->lock, flags); 2608*7ac9a364SKalle Valo } 2609*7ac9a364SKalle Valo EXPORT_SYMBOL(il_rx_queue_update_write_ptr); 2610*7ac9a364SKalle Valo 2611*7ac9a364SKalle Valo int 2612*7ac9a364SKalle Valo il_rx_queue_alloc(struct il_priv *il) 2613*7ac9a364SKalle Valo { 2614*7ac9a364SKalle Valo struct il_rx_queue *rxq = &il->rxq; 2615*7ac9a364SKalle Valo struct device *dev = &il->pci_dev->dev; 2616*7ac9a364SKalle Valo int i; 2617*7ac9a364SKalle Valo 2618*7ac9a364SKalle Valo spin_lock_init(&rxq->lock); 2619*7ac9a364SKalle Valo INIT_LIST_HEAD(&rxq->rx_free); 2620*7ac9a364SKalle Valo INIT_LIST_HEAD(&rxq->rx_used); 2621*7ac9a364SKalle Valo 2622*7ac9a364SKalle Valo /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ 2623*7ac9a364SKalle Valo rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, 2624*7ac9a364SKalle Valo GFP_KERNEL); 2625*7ac9a364SKalle Valo if (!rxq->bd) 2626*7ac9a364SKalle Valo goto err_bd; 2627*7ac9a364SKalle Valo 2628*7ac9a364SKalle Valo rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct il_rb_status), 2629*7ac9a364SKalle Valo &rxq->rb_stts_dma, GFP_KERNEL); 2630*7ac9a364SKalle Valo if (!rxq->rb_stts) 2631*7ac9a364SKalle Valo goto err_rb; 2632*7ac9a364SKalle Valo 2633*7ac9a364SKalle Valo /* Fill the rx_used queue with _all_ of the Rx buffers */ 2634*7ac9a364SKalle Valo for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) 2635*7ac9a364SKalle Valo list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 2636*7ac9a364SKalle Valo 2637*7ac9a364SKalle Valo /* Set us so that we have processed and used all buffers, but have 2638*7ac9a364SKalle Valo * not restocked the Rx queue with fresh buffers */ 2639*7ac9a364SKalle Valo rxq->read = rxq->write = 0; 2640*7ac9a364SKalle Valo rxq->write_actual = 0; 2641*7ac9a364SKalle Valo rxq->free_count = 0; 2642*7ac9a364SKalle Valo rxq->need_update = 0; 2643*7ac9a364SKalle Valo return 0; 2644*7ac9a364SKalle Valo 2645*7ac9a364SKalle Valo err_rb: 2646*7ac9a364SKalle Valo dma_free_coherent(&il->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, 2647*7ac9a364SKalle Valo rxq->bd_dma); 2648*7ac9a364SKalle Valo err_bd: 2649*7ac9a364SKalle Valo return -ENOMEM; 2650*7ac9a364SKalle Valo } 2651*7ac9a364SKalle Valo EXPORT_SYMBOL(il_rx_queue_alloc); 2652*7ac9a364SKalle Valo 2653*7ac9a364SKalle Valo void 2654*7ac9a364SKalle Valo il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb) 2655*7ac9a364SKalle Valo { 2656*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 2657*7ac9a364SKalle Valo struct il_spectrum_notification *report = &(pkt->u.spectrum_notif); 2658*7ac9a364SKalle Valo 2659*7ac9a364SKalle Valo if (!report->state) { 2660*7ac9a364SKalle Valo D_11H("Spectrum Measure Notification: Start\n"); 2661*7ac9a364SKalle Valo return; 2662*7ac9a364SKalle Valo } 2663*7ac9a364SKalle Valo 2664*7ac9a364SKalle Valo memcpy(&il->measure_report, report, sizeof(*report)); 2665*7ac9a364SKalle Valo il->measurement_status |= MEASUREMENT_READY; 2666*7ac9a364SKalle Valo } 2667*7ac9a364SKalle Valo EXPORT_SYMBOL(il_hdl_spectrum_measurement); 2668*7ac9a364SKalle Valo 2669*7ac9a364SKalle Valo /* 2670*7ac9a364SKalle Valo * returns non-zero if packet should be dropped 2671*7ac9a364SKalle Valo */ 2672*7ac9a364SKalle Valo int 2673*7ac9a364SKalle Valo il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr, 2674*7ac9a364SKalle Valo u32 decrypt_res, struct ieee80211_rx_status *stats) 2675*7ac9a364SKalle Valo { 2676*7ac9a364SKalle Valo u16 fc = le16_to_cpu(hdr->frame_control); 2677*7ac9a364SKalle Valo 2678*7ac9a364SKalle Valo /* 2679*7ac9a364SKalle Valo * All contexts have the same setting here due to it being 2680*7ac9a364SKalle Valo * a module parameter, so OK to check any context. 2681*7ac9a364SKalle Valo */ 2682*7ac9a364SKalle Valo if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) 2683*7ac9a364SKalle Valo return 0; 2684*7ac9a364SKalle Valo 2685*7ac9a364SKalle Valo if (!(fc & IEEE80211_FCTL_PROTECTED)) 2686*7ac9a364SKalle Valo return 0; 2687*7ac9a364SKalle Valo 2688*7ac9a364SKalle Valo D_RX("decrypt_res:0x%x\n", decrypt_res); 2689*7ac9a364SKalle Valo switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { 2690*7ac9a364SKalle Valo case RX_RES_STATUS_SEC_TYPE_TKIP: 2691*7ac9a364SKalle Valo /* The uCode has got a bad phase 1 Key, pushes the packet. 2692*7ac9a364SKalle Valo * Decryption will be done in SW. */ 2693*7ac9a364SKalle Valo if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 2694*7ac9a364SKalle Valo RX_RES_STATUS_BAD_KEY_TTAK) 2695*7ac9a364SKalle Valo break; 2696*7ac9a364SKalle Valo 2697*7ac9a364SKalle Valo case RX_RES_STATUS_SEC_TYPE_WEP: 2698*7ac9a364SKalle Valo if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 2699*7ac9a364SKalle Valo RX_RES_STATUS_BAD_ICV_MIC) { 2700*7ac9a364SKalle Valo /* bad ICV, the packet is destroyed since the 2701*7ac9a364SKalle Valo * decryption is inplace, drop it */ 2702*7ac9a364SKalle Valo D_RX("Packet destroyed\n"); 2703*7ac9a364SKalle Valo return -1; 2704*7ac9a364SKalle Valo } 2705*7ac9a364SKalle Valo case RX_RES_STATUS_SEC_TYPE_CCMP: 2706*7ac9a364SKalle Valo if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 2707*7ac9a364SKalle Valo RX_RES_STATUS_DECRYPT_OK) { 2708*7ac9a364SKalle Valo D_RX("hw decrypt successfully!!!\n"); 2709*7ac9a364SKalle Valo stats->flag |= RX_FLAG_DECRYPTED; 2710*7ac9a364SKalle Valo } 2711*7ac9a364SKalle Valo break; 2712*7ac9a364SKalle Valo 2713*7ac9a364SKalle Valo default: 2714*7ac9a364SKalle Valo break; 2715*7ac9a364SKalle Valo } 2716*7ac9a364SKalle Valo return 0; 2717*7ac9a364SKalle Valo } 2718*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_decrypted_flag); 2719*7ac9a364SKalle Valo 2720*7ac9a364SKalle Valo /** 2721*7ac9a364SKalle Valo * il_txq_update_write_ptr - Send new write idx to hardware 2722*7ac9a364SKalle Valo */ 2723*7ac9a364SKalle Valo void 2724*7ac9a364SKalle Valo il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq) 2725*7ac9a364SKalle Valo { 2726*7ac9a364SKalle Valo u32 reg = 0; 2727*7ac9a364SKalle Valo int txq_id = txq->q.id; 2728*7ac9a364SKalle Valo 2729*7ac9a364SKalle Valo if (txq->need_update == 0) 2730*7ac9a364SKalle Valo return; 2731*7ac9a364SKalle Valo 2732*7ac9a364SKalle Valo /* if we're trying to save power */ 2733*7ac9a364SKalle Valo if (test_bit(S_POWER_PMI, &il->status)) { 2734*7ac9a364SKalle Valo /* wake up nic if it's powered down ... 2735*7ac9a364SKalle Valo * uCode will wake up, and interrupt us again, so next 2736*7ac9a364SKalle Valo * time we'll skip this part. */ 2737*7ac9a364SKalle Valo reg = _il_rd(il, CSR_UCODE_DRV_GP1); 2738*7ac9a364SKalle Valo 2739*7ac9a364SKalle Valo if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 2740*7ac9a364SKalle Valo D_INFO("Tx queue %d requesting wakeup," " GP1 = 0x%x\n", 2741*7ac9a364SKalle Valo txq_id, reg); 2742*7ac9a364SKalle Valo il_set_bit(il, CSR_GP_CNTRL, 2743*7ac9a364SKalle Valo CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2744*7ac9a364SKalle Valo return; 2745*7ac9a364SKalle Valo } 2746*7ac9a364SKalle Valo 2747*7ac9a364SKalle Valo il_wr(il, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); 2748*7ac9a364SKalle Valo 2749*7ac9a364SKalle Valo /* 2750*7ac9a364SKalle Valo * else not in power-save mode, 2751*7ac9a364SKalle Valo * uCode will never sleep when we're 2752*7ac9a364SKalle Valo * trying to tx (during RFKILL, we're not trying to tx). 2753*7ac9a364SKalle Valo */ 2754*7ac9a364SKalle Valo } else 2755*7ac9a364SKalle Valo _il_wr(il, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); 2756*7ac9a364SKalle Valo txq->need_update = 0; 2757*7ac9a364SKalle Valo } 2758*7ac9a364SKalle Valo EXPORT_SYMBOL(il_txq_update_write_ptr); 2759*7ac9a364SKalle Valo 2760*7ac9a364SKalle Valo /** 2761*7ac9a364SKalle Valo * il_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's 2762*7ac9a364SKalle Valo */ 2763*7ac9a364SKalle Valo void 2764*7ac9a364SKalle Valo il_tx_queue_unmap(struct il_priv *il, int txq_id) 2765*7ac9a364SKalle Valo { 2766*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[txq_id]; 2767*7ac9a364SKalle Valo struct il_queue *q = &txq->q; 2768*7ac9a364SKalle Valo 2769*7ac9a364SKalle Valo if (q->n_bd == 0) 2770*7ac9a364SKalle Valo return; 2771*7ac9a364SKalle Valo 2772*7ac9a364SKalle Valo while (q->write_ptr != q->read_ptr) { 2773*7ac9a364SKalle Valo il->ops->txq_free_tfd(il, txq); 2774*7ac9a364SKalle Valo q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd); 2775*7ac9a364SKalle Valo } 2776*7ac9a364SKalle Valo } 2777*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_queue_unmap); 2778*7ac9a364SKalle Valo 2779*7ac9a364SKalle Valo /** 2780*7ac9a364SKalle Valo * il_tx_queue_free - Deallocate DMA queue. 2781*7ac9a364SKalle Valo * @txq: Transmit queue to deallocate. 2782*7ac9a364SKalle Valo * 2783*7ac9a364SKalle Valo * Empty queue by removing and destroying all BD's. 2784*7ac9a364SKalle Valo * Free all buffers. 2785*7ac9a364SKalle Valo * 0-fill, but do not free "txq" descriptor structure. 2786*7ac9a364SKalle Valo */ 2787*7ac9a364SKalle Valo void 2788*7ac9a364SKalle Valo il_tx_queue_free(struct il_priv *il, int txq_id) 2789*7ac9a364SKalle Valo { 2790*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[txq_id]; 2791*7ac9a364SKalle Valo struct device *dev = &il->pci_dev->dev; 2792*7ac9a364SKalle Valo int i; 2793*7ac9a364SKalle Valo 2794*7ac9a364SKalle Valo il_tx_queue_unmap(il, txq_id); 2795*7ac9a364SKalle Valo 2796*7ac9a364SKalle Valo /* De-alloc array of command/tx buffers */ 2797*7ac9a364SKalle Valo for (i = 0; i < TFD_TX_CMD_SLOTS; i++) 2798*7ac9a364SKalle Valo kfree(txq->cmd[i]); 2799*7ac9a364SKalle Valo 2800*7ac9a364SKalle Valo /* De-alloc circular buffer of TFDs */ 2801*7ac9a364SKalle Valo if (txq->q.n_bd) 2802*7ac9a364SKalle Valo dma_free_coherent(dev, il->hw_params.tfd_size * txq->q.n_bd, 2803*7ac9a364SKalle Valo txq->tfds, txq->q.dma_addr); 2804*7ac9a364SKalle Valo 2805*7ac9a364SKalle Valo /* De-alloc array of per-TFD driver data */ 2806*7ac9a364SKalle Valo kfree(txq->skbs); 2807*7ac9a364SKalle Valo txq->skbs = NULL; 2808*7ac9a364SKalle Valo 2809*7ac9a364SKalle Valo /* deallocate arrays */ 2810*7ac9a364SKalle Valo kfree(txq->cmd); 2811*7ac9a364SKalle Valo kfree(txq->meta); 2812*7ac9a364SKalle Valo txq->cmd = NULL; 2813*7ac9a364SKalle Valo txq->meta = NULL; 2814*7ac9a364SKalle Valo 2815*7ac9a364SKalle Valo /* 0-fill queue descriptor structure */ 2816*7ac9a364SKalle Valo memset(txq, 0, sizeof(*txq)); 2817*7ac9a364SKalle Valo } 2818*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_queue_free); 2819*7ac9a364SKalle Valo 2820*7ac9a364SKalle Valo /** 2821*7ac9a364SKalle Valo * il_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue 2822*7ac9a364SKalle Valo */ 2823*7ac9a364SKalle Valo void 2824*7ac9a364SKalle Valo il_cmd_queue_unmap(struct il_priv *il) 2825*7ac9a364SKalle Valo { 2826*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[il->cmd_queue]; 2827*7ac9a364SKalle Valo struct il_queue *q = &txq->q; 2828*7ac9a364SKalle Valo int i; 2829*7ac9a364SKalle Valo 2830*7ac9a364SKalle Valo if (q->n_bd == 0) 2831*7ac9a364SKalle Valo return; 2832*7ac9a364SKalle Valo 2833*7ac9a364SKalle Valo while (q->read_ptr != q->write_ptr) { 2834*7ac9a364SKalle Valo i = il_get_cmd_idx(q, q->read_ptr, 0); 2835*7ac9a364SKalle Valo 2836*7ac9a364SKalle Valo if (txq->meta[i].flags & CMD_MAPPED) { 2837*7ac9a364SKalle Valo pci_unmap_single(il->pci_dev, 2838*7ac9a364SKalle Valo dma_unmap_addr(&txq->meta[i], mapping), 2839*7ac9a364SKalle Valo dma_unmap_len(&txq->meta[i], len), 2840*7ac9a364SKalle Valo PCI_DMA_BIDIRECTIONAL); 2841*7ac9a364SKalle Valo txq->meta[i].flags = 0; 2842*7ac9a364SKalle Valo } 2843*7ac9a364SKalle Valo 2844*7ac9a364SKalle Valo q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd); 2845*7ac9a364SKalle Valo } 2846*7ac9a364SKalle Valo 2847*7ac9a364SKalle Valo i = q->n_win; 2848*7ac9a364SKalle Valo if (txq->meta[i].flags & CMD_MAPPED) { 2849*7ac9a364SKalle Valo pci_unmap_single(il->pci_dev, 2850*7ac9a364SKalle Valo dma_unmap_addr(&txq->meta[i], mapping), 2851*7ac9a364SKalle Valo dma_unmap_len(&txq->meta[i], len), 2852*7ac9a364SKalle Valo PCI_DMA_BIDIRECTIONAL); 2853*7ac9a364SKalle Valo txq->meta[i].flags = 0; 2854*7ac9a364SKalle Valo } 2855*7ac9a364SKalle Valo } 2856*7ac9a364SKalle Valo EXPORT_SYMBOL(il_cmd_queue_unmap); 2857*7ac9a364SKalle Valo 2858*7ac9a364SKalle Valo /** 2859*7ac9a364SKalle Valo * il_cmd_queue_free - Deallocate DMA queue. 2860*7ac9a364SKalle Valo * @txq: Transmit queue to deallocate. 2861*7ac9a364SKalle Valo * 2862*7ac9a364SKalle Valo * Empty queue by removing and destroying all BD's. 2863*7ac9a364SKalle Valo * Free all buffers. 2864*7ac9a364SKalle Valo * 0-fill, but do not free "txq" descriptor structure. 2865*7ac9a364SKalle Valo */ 2866*7ac9a364SKalle Valo void 2867*7ac9a364SKalle Valo il_cmd_queue_free(struct il_priv *il) 2868*7ac9a364SKalle Valo { 2869*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[il->cmd_queue]; 2870*7ac9a364SKalle Valo struct device *dev = &il->pci_dev->dev; 2871*7ac9a364SKalle Valo int i; 2872*7ac9a364SKalle Valo 2873*7ac9a364SKalle Valo il_cmd_queue_unmap(il); 2874*7ac9a364SKalle Valo 2875*7ac9a364SKalle Valo /* De-alloc array of command/tx buffers */ 2876*7ac9a364SKalle Valo for (i = 0; i <= TFD_CMD_SLOTS; i++) 2877*7ac9a364SKalle Valo kfree(txq->cmd[i]); 2878*7ac9a364SKalle Valo 2879*7ac9a364SKalle Valo /* De-alloc circular buffer of TFDs */ 2880*7ac9a364SKalle Valo if (txq->q.n_bd) 2881*7ac9a364SKalle Valo dma_free_coherent(dev, il->hw_params.tfd_size * txq->q.n_bd, 2882*7ac9a364SKalle Valo txq->tfds, txq->q.dma_addr); 2883*7ac9a364SKalle Valo 2884*7ac9a364SKalle Valo /* deallocate arrays */ 2885*7ac9a364SKalle Valo kfree(txq->cmd); 2886*7ac9a364SKalle Valo kfree(txq->meta); 2887*7ac9a364SKalle Valo txq->cmd = NULL; 2888*7ac9a364SKalle Valo txq->meta = NULL; 2889*7ac9a364SKalle Valo 2890*7ac9a364SKalle Valo /* 0-fill queue descriptor structure */ 2891*7ac9a364SKalle Valo memset(txq, 0, sizeof(*txq)); 2892*7ac9a364SKalle Valo } 2893*7ac9a364SKalle Valo EXPORT_SYMBOL(il_cmd_queue_free); 2894*7ac9a364SKalle Valo 2895*7ac9a364SKalle Valo /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 2896*7ac9a364SKalle Valo * DMA services 2897*7ac9a364SKalle Valo * 2898*7ac9a364SKalle Valo * Theory of operation 2899*7ac9a364SKalle Valo * 2900*7ac9a364SKalle Valo * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer 2901*7ac9a364SKalle Valo * of buffer descriptors, each of which points to one or more data buffers for 2902*7ac9a364SKalle Valo * the device to read from or fill. Driver and device exchange status of each 2903*7ac9a364SKalle Valo * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty 2904*7ac9a364SKalle Valo * entries in each circular buffer, to protect against confusing empty and full 2905*7ac9a364SKalle Valo * queue states. 2906*7ac9a364SKalle Valo * 2907*7ac9a364SKalle Valo * The device reads or writes the data in the queues via the device's several 2908*7ac9a364SKalle Valo * DMA/FIFO channels. Each queue is mapped to a single DMA channel. 2909*7ac9a364SKalle Valo * 2910*7ac9a364SKalle Valo * For Tx queue, there are low mark and high mark limits. If, after queuing 2911*7ac9a364SKalle Valo * the packet for Tx, free space become < low mark, Tx queue stopped. When 2912*7ac9a364SKalle Valo * reclaiming packets (on 'tx done IRQ), if free space become > high mark, 2913*7ac9a364SKalle Valo * Tx queue resumed. 2914*7ac9a364SKalle Valo * 2915*7ac9a364SKalle Valo * See more detailed info in 4965.h. 2916*7ac9a364SKalle Valo ***************************************************/ 2917*7ac9a364SKalle Valo 2918*7ac9a364SKalle Valo int 2919*7ac9a364SKalle Valo il_queue_space(const struct il_queue *q) 2920*7ac9a364SKalle Valo { 2921*7ac9a364SKalle Valo int s = q->read_ptr - q->write_ptr; 2922*7ac9a364SKalle Valo 2923*7ac9a364SKalle Valo if (q->read_ptr > q->write_ptr) 2924*7ac9a364SKalle Valo s -= q->n_bd; 2925*7ac9a364SKalle Valo 2926*7ac9a364SKalle Valo if (s <= 0) 2927*7ac9a364SKalle Valo s += q->n_win; 2928*7ac9a364SKalle Valo /* keep some reserve to not confuse empty and full situations */ 2929*7ac9a364SKalle Valo s -= 2; 2930*7ac9a364SKalle Valo if (s < 0) 2931*7ac9a364SKalle Valo s = 0; 2932*7ac9a364SKalle Valo return s; 2933*7ac9a364SKalle Valo } 2934*7ac9a364SKalle Valo EXPORT_SYMBOL(il_queue_space); 2935*7ac9a364SKalle Valo 2936*7ac9a364SKalle Valo 2937*7ac9a364SKalle Valo /** 2938*7ac9a364SKalle Valo * il_queue_init - Initialize queue's high/low-water and read/write idxes 2939*7ac9a364SKalle Valo */ 2940*7ac9a364SKalle Valo static int 2941*7ac9a364SKalle Valo il_queue_init(struct il_priv *il, struct il_queue *q, int slots, u32 id) 2942*7ac9a364SKalle Valo { 2943*7ac9a364SKalle Valo /* 2944*7ac9a364SKalle Valo * TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise 2945*7ac9a364SKalle Valo * il_queue_inc_wrap and il_queue_dec_wrap are broken. 2946*7ac9a364SKalle Valo */ 2947*7ac9a364SKalle Valo BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); 2948*7ac9a364SKalle Valo /* FIXME: remove q->n_bd */ 2949*7ac9a364SKalle Valo q->n_bd = TFD_QUEUE_SIZE_MAX; 2950*7ac9a364SKalle Valo 2951*7ac9a364SKalle Valo q->n_win = slots; 2952*7ac9a364SKalle Valo q->id = id; 2953*7ac9a364SKalle Valo 2954*7ac9a364SKalle Valo /* slots_must be power-of-two size, otherwise 2955*7ac9a364SKalle Valo * il_get_cmd_idx is broken. */ 2956*7ac9a364SKalle Valo BUG_ON(!is_power_of_2(slots)); 2957*7ac9a364SKalle Valo 2958*7ac9a364SKalle Valo q->low_mark = q->n_win / 4; 2959*7ac9a364SKalle Valo if (q->low_mark < 4) 2960*7ac9a364SKalle Valo q->low_mark = 4; 2961*7ac9a364SKalle Valo 2962*7ac9a364SKalle Valo q->high_mark = q->n_win / 8; 2963*7ac9a364SKalle Valo if (q->high_mark < 2) 2964*7ac9a364SKalle Valo q->high_mark = 2; 2965*7ac9a364SKalle Valo 2966*7ac9a364SKalle Valo q->write_ptr = q->read_ptr = 0; 2967*7ac9a364SKalle Valo 2968*7ac9a364SKalle Valo return 0; 2969*7ac9a364SKalle Valo } 2970*7ac9a364SKalle Valo 2971*7ac9a364SKalle Valo /** 2972*7ac9a364SKalle Valo * il_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue 2973*7ac9a364SKalle Valo */ 2974*7ac9a364SKalle Valo static int 2975*7ac9a364SKalle Valo il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) 2976*7ac9a364SKalle Valo { 2977*7ac9a364SKalle Valo struct device *dev = &il->pci_dev->dev; 2978*7ac9a364SKalle Valo size_t tfd_sz = il->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; 2979*7ac9a364SKalle Valo 2980*7ac9a364SKalle Valo /* Driver ilate data, only for Tx (not command) queues, 2981*7ac9a364SKalle Valo * not shared with device. */ 2982*7ac9a364SKalle Valo if (id != il->cmd_queue) { 2983*7ac9a364SKalle Valo txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, 2984*7ac9a364SKalle Valo sizeof(struct sk_buff *), 2985*7ac9a364SKalle Valo GFP_KERNEL); 2986*7ac9a364SKalle Valo if (!txq->skbs) { 2987*7ac9a364SKalle Valo IL_ERR("Fail to alloc skbs\n"); 2988*7ac9a364SKalle Valo goto error; 2989*7ac9a364SKalle Valo } 2990*7ac9a364SKalle Valo } else 2991*7ac9a364SKalle Valo txq->skbs = NULL; 2992*7ac9a364SKalle Valo 2993*7ac9a364SKalle Valo /* Circular buffer of transmit frame descriptors (TFDs), 2994*7ac9a364SKalle Valo * shared with device */ 2995*7ac9a364SKalle Valo txq->tfds = 2996*7ac9a364SKalle Valo dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); 2997*7ac9a364SKalle Valo if (!txq->tfds) 2998*7ac9a364SKalle Valo goto error; 2999*7ac9a364SKalle Valo 3000*7ac9a364SKalle Valo txq->q.id = id; 3001*7ac9a364SKalle Valo 3002*7ac9a364SKalle Valo return 0; 3003*7ac9a364SKalle Valo 3004*7ac9a364SKalle Valo error: 3005*7ac9a364SKalle Valo kfree(txq->skbs); 3006*7ac9a364SKalle Valo txq->skbs = NULL; 3007*7ac9a364SKalle Valo 3008*7ac9a364SKalle Valo return -ENOMEM; 3009*7ac9a364SKalle Valo } 3010*7ac9a364SKalle Valo 3011*7ac9a364SKalle Valo /** 3012*7ac9a364SKalle Valo * il_tx_queue_init - Allocate and initialize one tx/cmd queue 3013*7ac9a364SKalle Valo */ 3014*7ac9a364SKalle Valo int 3015*7ac9a364SKalle Valo il_tx_queue_init(struct il_priv *il, u32 txq_id) 3016*7ac9a364SKalle Valo { 3017*7ac9a364SKalle Valo int i, len, ret; 3018*7ac9a364SKalle Valo int slots, actual_slots; 3019*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[txq_id]; 3020*7ac9a364SKalle Valo 3021*7ac9a364SKalle Valo /* 3022*7ac9a364SKalle Valo * Alloc buffer array for commands (Tx or other types of commands). 3023*7ac9a364SKalle Valo * For the command queue (#4/#9), allocate command space + one big 3024*7ac9a364SKalle Valo * command for scan, since scan command is very huge; the system will 3025*7ac9a364SKalle Valo * not have two scans at the same time, so only one is needed. 3026*7ac9a364SKalle Valo * For normal Tx queues (all other queues), no super-size command 3027*7ac9a364SKalle Valo * space is needed. 3028*7ac9a364SKalle Valo */ 3029*7ac9a364SKalle Valo if (txq_id == il->cmd_queue) { 3030*7ac9a364SKalle Valo slots = TFD_CMD_SLOTS; 3031*7ac9a364SKalle Valo actual_slots = slots + 1; 3032*7ac9a364SKalle Valo } else { 3033*7ac9a364SKalle Valo slots = TFD_TX_CMD_SLOTS; 3034*7ac9a364SKalle Valo actual_slots = slots; 3035*7ac9a364SKalle Valo } 3036*7ac9a364SKalle Valo 3037*7ac9a364SKalle Valo txq->meta = 3038*7ac9a364SKalle Valo kzalloc(sizeof(struct il_cmd_meta) * actual_slots, GFP_KERNEL); 3039*7ac9a364SKalle Valo txq->cmd = 3040*7ac9a364SKalle Valo kzalloc(sizeof(struct il_device_cmd *) * actual_slots, GFP_KERNEL); 3041*7ac9a364SKalle Valo 3042*7ac9a364SKalle Valo if (!txq->meta || !txq->cmd) 3043*7ac9a364SKalle Valo goto out_free_arrays; 3044*7ac9a364SKalle Valo 3045*7ac9a364SKalle Valo len = sizeof(struct il_device_cmd); 3046*7ac9a364SKalle Valo for (i = 0; i < actual_slots; i++) { 3047*7ac9a364SKalle Valo /* only happens for cmd queue */ 3048*7ac9a364SKalle Valo if (i == slots) 3049*7ac9a364SKalle Valo len = IL_MAX_CMD_SIZE; 3050*7ac9a364SKalle Valo 3051*7ac9a364SKalle Valo txq->cmd[i] = kmalloc(len, GFP_KERNEL); 3052*7ac9a364SKalle Valo if (!txq->cmd[i]) 3053*7ac9a364SKalle Valo goto err; 3054*7ac9a364SKalle Valo } 3055*7ac9a364SKalle Valo 3056*7ac9a364SKalle Valo /* Alloc driver data array and TFD circular buffer */ 3057*7ac9a364SKalle Valo ret = il_tx_queue_alloc(il, txq, txq_id); 3058*7ac9a364SKalle Valo if (ret) 3059*7ac9a364SKalle Valo goto err; 3060*7ac9a364SKalle Valo 3061*7ac9a364SKalle Valo txq->need_update = 0; 3062*7ac9a364SKalle Valo 3063*7ac9a364SKalle Valo /* 3064*7ac9a364SKalle Valo * For the default queues 0-3, set up the swq_id 3065*7ac9a364SKalle Valo * already -- all others need to get one later 3066*7ac9a364SKalle Valo * (if they need one at all). 3067*7ac9a364SKalle Valo */ 3068*7ac9a364SKalle Valo if (txq_id < 4) 3069*7ac9a364SKalle Valo il_set_swq_id(txq, txq_id, txq_id); 3070*7ac9a364SKalle Valo 3071*7ac9a364SKalle Valo /* Initialize queue's high/low-water marks, and head/tail idxes */ 3072*7ac9a364SKalle Valo il_queue_init(il, &txq->q, slots, txq_id); 3073*7ac9a364SKalle Valo 3074*7ac9a364SKalle Valo /* Tell device where to find queue */ 3075*7ac9a364SKalle Valo il->ops->txq_init(il, txq); 3076*7ac9a364SKalle Valo 3077*7ac9a364SKalle Valo return 0; 3078*7ac9a364SKalle Valo err: 3079*7ac9a364SKalle Valo for (i = 0; i < actual_slots; i++) 3080*7ac9a364SKalle Valo kfree(txq->cmd[i]); 3081*7ac9a364SKalle Valo out_free_arrays: 3082*7ac9a364SKalle Valo kfree(txq->meta); 3083*7ac9a364SKalle Valo kfree(txq->cmd); 3084*7ac9a364SKalle Valo 3085*7ac9a364SKalle Valo return -ENOMEM; 3086*7ac9a364SKalle Valo } 3087*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_queue_init); 3088*7ac9a364SKalle Valo 3089*7ac9a364SKalle Valo void 3090*7ac9a364SKalle Valo il_tx_queue_reset(struct il_priv *il, u32 txq_id) 3091*7ac9a364SKalle Valo { 3092*7ac9a364SKalle Valo int slots, actual_slots; 3093*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[txq_id]; 3094*7ac9a364SKalle Valo 3095*7ac9a364SKalle Valo if (txq_id == il->cmd_queue) { 3096*7ac9a364SKalle Valo slots = TFD_CMD_SLOTS; 3097*7ac9a364SKalle Valo actual_slots = TFD_CMD_SLOTS + 1; 3098*7ac9a364SKalle Valo } else { 3099*7ac9a364SKalle Valo slots = TFD_TX_CMD_SLOTS; 3100*7ac9a364SKalle Valo actual_slots = TFD_TX_CMD_SLOTS; 3101*7ac9a364SKalle Valo } 3102*7ac9a364SKalle Valo 3103*7ac9a364SKalle Valo memset(txq->meta, 0, sizeof(struct il_cmd_meta) * actual_slots); 3104*7ac9a364SKalle Valo txq->need_update = 0; 3105*7ac9a364SKalle Valo 3106*7ac9a364SKalle Valo /* Initialize queue's high/low-water marks, and head/tail idxes */ 3107*7ac9a364SKalle Valo il_queue_init(il, &txq->q, slots, txq_id); 3108*7ac9a364SKalle Valo 3109*7ac9a364SKalle Valo /* Tell device where to find queue */ 3110*7ac9a364SKalle Valo il->ops->txq_init(il, txq); 3111*7ac9a364SKalle Valo } 3112*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_queue_reset); 3113*7ac9a364SKalle Valo 3114*7ac9a364SKalle Valo /*************** HOST COMMAND QUEUE FUNCTIONS *****/ 3115*7ac9a364SKalle Valo 3116*7ac9a364SKalle Valo /** 3117*7ac9a364SKalle Valo * il_enqueue_hcmd - enqueue a uCode command 3118*7ac9a364SKalle Valo * @il: device ilate data point 3119*7ac9a364SKalle Valo * @cmd: a point to the ucode command structure 3120*7ac9a364SKalle Valo * 3121*7ac9a364SKalle Valo * The function returns < 0 values to indicate the operation is 3122*7ac9a364SKalle Valo * failed. On success, it turns the idx (> 0) of command in the 3123*7ac9a364SKalle Valo * command queue. 3124*7ac9a364SKalle Valo */ 3125*7ac9a364SKalle Valo int 3126*7ac9a364SKalle Valo il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) 3127*7ac9a364SKalle Valo { 3128*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[il->cmd_queue]; 3129*7ac9a364SKalle Valo struct il_queue *q = &txq->q; 3130*7ac9a364SKalle Valo struct il_device_cmd *out_cmd; 3131*7ac9a364SKalle Valo struct il_cmd_meta *out_meta; 3132*7ac9a364SKalle Valo dma_addr_t phys_addr; 3133*7ac9a364SKalle Valo unsigned long flags; 3134*7ac9a364SKalle Valo int len; 3135*7ac9a364SKalle Valo u32 idx; 3136*7ac9a364SKalle Valo u16 fix_size; 3137*7ac9a364SKalle Valo 3138*7ac9a364SKalle Valo cmd->len = il->ops->get_hcmd_size(cmd->id, cmd->len); 3139*7ac9a364SKalle Valo fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr)); 3140*7ac9a364SKalle Valo 3141*7ac9a364SKalle Valo /* If any of the command structures end up being larger than 3142*7ac9a364SKalle Valo * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then 3143*7ac9a364SKalle Valo * we will need to increase the size of the TFD entries 3144*7ac9a364SKalle Valo * Also, check to see if command buffer should not exceed the size 3145*7ac9a364SKalle Valo * of device_cmd and max_cmd_size. */ 3146*7ac9a364SKalle Valo BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && 3147*7ac9a364SKalle Valo !(cmd->flags & CMD_SIZE_HUGE)); 3148*7ac9a364SKalle Valo BUG_ON(fix_size > IL_MAX_CMD_SIZE); 3149*7ac9a364SKalle Valo 3150*7ac9a364SKalle Valo if (il_is_rfkill(il) || il_is_ctkill(il)) { 3151*7ac9a364SKalle Valo IL_WARN("Not sending command - %s KILL\n", 3152*7ac9a364SKalle Valo il_is_rfkill(il) ? "RF" : "CT"); 3153*7ac9a364SKalle Valo return -EIO; 3154*7ac9a364SKalle Valo } 3155*7ac9a364SKalle Valo 3156*7ac9a364SKalle Valo spin_lock_irqsave(&il->hcmd_lock, flags); 3157*7ac9a364SKalle Valo 3158*7ac9a364SKalle Valo if (il_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { 3159*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->hcmd_lock, flags); 3160*7ac9a364SKalle Valo 3161*7ac9a364SKalle Valo IL_ERR("Restarting adapter due to command queue full\n"); 3162*7ac9a364SKalle Valo queue_work(il->workqueue, &il->restart); 3163*7ac9a364SKalle Valo return -ENOSPC; 3164*7ac9a364SKalle Valo } 3165*7ac9a364SKalle Valo 3166*7ac9a364SKalle Valo idx = il_get_cmd_idx(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 3167*7ac9a364SKalle Valo out_cmd = txq->cmd[idx]; 3168*7ac9a364SKalle Valo out_meta = &txq->meta[idx]; 3169*7ac9a364SKalle Valo 3170*7ac9a364SKalle Valo if (WARN_ON(out_meta->flags & CMD_MAPPED)) { 3171*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->hcmd_lock, flags); 3172*7ac9a364SKalle Valo return -ENOSPC; 3173*7ac9a364SKalle Valo } 3174*7ac9a364SKalle Valo 3175*7ac9a364SKalle Valo memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ 3176*7ac9a364SKalle Valo out_meta->flags = cmd->flags | CMD_MAPPED; 3177*7ac9a364SKalle Valo if (cmd->flags & CMD_WANT_SKB) 3178*7ac9a364SKalle Valo out_meta->source = cmd; 3179*7ac9a364SKalle Valo if (cmd->flags & CMD_ASYNC) 3180*7ac9a364SKalle Valo out_meta->callback = cmd->callback; 3181*7ac9a364SKalle Valo 3182*7ac9a364SKalle Valo out_cmd->hdr.cmd = cmd->id; 3183*7ac9a364SKalle Valo memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); 3184*7ac9a364SKalle Valo 3185*7ac9a364SKalle Valo /* At this point, the out_cmd now has all of the incoming cmd 3186*7ac9a364SKalle Valo * information */ 3187*7ac9a364SKalle Valo 3188*7ac9a364SKalle Valo out_cmd->hdr.flags = 0; 3189*7ac9a364SKalle Valo out_cmd->hdr.sequence = 3190*7ac9a364SKalle Valo cpu_to_le16(QUEUE_TO_SEQ(il->cmd_queue) | IDX_TO_SEQ(q->write_ptr)); 3191*7ac9a364SKalle Valo if (cmd->flags & CMD_SIZE_HUGE) 3192*7ac9a364SKalle Valo out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 3193*7ac9a364SKalle Valo len = sizeof(struct il_device_cmd); 3194*7ac9a364SKalle Valo if (idx == TFD_CMD_SLOTS) 3195*7ac9a364SKalle Valo len = IL_MAX_CMD_SIZE; 3196*7ac9a364SKalle Valo 3197*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 3198*7ac9a364SKalle Valo switch (out_cmd->hdr.cmd) { 3199*7ac9a364SKalle Valo case C_TX_LINK_QUALITY_CMD: 3200*7ac9a364SKalle Valo case C_SENSITIVITY: 3201*7ac9a364SKalle Valo D_HC_DUMP("Sending command %s (#%x), seq: 0x%04X, " 3202*7ac9a364SKalle Valo "%d bytes at %d[%d]:%d\n", 3203*7ac9a364SKalle Valo il_get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, 3204*7ac9a364SKalle Valo le16_to_cpu(out_cmd->hdr.sequence), fix_size, 3205*7ac9a364SKalle Valo q->write_ptr, idx, il->cmd_queue); 3206*7ac9a364SKalle Valo break; 3207*7ac9a364SKalle Valo default: 3208*7ac9a364SKalle Valo D_HC("Sending command %s (#%x), seq: 0x%04X, " 3209*7ac9a364SKalle Valo "%d bytes at %d[%d]:%d\n", 3210*7ac9a364SKalle Valo il_get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, 3211*7ac9a364SKalle Valo le16_to_cpu(out_cmd->hdr.sequence), fix_size, q->write_ptr, 3212*7ac9a364SKalle Valo idx, il->cmd_queue); 3213*7ac9a364SKalle Valo } 3214*7ac9a364SKalle Valo #endif 3215*7ac9a364SKalle Valo 3216*7ac9a364SKalle Valo phys_addr = 3217*7ac9a364SKalle Valo pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, 3218*7ac9a364SKalle Valo PCI_DMA_BIDIRECTIONAL); 3219*7ac9a364SKalle Valo if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) { 3220*7ac9a364SKalle Valo idx = -ENOMEM; 3221*7ac9a364SKalle Valo goto out; 3222*7ac9a364SKalle Valo } 3223*7ac9a364SKalle Valo dma_unmap_addr_set(out_meta, mapping, phys_addr); 3224*7ac9a364SKalle Valo dma_unmap_len_set(out_meta, len, fix_size); 3225*7ac9a364SKalle Valo 3226*7ac9a364SKalle Valo txq->need_update = 1; 3227*7ac9a364SKalle Valo 3228*7ac9a364SKalle Valo if (il->ops->txq_update_byte_cnt_tbl) 3229*7ac9a364SKalle Valo /* Set up entry in queue's byte count circular buffer */ 3230*7ac9a364SKalle Valo il->ops->txq_update_byte_cnt_tbl(il, txq, 0); 3231*7ac9a364SKalle Valo 3232*7ac9a364SKalle Valo il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1, 3233*7ac9a364SKalle Valo U32_PAD(cmd->len)); 3234*7ac9a364SKalle Valo 3235*7ac9a364SKalle Valo /* Increment and update queue's write idx */ 3236*7ac9a364SKalle Valo q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); 3237*7ac9a364SKalle Valo il_txq_update_write_ptr(il, txq); 3238*7ac9a364SKalle Valo 3239*7ac9a364SKalle Valo out: 3240*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->hcmd_lock, flags); 3241*7ac9a364SKalle Valo return idx; 3242*7ac9a364SKalle Valo } 3243*7ac9a364SKalle Valo 3244*7ac9a364SKalle Valo /** 3245*7ac9a364SKalle Valo * il_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd 3246*7ac9a364SKalle Valo * 3247*7ac9a364SKalle Valo * When FW advances 'R' idx, all entries between old and new 'R' idx 3248*7ac9a364SKalle Valo * need to be reclaimed. As result, some free space forms. If there is 3249*7ac9a364SKalle Valo * enough free space (> low mark), wake the stack that feeds us. 3250*7ac9a364SKalle Valo */ 3251*7ac9a364SKalle Valo static void 3252*7ac9a364SKalle Valo il_hcmd_queue_reclaim(struct il_priv *il, int txq_id, int idx, int cmd_idx) 3253*7ac9a364SKalle Valo { 3254*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[txq_id]; 3255*7ac9a364SKalle Valo struct il_queue *q = &txq->q; 3256*7ac9a364SKalle Valo int nfreed = 0; 3257*7ac9a364SKalle Valo 3258*7ac9a364SKalle Valo if (idx >= q->n_bd || il_queue_used(q, idx) == 0) { 3259*7ac9a364SKalle Valo IL_ERR("Read idx for DMA queue txq id (%d), idx %d, " 3260*7ac9a364SKalle Valo "is out of range [0-%d] %d %d.\n", txq_id, idx, q->n_bd, 3261*7ac9a364SKalle Valo q->write_ptr, q->read_ptr); 3262*7ac9a364SKalle Valo return; 3263*7ac9a364SKalle Valo } 3264*7ac9a364SKalle Valo 3265*7ac9a364SKalle Valo for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; 3266*7ac9a364SKalle Valo q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) { 3267*7ac9a364SKalle Valo 3268*7ac9a364SKalle Valo if (nfreed++ > 0) { 3269*7ac9a364SKalle Valo IL_ERR("HCMD skipped: idx (%d) %d %d\n", idx, 3270*7ac9a364SKalle Valo q->write_ptr, q->read_ptr); 3271*7ac9a364SKalle Valo queue_work(il->workqueue, &il->restart); 3272*7ac9a364SKalle Valo } 3273*7ac9a364SKalle Valo 3274*7ac9a364SKalle Valo } 3275*7ac9a364SKalle Valo } 3276*7ac9a364SKalle Valo 3277*7ac9a364SKalle Valo /** 3278*7ac9a364SKalle Valo * il_tx_cmd_complete - Pull unused buffers off the queue and reclaim them 3279*7ac9a364SKalle Valo * @rxb: Rx buffer to reclaim 3280*7ac9a364SKalle Valo * 3281*7ac9a364SKalle Valo * If an Rx buffer has an async callback associated with it the callback 3282*7ac9a364SKalle Valo * will be executed. The attached skb (if present) will only be freed 3283*7ac9a364SKalle Valo * if the callback returns 1 3284*7ac9a364SKalle Valo */ 3285*7ac9a364SKalle Valo void 3286*7ac9a364SKalle Valo il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb) 3287*7ac9a364SKalle Valo { 3288*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 3289*7ac9a364SKalle Valo u16 sequence = le16_to_cpu(pkt->hdr.sequence); 3290*7ac9a364SKalle Valo int txq_id = SEQ_TO_QUEUE(sequence); 3291*7ac9a364SKalle Valo int idx = SEQ_TO_IDX(sequence); 3292*7ac9a364SKalle Valo int cmd_idx; 3293*7ac9a364SKalle Valo bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 3294*7ac9a364SKalle Valo struct il_device_cmd *cmd; 3295*7ac9a364SKalle Valo struct il_cmd_meta *meta; 3296*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[il->cmd_queue]; 3297*7ac9a364SKalle Valo unsigned long flags; 3298*7ac9a364SKalle Valo 3299*7ac9a364SKalle Valo /* If a Tx command is being handled and it isn't in the actual 3300*7ac9a364SKalle Valo * command queue then there a command routing bug has been introduced 3301*7ac9a364SKalle Valo * in the queue management code. */ 3302*7ac9a364SKalle Valo if (WARN 3303*7ac9a364SKalle Valo (txq_id != il->cmd_queue, 3304*7ac9a364SKalle Valo "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", 3305*7ac9a364SKalle Valo txq_id, il->cmd_queue, sequence, il->txq[il->cmd_queue].q.read_ptr, 3306*7ac9a364SKalle Valo il->txq[il->cmd_queue].q.write_ptr)) { 3307*7ac9a364SKalle Valo il_print_hex_error(il, pkt, 32); 3308*7ac9a364SKalle Valo return; 3309*7ac9a364SKalle Valo } 3310*7ac9a364SKalle Valo 3311*7ac9a364SKalle Valo cmd_idx = il_get_cmd_idx(&txq->q, idx, huge); 3312*7ac9a364SKalle Valo cmd = txq->cmd[cmd_idx]; 3313*7ac9a364SKalle Valo meta = &txq->meta[cmd_idx]; 3314*7ac9a364SKalle Valo 3315*7ac9a364SKalle Valo txq->time_stamp = jiffies; 3316*7ac9a364SKalle Valo 3317*7ac9a364SKalle Valo pci_unmap_single(il->pci_dev, dma_unmap_addr(meta, mapping), 3318*7ac9a364SKalle Valo dma_unmap_len(meta, len), PCI_DMA_BIDIRECTIONAL); 3319*7ac9a364SKalle Valo 3320*7ac9a364SKalle Valo /* Input error checking is done when commands are added to queue. */ 3321*7ac9a364SKalle Valo if (meta->flags & CMD_WANT_SKB) { 3322*7ac9a364SKalle Valo meta->source->reply_page = (unsigned long)rxb_addr(rxb); 3323*7ac9a364SKalle Valo rxb->page = NULL; 3324*7ac9a364SKalle Valo } else if (meta->callback) 3325*7ac9a364SKalle Valo meta->callback(il, cmd, pkt); 3326*7ac9a364SKalle Valo 3327*7ac9a364SKalle Valo spin_lock_irqsave(&il->hcmd_lock, flags); 3328*7ac9a364SKalle Valo 3329*7ac9a364SKalle Valo il_hcmd_queue_reclaim(il, txq_id, idx, cmd_idx); 3330*7ac9a364SKalle Valo 3331*7ac9a364SKalle Valo if (!(meta->flags & CMD_ASYNC)) { 3332*7ac9a364SKalle Valo clear_bit(S_HCMD_ACTIVE, &il->status); 3333*7ac9a364SKalle Valo D_INFO("Clearing HCMD_ACTIVE for command %s\n", 3334*7ac9a364SKalle Valo il_get_cmd_string(cmd->hdr.cmd)); 3335*7ac9a364SKalle Valo wake_up(&il->wait_command_queue); 3336*7ac9a364SKalle Valo } 3337*7ac9a364SKalle Valo 3338*7ac9a364SKalle Valo /* Mark as unmapped */ 3339*7ac9a364SKalle Valo meta->flags = 0; 3340*7ac9a364SKalle Valo 3341*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->hcmd_lock, flags); 3342*7ac9a364SKalle Valo } 3343*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_cmd_complete); 3344*7ac9a364SKalle Valo 3345*7ac9a364SKalle Valo MODULE_DESCRIPTION("iwl-legacy: common functions for 3945 and 4965"); 3346*7ac9a364SKalle Valo MODULE_VERSION(IWLWIFI_VERSION); 3347*7ac9a364SKalle Valo MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 3348*7ac9a364SKalle Valo MODULE_LICENSE("GPL"); 3349*7ac9a364SKalle Valo 3350*7ac9a364SKalle Valo /* 3351*7ac9a364SKalle Valo * set bt_coex_active to true, uCode will do kill/defer 3352*7ac9a364SKalle Valo * every time the priority line is asserted (BT is sending signals on the 3353*7ac9a364SKalle Valo * priority line in the PCIx). 3354*7ac9a364SKalle Valo * set bt_coex_active to false, uCode will ignore the BT activity and 3355*7ac9a364SKalle Valo * perform the normal operation 3356*7ac9a364SKalle Valo * 3357*7ac9a364SKalle Valo * User might experience transmit issue on some platform due to WiFi/BT 3358*7ac9a364SKalle Valo * co-exist problem. The possible behaviors are: 3359*7ac9a364SKalle Valo * Able to scan and finding all the available AP 3360*7ac9a364SKalle Valo * Not able to associate with any AP 3361*7ac9a364SKalle Valo * On those platforms, WiFi communication can be restored by set 3362*7ac9a364SKalle Valo * "bt_coex_active" module parameter to "false" 3363*7ac9a364SKalle Valo * 3364*7ac9a364SKalle Valo * default: bt_coex_active = true (BT_COEX_ENABLE) 3365*7ac9a364SKalle Valo */ 3366*7ac9a364SKalle Valo static bool bt_coex_active = true; 3367*7ac9a364SKalle Valo module_param(bt_coex_active, bool, S_IRUGO); 3368*7ac9a364SKalle Valo MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); 3369*7ac9a364SKalle Valo 3370*7ac9a364SKalle Valo u32 il_debug_level; 3371*7ac9a364SKalle Valo EXPORT_SYMBOL(il_debug_level); 3372*7ac9a364SKalle Valo 3373*7ac9a364SKalle Valo const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 3374*7ac9a364SKalle Valo EXPORT_SYMBOL(il_bcast_addr); 3375*7ac9a364SKalle Valo 3376*7ac9a364SKalle Valo #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 3377*7ac9a364SKalle Valo #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 3378*7ac9a364SKalle Valo static void 3379*7ac9a364SKalle Valo il_init_ht_hw_capab(const struct il_priv *il, 3380*7ac9a364SKalle Valo struct ieee80211_sta_ht_cap *ht_info, 3381*7ac9a364SKalle Valo enum ieee80211_band band) 3382*7ac9a364SKalle Valo { 3383*7ac9a364SKalle Valo u16 max_bit_rate = 0; 3384*7ac9a364SKalle Valo u8 rx_chains_num = il->hw_params.rx_chains_num; 3385*7ac9a364SKalle Valo u8 tx_chains_num = il->hw_params.tx_chains_num; 3386*7ac9a364SKalle Valo 3387*7ac9a364SKalle Valo ht_info->cap = 0; 3388*7ac9a364SKalle Valo memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 3389*7ac9a364SKalle Valo 3390*7ac9a364SKalle Valo ht_info->ht_supported = true; 3391*7ac9a364SKalle Valo 3392*7ac9a364SKalle Valo ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 3393*7ac9a364SKalle Valo max_bit_rate = MAX_BIT_RATE_20_MHZ; 3394*7ac9a364SKalle Valo if (il->hw_params.ht40_channel & BIT(band)) { 3395*7ac9a364SKalle Valo ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 3396*7ac9a364SKalle Valo ht_info->cap |= IEEE80211_HT_CAP_SGI_40; 3397*7ac9a364SKalle Valo ht_info->mcs.rx_mask[4] = 0x01; 3398*7ac9a364SKalle Valo max_bit_rate = MAX_BIT_RATE_40_MHZ; 3399*7ac9a364SKalle Valo } 3400*7ac9a364SKalle Valo 3401*7ac9a364SKalle Valo if (il->cfg->mod_params->amsdu_size_8K) 3402*7ac9a364SKalle Valo ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 3403*7ac9a364SKalle Valo 3404*7ac9a364SKalle Valo ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; 3405*7ac9a364SKalle Valo ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; 3406*7ac9a364SKalle Valo 3407*7ac9a364SKalle Valo ht_info->mcs.rx_mask[0] = 0xFF; 3408*7ac9a364SKalle Valo if (rx_chains_num >= 2) 3409*7ac9a364SKalle Valo ht_info->mcs.rx_mask[1] = 0xFF; 3410*7ac9a364SKalle Valo if (rx_chains_num >= 3) 3411*7ac9a364SKalle Valo ht_info->mcs.rx_mask[2] = 0xFF; 3412*7ac9a364SKalle Valo 3413*7ac9a364SKalle Valo /* Highest supported Rx data rate */ 3414*7ac9a364SKalle Valo max_bit_rate *= rx_chains_num; 3415*7ac9a364SKalle Valo WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); 3416*7ac9a364SKalle Valo ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); 3417*7ac9a364SKalle Valo 3418*7ac9a364SKalle Valo /* Tx MCS capabilities */ 3419*7ac9a364SKalle Valo ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 3420*7ac9a364SKalle Valo if (tx_chains_num != rx_chains_num) { 3421*7ac9a364SKalle Valo ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; 3422*7ac9a364SKalle Valo ht_info->mcs.tx_params |= 3423*7ac9a364SKalle Valo ((tx_chains_num - 3424*7ac9a364SKalle Valo 1) << IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); 3425*7ac9a364SKalle Valo } 3426*7ac9a364SKalle Valo } 3427*7ac9a364SKalle Valo 3428*7ac9a364SKalle Valo /** 3429*7ac9a364SKalle Valo * il_init_geos - Initialize mac80211's geo/channel info based from eeprom 3430*7ac9a364SKalle Valo */ 3431*7ac9a364SKalle Valo int 3432*7ac9a364SKalle Valo il_init_geos(struct il_priv *il) 3433*7ac9a364SKalle Valo { 3434*7ac9a364SKalle Valo struct il_channel_info *ch; 3435*7ac9a364SKalle Valo struct ieee80211_supported_band *sband; 3436*7ac9a364SKalle Valo struct ieee80211_channel *channels; 3437*7ac9a364SKalle Valo struct ieee80211_channel *geo_ch; 3438*7ac9a364SKalle Valo struct ieee80211_rate *rates; 3439*7ac9a364SKalle Valo int i = 0; 3440*7ac9a364SKalle Valo s8 max_tx_power = 0; 3441*7ac9a364SKalle Valo 3442*7ac9a364SKalle Valo if (il->bands[IEEE80211_BAND_2GHZ].n_bitrates || 3443*7ac9a364SKalle Valo il->bands[IEEE80211_BAND_5GHZ].n_bitrates) { 3444*7ac9a364SKalle Valo D_INFO("Geography modes already initialized.\n"); 3445*7ac9a364SKalle Valo set_bit(S_GEO_CONFIGURED, &il->status); 3446*7ac9a364SKalle Valo return 0; 3447*7ac9a364SKalle Valo } 3448*7ac9a364SKalle Valo 3449*7ac9a364SKalle Valo channels = 3450*7ac9a364SKalle Valo kzalloc(sizeof(struct ieee80211_channel) * il->channel_count, 3451*7ac9a364SKalle Valo GFP_KERNEL); 3452*7ac9a364SKalle Valo if (!channels) 3453*7ac9a364SKalle Valo return -ENOMEM; 3454*7ac9a364SKalle Valo 3455*7ac9a364SKalle Valo rates = 3456*7ac9a364SKalle Valo kzalloc((sizeof(struct ieee80211_rate) * RATE_COUNT_LEGACY), 3457*7ac9a364SKalle Valo GFP_KERNEL); 3458*7ac9a364SKalle Valo if (!rates) { 3459*7ac9a364SKalle Valo kfree(channels); 3460*7ac9a364SKalle Valo return -ENOMEM; 3461*7ac9a364SKalle Valo } 3462*7ac9a364SKalle Valo 3463*7ac9a364SKalle Valo /* 5.2GHz channels start after the 2.4GHz channels */ 3464*7ac9a364SKalle Valo sband = &il->bands[IEEE80211_BAND_5GHZ]; 3465*7ac9a364SKalle Valo sband->channels = &channels[ARRAY_SIZE(il_eeprom_band_1)]; 3466*7ac9a364SKalle Valo /* just OFDM */ 3467*7ac9a364SKalle Valo sband->bitrates = &rates[IL_FIRST_OFDM_RATE]; 3468*7ac9a364SKalle Valo sband->n_bitrates = RATE_COUNT_LEGACY - IL_FIRST_OFDM_RATE; 3469*7ac9a364SKalle Valo 3470*7ac9a364SKalle Valo if (il->cfg->sku & IL_SKU_N) 3471*7ac9a364SKalle Valo il_init_ht_hw_capab(il, &sband->ht_cap, IEEE80211_BAND_5GHZ); 3472*7ac9a364SKalle Valo 3473*7ac9a364SKalle Valo sband = &il->bands[IEEE80211_BAND_2GHZ]; 3474*7ac9a364SKalle Valo sband->channels = channels; 3475*7ac9a364SKalle Valo /* OFDM & CCK */ 3476*7ac9a364SKalle Valo sband->bitrates = rates; 3477*7ac9a364SKalle Valo sband->n_bitrates = RATE_COUNT_LEGACY; 3478*7ac9a364SKalle Valo 3479*7ac9a364SKalle Valo if (il->cfg->sku & IL_SKU_N) 3480*7ac9a364SKalle Valo il_init_ht_hw_capab(il, &sband->ht_cap, IEEE80211_BAND_2GHZ); 3481*7ac9a364SKalle Valo 3482*7ac9a364SKalle Valo il->ieee_channels = channels; 3483*7ac9a364SKalle Valo il->ieee_rates = rates; 3484*7ac9a364SKalle Valo 3485*7ac9a364SKalle Valo for (i = 0; i < il->channel_count; i++) { 3486*7ac9a364SKalle Valo ch = &il->channel_info[i]; 3487*7ac9a364SKalle Valo 3488*7ac9a364SKalle Valo if (!il_is_channel_valid(ch)) 3489*7ac9a364SKalle Valo continue; 3490*7ac9a364SKalle Valo 3491*7ac9a364SKalle Valo sband = &il->bands[ch->band]; 3492*7ac9a364SKalle Valo 3493*7ac9a364SKalle Valo geo_ch = &sband->channels[sband->n_channels++]; 3494*7ac9a364SKalle Valo 3495*7ac9a364SKalle Valo geo_ch->center_freq = 3496*7ac9a364SKalle Valo ieee80211_channel_to_frequency(ch->channel, ch->band); 3497*7ac9a364SKalle Valo geo_ch->max_power = ch->max_power_avg; 3498*7ac9a364SKalle Valo geo_ch->max_antenna_gain = 0xff; 3499*7ac9a364SKalle Valo geo_ch->hw_value = ch->channel; 3500*7ac9a364SKalle Valo 3501*7ac9a364SKalle Valo if (il_is_channel_valid(ch)) { 3502*7ac9a364SKalle Valo if (!(ch->flags & EEPROM_CHANNEL_IBSS)) 3503*7ac9a364SKalle Valo geo_ch->flags |= IEEE80211_CHAN_NO_IR; 3504*7ac9a364SKalle Valo 3505*7ac9a364SKalle Valo if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) 3506*7ac9a364SKalle Valo geo_ch->flags |= IEEE80211_CHAN_NO_IR; 3507*7ac9a364SKalle Valo 3508*7ac9a364SKalle Valo if (ch->flags & EEPROM_CHANNEL_RADAR) 3509*7ac9a364SKalle Valo geo_ch->flags |= IEEE80211_CHAN_RADAR; 3510*7ac9a364SKalle Valo 3511*7ac9a364SKalle Valo geo_ch->flags |= ch->ht40_extension_channel; 3512*7ac9a364SKalle Valo 3513*7ac9a364SKalle Valo if (ch->max_power_avg > max_tx_power) 3514*7ac9a364SKalle Valo max_tx_power = ch->max_power_avg; 3515*7ac9a364SKalle Valo } else { 3516*7ac9a364SKalle Valo geo_ch->flags |= IEEE80211_CHAN_DISABLED; 3517*7ac9a364SKalle Valo } 3518*7ac9a364SKalle Valo 3519*7ac9a364SKalle Valo D_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", ch->channel, 3520*7ac9a364SKalle Valo geo_ch->center_freq, 3521*7ac9a364SKalle Valo il_is_channel_a_band(ch) ? "5.2" : "2.4", 3522*7ac9a364SKalle Valo geo_ch-> 3523*7ac9a364SKalle Valo flags & IEEE80211_CHAN_DISABLED ? "restricted" : "valid", 3524*7ac9a364SKalle Valo geo_ch->flags); 3525*7ac9a364SKalle Valo } 3526*7ac9a364SKalle Valo 3527*7ac9a364SKalle Valo il->tx_power_device_lmt = max_tx_power; 3528*7ac9a364SKalle Valo il->tx_power_user_lmt = max_tx_power; 3529*7ac9a364SKalle Valo il->tx_power_next = max_tx_power; 3530*7ac9a364SKalle Valo 3531*7ac9a364SKalle Valo if (il->bands[IEEE80211_BAND_5GHZ].n_channels == 0 && 3532*7ac9a364SKalle Valo (il->cfg->sku & IL_SKU_A)) { 3533*7ac9a364SKalle Valo IL_INFO("Incorrectly detected BG card as ABG. " 3534*7ac9a364SKalle Valo "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", 3535*7ac9a364SKalle Valo il->pci_dev->device, il->pci_dev->subsystem_device); 3536*7ac9a364SKalle Valo il->cfg->sku &= ~IL_SKU_A; 3537*7ac9a364SKalle Valo } 3538*7ac9a364SKalle Valo 3539*7ac9a364SKalle Valo IL_INFO("Tunable channels: %d 802.11bg, %d 802.11a channels\n", 3540*7ac9a364SKalle Valo il->bands[IEEE80211_BAND_2GHZ].n_channels, 3541*7ac9a364SKalle Valo il->bands[IEEE80211_BAND_5GHZ].n_channels); 3542*7ac9a364SKalle Valo 3543*7ac9a364SKalle Valo set_bit(S_GEO_CONFIGURED, &il->status); 3544*7ac9a364SKalle Valo 3545*7ac9a364SKalle Valo return 0; 3546*7ac9a364SKalle Valo } 3547*7ac9a364SKalle Valo EXPORT_SYMBOL(il_init_geos); 3548*7ac9a364SKalle Valo 3549*7ac9a364SKalle Valo /* 3550*7ac9a364SKalle Valo * il_free_geos - undo allocations in il_init_geos 3551*7ac9a364SKalle Valo */ 3552*7ac9a364SKalle Valo void 3553*7ac9a364SKalle Valo il_free_geos(struct il_priv *il) 3554*7ac9a364SKalle Valo { 3555*7ac9a364SKalle Valo kfree(il->ieee_channels); 3556*7ac9a364SKalle Valo kfree(il->ieee_rates); 3557*7ac9a364SKalle Valo clear_bit(S_GEO_CONFIGURED, &il->status); 3558*7ac9a364SKalle Valo } 3559*7ac9a364SKalle Valo EXPORT_SYMBOL(il_free_geos); 3560*7ac9a364SKalle Valo 3561*7ac9a364SKalle Valo static bool 3562*7ac9a364SKalle Valo il_is_channel_extension(struct il_priv *il, enum ieee80211_band band, 3563*7ac9a364SKalle Valo u16 channel, u8 extension_chan_offset) 3564*7ac9a364SKalle Valo { 3565*7ac9a364SKalle Valo const struct il_channel_info *ch_info; 3566*7ac9a364SKalle Valo 3567*7ac9a364SKalle Valo ch_info = il_get_channel_info(il, band, channel); 3568*7ac9a364SKalle Valo if (!il_is_channel_valid(ch_info)) 3569*7ac9a364SKalle Valo return false; 3570*7ac9a364SKalle Valo 3571*7ac9a364SKalle Valo if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) 3572*7ac9a364SKalle Valo return !(ch_info-> 3573*7ac9a364SKalle Valo ht40_extension_channel & IEEE80211_CHAN_NO_HT40PLUS); 3574*7ac9a364SKalle Valo else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) 3575*7ac9a364SKalle Valo return !(ch_info-> 3576*7ac9a364SKalle Valo ht40_extension_channel & IEEE80211_CHAN_NO_HT40MINUS); 3577*7ac9a364SKalle Valo 3578*7ac9a364SKalle Valo return false; 3579*7ac9a364SKalle Valo } 3580*7ac9a364SKalle Valo 3581*7ac9a364SKalle Valo bool 3582*7ac9a364SKalle Valo il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap) 3583*7ac9a364SKalle Valo { 3584*7ac9a364SKalle Valo if (!il->ht.enabled || !il->ht.is_40mhz) 3585*7ac9a364SKalle Valo return false; 3586*7ac9a364SKalle Valo 3587*7ac9a364SKalle Valo /* 3588*7ac9a364SKalle Valo * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 3589*7ac9a364SKalle Valo * the bit will not set if it is pure 40MHz case 3590*7ac9a364SKalle Valo */ 3591*7ac9a364SKalle Valo if (ht_cap && !ht_cap->ht_supported) 3592*7ac9a364SKalle Valo return false; 3593*7ac9a364SKalle Valo 3594*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUGFS 3595*7ac9a364SKalle Valo if (il->disable_ht40) 3596*7ac9a364SKalle Valo return false; 3597*7ac9a364SKalle Valo #endif 3598*7ac9a364SKalle Valo 3599*7ac9a364SKalle Valo return il_is_channel_extension(il, il->band, 3600*7ac9a364SKalle Valo le16_to_cpu(il->staging.channel), 3601*7ac9a364SKalle Valo il->ht.extension_chan_offset); 3602*7ac9a364SKalle Valo } 3603*7ac9a364SKalle Valo EXPORT_SYMBOL(il_is_ht40_tx_allowed); 3604*7ac9a364SKalle Valo 3605*7ac9a364SKalle Valo static u16 3606*7ac9a364SKalle Valo il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) 3607*7ac9a364SKalle Valo { 3608*7ac9a364SKalle Valo u16 new_val; 3609*7ac9a364SKalle Valo u16 beacon_factor; 3610*7ac9a364SKalle Valo 3611*7ac9a364SKalle Valo /* 3612*7ac9a364SKalle Valo * If mac80211 hasn't given us a beacon interval, program 3613*7ac9a364SKalle Valo * the default into the device. 3614*7ac9a364SKalle Valo */ 3615*7ac9a364SKalle Valo if (!beacon_val) 3616*7ac9a364SKalle Valo return DEFAULT_BEACON_INTERVAL; 3617*7ac9a364SKalle Valo 3618*7ac9a364SKalle Valo /* 3619*7ac9a364SKalle Valo * If the beacon interval we obtained from the peer 3620*7ac9a364SKalle Valo * is too large, we'll have to wake up more often 3621*7ac9a364SKalle Valo * (and in IBSS case, we'll beacon too much) 3622*7ac9a364SKalle Valo * 3623*7ac9a364SKalle Valo * For example, if max_beacon_val is 4096, and the 3624*7ac9a364SKalle Valo * requested beacon interval is 7000, we'll have to 3625*7ac9a364SKalle Valo * use 3500 to be able to wake up on the beacons. 3626*7ac9a364SKalle Valo * 3627*7ac9a364SKalle Valo * This could badly influence beacon detection stats. 3628*7ac9a364SKalle Valo */ 3629*7ac9a364SKalle Valo 3630*7ac9a364SKalle Valo beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val; 3631*7ac9a364SKalle Valo new_val = beacon_val / beacon_factor; 3632*7ac9a364SKalle Valo 3633*7ac9a364SKalle Valo if (!new_val) 3634*7ac9a364SKalle Valo new_val = max_beacon_val; 3635*7ac9a364SKalle Valo 3636*7ac9a364SKalle Valo return new_val; 3637*7ac9a364SKalle Valo } 3638*7ac9a364SKalle Valo 3639*7ac9a364SKalle Valo int 3640*7ac9a364SKalle Valo il_send_rxon_timing(struct il_priv *il) 3641*7ac9a364SKalle Valo { 3642*7ac9a364SKalle Valo u64 tsf; 3643*7ac9a364SKalle Valo s32 interval_tm, rem; 3644*7ac9a364SKalle Valo struct ieee80211_conf *conf = NULL; 3645*7ac9a364SKalle Valo u16 beacon_int; 3646*7ac9a364SKalle Valo struct ieee80211_vif *vif = il->vif; 3647*7ac9a364SKalle Valo 3648*7ac9a364SKalle Valo conf = &il->hw->conf; 3649*7ac9a364SKalle Valo 3650*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 3651*7ac9a364SKalle Valo 3652*7ac9a364SKalle Valo memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd)); 3653*7ac9a364SKalle Valo 3654*7ac9a364SKalle Valo il->timing.timestamp = cpu_to_le64(il->timestamp); 3655*7ac9a364SKalle Valo il->timing.listen_interval = cpu_to_le16(conf->listen_interval); 3656*7ac9a364SKalle Valo 3657*7ac9a364SKalle Valo beacon_int = vif ? vif->bss_conf.beacon_int : 0; 3658*7ac9a364SKalle Valo 3659*7ac9a364SKalle Valo /* 3660*7ac9a364SKalle Valo * TODO: For IBSS we need to get atim_win from mac80211, 3661*7ac9a364SKalle Valo * for now just always use 0 3662*7ac9a364SKalle Valo */ 3663*7ac9a364SKalle Valo il->timing.atim_win = 0; 3664*7ac9a364SKalle Valo 3665*7ac9a364SKalle Valo beacon_int = 3666*7ac9a364SKalle Valo il_adjust_beacon_interval(beacon_int, 3667*7ac9a364SKalle Valo il->hw_params.max_beacon_itrvl * 3668*7ac9a364SKalle Valo TIME_UNIT); 3669*7ac9a364SKalle Valo il->timing.beacon_interval = cpu_to_le16(beacon_int); 3670*7ac9a364SKalle Valo 3671*7ac9a364SKalle Valo tsf = il->timestamp; /* tsf is modifed by do_div: copy it */ 3672*7ac9a364SKalle Valo interval_tm = beacon_int * TIME_UNIT; 3673*7ac9a364SKalle Valo rem = do_div(tsf, interval_tm); 3674*7ac9a364SKalle Valo il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); 3675*7ac9a364SKalle Valo 3676*7ac9a364SKalle Valo il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1; 3677*7ac9a364SKalle Valo 3678*7ac9a364SKalle Valo D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n", 3679*7ac9a364SKalle Valo le16_to_cpu(il->timing.beacon_interval), 3680*7ac9a364SKalle Valo le32_to_cpu(il->timing.beacon_init_val), 3681*7ac9a364SKalle Valo le16_to_cpu(il->timing.atim_win)); 3682*7ac9a364SKalle Valo 3683*7ac9a364SKalle Valo return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing), 3684*7ac9a364SKalle Valo &il->timing); 3685*7ac9a364SKalle Valo } 3686*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_rxon_timing); 3687*7ac9a364SKalle Valo 3688*7ac9a364SKalle Valo void 3689*7ac9a364SKalle Valo il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt) 3690*7ac9a364SKalle Valo { 3691*7ac9a364SKalle Valo struct il_rxon_cmd *rxon = &il->staging; 3692*7ac9a364SKalle Valo 3693*7ac9a364SKalle Valo if (hw_decrypt) 3694*7ac9a364SKalle Valo rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; 3695*7ac9a364SKalle Valo else 3696*7ac9a364SKalle Valo rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; 3697*7ac9a364SKalle Valo 3698*7ac9a364SKalle Valo } 3699*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_rxon_hwcrypto); 3700*7ac9a364SKalle Valo 3701*7ac9a364SKalle Valo /* validate RXON structure is valid */ 3702*7ac9a364SKalle Valo int 3703*7ac9a364SKalle Valo il_check_rxon_cmd(struct il_priv *il) 3704*7ac9a364SKalle Valo { 3705*7ac9a364SKalle Valo struct il_rxon_cmd *rxon = &il->staging; 3706*7ac9a364SKalle Valo bool error = false; 3707*7ac9a364SKalle Valo 3708*7ac9a364SKalle Valo if (rxon->flags & RXON_FLG_BAND_24G_MSK) { 3709*7ac9a364SKalle Valo if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { 3710*7ac9a364SKalle Valo IL_WARN("check 2.4G: wrong narrow\n"); 3711*7ac9a364SKalle Valo error = true; 3712*7ac9a364SKalle Valo } 3713*7ac9a364SKalle Valo if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { 3714*7ac9a364SKalle Valo IL_WARN("check 2.4G: wrong radar\n"); 3715*7ac9a364SKalle Valo error = true; 3716*7ac9a364SKalle Valo } 3717*7ac9a364SKalle Valo } else { 3718*7ac9a364SKalle Valo if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { 3719*7ac9a364SKalle Valo IL_WARN("check 5.2G: not short slot!\n"); 3720*7ac9a364SKalle Valo error = true; 3721*7ac9a364SKalle Valo } 3722*7ac9a364SKalle Valo if (rxon->flags & RXON_FLG_CCK_MSK) { 3723*7ac9a364SKalle Valo IL_WARN("check 5.2G: CCK!\n"); 3724*7ac9a364SKalle Valo error = true; 3725*7ac9a364SKalle Valo } 3726*7ac9a364SKalle Valo } 3727*7ac9a364SKalle Valo if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { 3728*7ac9a364SKalle Valo IL_WARN("mac/bssid mcast!\n"); 3729*7ac9a364SKalle Valo error = true; 3730*7ac9a364SKalle Valo } 3731*7ac9a364SKalle Valo 3732*7ac9a364SKalle Valo /* make sure basic rates 6Mbps and 1Mbps are supported */ 3733*7ac9a364SKalle Valo if ((rxon->ofdm_basic_rates & RATE_6M_MASK) == 0 && 3734*7ac9a364SKalle Valo (rxon->cck_basic_rates & RATE_1M_MASK) == 0) { 3735*7ac9a364SKalle Valo IL_WARN("neither 1 nor 6 are basic\n"); 3736*7ac9a364SKalle Valo error = true; 3737*7ac9a364SKalle Valo } 3738*7ac9a364SKalle Valo 3739*7ac9a364SKalle Valo if (le16_to_cpu(rxon->assoc_id) > 2007) { 3740*7ac9a364SKalle Valo IL_WARN("aid > 2007\n"); 3741*7ac9a364SKalle Valo error = true; 3742*7ac9a364SKalle Valo } 3743*7ac9a364SKalle Valo 3744*7ac9a364SKalle Valo if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) == 3745*7ac9a364SKalle Valo (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { 3746*7ac9a364SKalle Valo IL_WARN("CCK and short slot\n"); 3747*7ac9a364SKalle Valo error = true; 3748*7ac9a364SKalle Valo } 3749*7ac9a364SKalle Valo 3750*7ac9a364SKalle Valo if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) == 3751*7ac9a364SKalle Valo (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { 3752*7ac9a364SKalle Valo IL_WARN("CCK and auto detect"); 3753*7ac9a364SKalle Valo error = true; 3754*7ac9a364SKalle Valo } 3755*7ac9a364SKalle Valo 3756*7ac9a364SKalle Valo if ((rxon-> 3757*7ac9a364SKalle Valo flags & (RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK)) == 3758*7ac9a364SKalle Valo RXON_FLG_TGG_PROTECT_MSK) { 3759*7ac9a364SKalle Valo IL_WARN("TGg but no auto-detect\n"); 3760*7ac9a364SKalle Valo error = true; 3761*7ac9a364SKalle Valo } 3762*7ac9a364SKalle Valo 3763*7ac9a364SKalle Valo if (error) 3764*7ac9a364SKalle Valo IL_WARN("Tuning to channel %d\n", le16_to_cpu(rxon->channel)); 3765*7ac9a364SKalle Valo 3766*7ac9a364SKalle Valo if (error) { 3767*7ac9a364SKalle Valo IL_ERR("Invalid RXON\n"); 3768*7ac9a364SKalle Valo return -EINVAL; 3769*7ac9a364SKalle Valo } 3770*7ac9a364SKalle Valo return 0; 3771*7ac9a364SKalle Valo } 3772*7ac9a364SKalle Valo EXPORT_SYMBOL(il_check_rxon_cmd); 3773*7ac9a364SKalle Valo 3774*7ac9a364SKalle Valo /** 3775*7ac9a364SKalle Valo * il_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed 3776*7ac9a364SKalle Valo * @il: staging_rxon is compared to active_rxon 3777*7ac9a364SKalle Valo * 3778*7ac9a364SKalle Valo * If the RXON structure is changing enough to require a new tune, 3779*7ac9a364SKalle Valo * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that 3780*7ac9a364SKalle Valo * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. 3781*7ac9a364SKalle Valo */ 3782*7ac9a364SKalle Valo int 3783*7ac9a364SKalle Valo il_full_rxon_required(struct il_priv *il) 3784*7ac9a364SKalle Valo { 3785*7ac9a364SKalle Valo const struct il_rxon_cmd *staging = &il->staging; 3786*7ac9a364SKalle Valo const struct il_rxon_cmd *active = &il->active; 3787*7ac9a364SKalle Valo 3788*7ac9a364SKalle Valo #define CHK(cond) \ 3789*7ac9a364SKalle Valo if ((cond)) { \ 3790*7ac9a364SKalle Valo D_INFO("need full RXON - " #cond "\n"); \ 3791*7ac9a364SKalle Valo return 1; \ 3792*7ac9a364SKalle Valo } 3793*7ac9a364SKalle Valo 3794*7ac9a364SKalle Valo #define CHK_NEQ(c1, c2) \ 3795*7ac9a364SKalle Valo if ((c1) != (c2)) { \ 3796*7ac9a364SKalle Valo D_INFO("need full RXON - " \ 3797*7ac9a364SKalle Valo #c1 " != " #c2 " - %d != %d\n", \ 3798*7ac9a364SKalle Valo (c1), (c2)); \ 3799*7ac9a364SKalle Valo return 1; \ 3800*7ac9a364SKalle Valo } 3801*7ac9a364SKalle Valo 3802*7ac9a364SKalle Valo /* These items are only settable from the full RXON command */ 3803*7ac9a364SKalle Valo CHK(!il_is_associated(il)); 3804*7ac9a364SKalle Valo CHK(!ether_addr_equal_64bits(staging->bssid_addr, active->bssid_addr)); 3805*7ac9a364SKalle Valo CHK(!ether_addr_equal_64bits(staging->node_addr, active->node_addr)); 3806*7ac9a364SKalle Valo CHK(!ether_addr_equal_64bits(staging->wlap_bssid_addr, 3807*7ac9a364SKalle Valo active->wlap_bssid_addr)); 3808*7ac9a364SKalle Valo CHK_NEQ(staging->dev_type, active->dev_type); 3809*7ac9a364SKalle Valo CHK_NEQ(staging->channel, active->channel); 3810*7ac9a364SKalle Valo CHK_NEQ(staging->air_propagation, active->air_propagation); 3811*7ac9a364SKalle Valo CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates, 3812*7ac9a364SKalle Valo active->ofdm_ht_single_stream_basic_rates); 3813*7ac9a364SKalle Valo CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates, 3814*7ac9a364SKalle Valo active->ofdm_ht_dual_stream_basic_rates); 3815*7ac9a364SKalle Valo CHK_NEQ(staging->assoc_id, active->assoc_id); 3816*7ac9a364SKalle Valo 3817*7ac9a364SKalle Valo /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can 3818*7ac9a364SKalle Valo * be updated with the RXON_ASSOC command -- however only some 3819*7ac9a364SKalle Valo * flag transitions are allowed using RXON_ASSOC */ 3820*7ac9a364SKalle Valo 3821*7ac9a364SKalle Valo /* Check if we are not switching bands */ 3822*7ac9a364SKalle Valo CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK, 3823*7ac9a364SKalle Valo active->flags & RXON_FLG_BAND_24G_MSK); 3824*7ac9a364SKalle Valo 3825*7ac9a364SKalle Valo /* Check if we are switching association toggle */ 3826*7ac9a364SKalle Valo CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK, 3827*7ac9a364SKalle Valo active->filter_flags & RXON_FILTER_ASSOC_MSK); 3828*7ac9a364SKalle Valo 3829*7ac9a364SKalle Valo #undef CHK 3830*7ac9a364SKalle Valo #undef CHK_NEQ 3831*7ac9a364SKalle Valo 3832*7ac9a364SKalle Valo return 0; 3833*7ac9a364SKalle Valo } 3834*7ac9a364SKalle Valo EXPORT_SYMBOL(il_full_rxon_required); 3835*7ac9a364SKalle Valo 3836*7ac9a364SKalle Valo u8 3837*7ac9a364SKalle Valo il_get_lowest_plcp(struct il_priv *il) 3838*7ac9a364SKalle Valo { 3839*7ac9a364SKalle Valo /* 3840*7ac9a364SKalle Valo * Assign the lowest rate -- should really get this from 3841*7ac9a364SKalle Valo * the beacon skb from mac80211. 3842*7ac9a364SKalle Valo */ 3843*7ac9a364SKalle Valo if (il->staging.flags & RXON_FLG_BAND_24G_MSK) 3844*7ac9a364SKalle Valo return RATE_1M_PLCP; 3845*7ac9a364SKalle Valo else 3846*7ac9a364SKalle Valo return RATE_6M_PLCP; 3847*7ac9a364SKalle Valo } 3848*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_lowest_plcp); 3849*7ac9a364SKalle Valo 3850*7ac9a364SKalle Valo static void 3851*7ac9a364SKalle Valo _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) 3852*7ac9a364SKalle Valo { 3853*7ac9a364SKalle Valo struct il_rxon_cmd *rxon = &il->staging; 3854*7ac9a364SKalle Valo 3855*7ac9a364SKalle Valo if (!il->ht.enabled) { 3856*7ac9a364SKalle Valo rxon->flags &= 3857*7ac9a364SKalle Valo ~(RXON_FLG_CHANNEL_MODE_MSK | 3858*7ac9a364SKalle Valo RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK 3859*7ac9a364SKalle Valo | RXON_FLG_HT_PROT_MSK); 3860*7ac9a364SKalle Valo return; 3861*7ac9a364SKalle Valo } 3862*7ac9a364SKalle Valo 3863*7ac9a364SKalle Valo rxon->flags |= 3864*7ac9a364SKalle Valo cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); 3865*7ac9a364SKalle Valo 3866*7ac9a364SKalle Valo /* Set up channel bandwidth: 3867*7ac9a364SKalle Valo * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ 3868*7ac9a364SKalle Valo /* clear the HT channel mode before set the mode */ 3869*7ac9a364SKalle Valo rxon->flags &= 3870*7ac9a364SKalle Valo ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); 3871*7ac9a364SKalle Valo if (il_is_ht40_tx_allowed(il, NULL)) { 3872*7ac9a364SKalle Valo /* pure ht40 */ 3873*7ac9a364SKalle Valo if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { 3874*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; 3875*7ac9a364SKalle Valo /* Note: control channel is opposite of extension channel */ 3876*7ac9a364SKalle Valo switch (il->ht.extension_chan_offset) { 3877*7ac9a364SKalle Valo case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3878*7ac9a364SKalle Valo rxon->flags &= 3879*7ac9a364SKalle Valo ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; 3880*7ac9a364SKalle Valo break; 3881*7ac9a364SKalle Valo case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 3882*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; 3883*7ac9a364SKalle Valo break; 3884*7ac9a364SKalle Valo } 3885*7ac9a364SKalle Valo } else { 3886*7ac9a364SKalle Valo /* Note: control channel is opposite of extension channel */ 3887*7ac9a364SKalle Valo switch (il->ht.extension_chan_offset) { 3888*7ac9a364SKalle Valo case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3889*7ac9a364SKalle Valo rxon->flags &= 3890*7ac9a364SKalle Valo ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); 3891*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; 3892*7ac9a364SKalle Valo break; 3893*7ac9a364SKalle Valo case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 3894*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; 3895*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; 3896*7ac9a364SKalle Valo break; 3897*7ac9a364SKalle Valo case IEEE80211_HT_PARAM_CHA_SEC_NONE: 3898*7ac9a364SKalle Valo default: 3899*7ac9a364SKalle Valo /* channel location only valid if in Mixed mode */ 3900*7ac9a364SKalle Valo IL_ERR("invalid extension channel offset\n"); 3901*7ac9a364SKalle Valo break; 3902*7ac9a364SKalle Valo } 3903*7ac9a364SKalle Valo } 3904*7ac9a364SKalle Valo } else { 3905*7ac9a364SKalle Valo rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; 3906*7ac9a364SKalle Valo } 3907*7ac9a364SKalle Valo 3908*7ac9a364SKalle Valo if (il->ops->set_rxon_chain) 3909*7ac9a364SKalle Valo il->ops->set_rxon_chain(il); 3910*7ac9a364SKalle Valo 3911*7ac9a364SKalle Valo D_ASSOC("rxon flags 0x%X operation mode :0x%X " 3912*7ac9a364SKalle Valo "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), 3913*7ac9a364SKalle Valo il->ht.protection, il->ht.extension_chan_offset); 3914*7ac9a364SKalle Valo } 3915*7ac9a364SKalle Valo 3916*7ac9a364SKalle Valo void 3917*7ac9a364SKalle Valo il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) 3918*7ac9a364SKalle Valo { 3919*7ac9a364SKalle Valo _il_set_rxon_ht(il, ht_conf); 3920*7ac9a364SKalle Valo } 3921*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_rxon_ht); 3922*7ac9a364SKalle Valo 3923*7ac9a364SKalle Valo /* Return valid, unused, channel for a passive scan to reset the RF */ 3924*7ac9a364SKalle Valo u8 3925*7ac9a364SKalle Valo il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band) 3926*7ac9a364SKalle Valo { 3927*7ac9a364SKalle Valo const struct il_channel_info *ch_info; 3928*7ac9a364SKalle Valo int i; 3929*7ac9a364SKalle Valo u8 channel = 0; 3930*7ac9a364SKalle Valo u8 min, max; 3931*7ac9a364SKalle Valo 3932*7ac9a364SKalle Valo if (band == IEEE80211_BAND_5GHZ) { 3933*7ac9a364SKalle Valo min = 14; 3934*7ac9a364SKalle Valo max = il->channel_count; 3935*7ac9a364SKalle Valo } else { 3936*7ac9a364SKalle Valo min = 0; 3937*7ac9a364SKalle Valo max = 14; 3938*7ac9a364SKalle Valo } 3939*7ac9a364SKalle Valo 3940*7ac9a364SKalle Valo for (i = min; i < max; i++) { 3941*7ac9a364SKalle Valo channel = il->channel_info[i].channel; 3942*7ac9a364SKalle Valo if (channel == le16_to_cpu(il->staging.channel)) 3943*7ac9a364SKalle Valo continue; 3944*7ac9a364SKalle Valo 3945*7ac9a364SKalle Valo ch_info = il_get_channel_info(il, band, channel); 3946*7ac9a364SKalle Valo if (il_is_channel_valid(ch_info)) 3947*7ac9a364SKalle Valo break; 3948*7ac9a364SKalle Valo } 3949*7ac9a364SKalle Valo 3950*7ac9a364SKalle Valo return channel; 3951*7ac9a364SKalle Valo } 3952*7ac9a364SKalle Valo EXPORT_SYMBOL(il_get_single_channel_number); 3953*7ac9a364SKalle Valo 3954*7ac9a364SKalle Valo /** 3955*7ac9a364SKalle Valo * il_set_rxon_channel - Set the band and channel values in staging RXON 3956*7ac9a364SKalle Valo * @ch: requested channel as a pointer to struct ieee80211_channel 3957*7ac9a364SKalle Valo 3958*7ac9a364SKalle Valo * NOTE: Does not commit to the hardware; it sets appropriate bit fields 3959*7ac9a364SKalle Valo * in the staging RXON flag structure based on the ch->band 3960*7ac9a364SKalle Valo */ 3961*7ac9a364SKalle Valo int 3962*7ac9a364SKalle Valo il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch) 3963*7ac9a364SKalle Valo { 3964*7ac9a364SKalle Valo enum ieee80211_band band = ch->band; 3965*7ac9a364SKalle Valo u16 channel = ch->hw_value; 3966*7ac9a364SKalle Valo 3967*7ac9a364SKalle Valo if (le16_to_cpu(il->staging.channel) == channel && il->band == band) 3968*7ac9a364SKalle Valo return 0; 3969*7ac9a364SKalle Valo 3970*7ac9a364SKalle Valo il->staging.channel = cpu_to_le16(channel); 3971*7ac9a364SKalle Valo if (band == IEEE80211_BAND_5GHZ) 3972*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_BAND_24G_MSK; 3973*7ac9a364SKalle Valo else 3974*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_BAND_24G_MSK; 3975*7ac9a364SKalle Valo 3976*7ac9a364SKalle Valo il->band = band; 3977*7ac9a364SKalle Valo 3978*7ac9a364SKalle Valo D_INFO("Staging channel set to %d [%d]\n", channel, band); 3979*7ac9a364SKalle Valo 3980*7ac9a364SKalle Valo return 0; 3981*7ac9a364SKalle Valo } 3982*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_rxon_channel); 3983*7ac9a364SKalle Valo 3984*7ac9a364SKalle Valo void 3985*7ac9a364SKalle Valo il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band, 3986*7ac9a364SKalle Valo struct ieee80211_vif *vif) 3987*7ac9a364SKalle Valo { 3988*7ac9a364SKalle Valo if (band == IEEE80211_BAND_5GHZ) { 3989*7ac9a364SKalle Valo il->staging.flags &= 3990*7ac9a364SKalle Valo ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 3991*7ac9a364SKalle Valo RXON_FLG_CCK_MSK); 3992*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 3993*7ac9a364SKalle Valo } else { 3994*7ac9a364SKalle Valo /* Copied from il_post_associate() */ 3995*7ac9a364SKalle Valo if (vif && vif->bss_conf.use_short_slot) 3996*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 3997*7ac9a364SKalle Valo else 3998*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3999*7ac9a364SKalle Valo 4000*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_BAND_24G_MSK; 4001*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; 4002*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_CCK_MSK; 4003*7ac9a364SKalle Valo } 4004*7ac9a364SKalle Valo } 4005*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_flags_for_band); 4006*7ac9a364SKalle Valo 4007*7ac9a364SKalle Valo /* 4008*7ac9a364SKalle Valo * initialize rxon structure with default values from eeprom 4009*7ac9a364SKalle Valo */ 4010*7ac9a364SKalle Valo void 4011*7ac9a364SKalle Valo il_connection_init_rx_config(struct il_priv *il) 4012*7ac9a364SKalle Valo { 4013*7ac9a364SKalle Valo const struct il_channel_info *ch_info; 4014*7ac9a364SKalle Valo 4015*7ac9a364SKalle Valo memset(&il->staging, 0, sizeof(il->staging)); 4016*7ac9a364SKalle Valo 4017*7ac9a364SKalle Valo switch (il->iw_mode) { 4018*7ac9a364SKalle Valo case NL80211_IFTYPE_UNSPECIFIED: 4019*7ac9a364SKalle Valo il->staging.dev_type = RXON_DEV_TYPE_ESS; 4020*7ac9a364SKalle Valo break; 4021*7ac9a364SKalle Valo case NL80211_IFTYPE_STATION: 4022*7ac9a364SKalle Valo il->staging.dev_type = RXON_DEV_TYPE_ESS; 4023*7ac9a364SKalle Valo il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; 4024*7ac9a364SKalle Valo break; 4025*7ac9a364SKalle Valo case NL80211_IFTYPE_ADHOC: 4026*7ac9a364SKalle Valo il->staging.dev_type = RXON_DEV_TYPE_IBSS; 4027*7ac9a364SKalle Valo il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; 4028*7ac9a364SKalle Valo il->staging.filter_flags = 4029*7ac9a364SKalle Valo RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; 4030*7ac9a364SKalle Valo break; 4031*7ac9a364SKalle Valo default: 4032*7ac9a364SKalle Valo IL_ERR("Unsupported interface type %d\n", il->vif->type); 4033*7ac9a364SKalle Valo return; 4034*7ac9a364SKalle Valo } 4035*7ac9a364SKalle Valo 4036*7ac9a364SKalle Valo #if 0 4037*7ac9a364SKalle Valo /* TODO: Figure out when short_preamble would be set and cache from 4038*7ac9a364SKalle Valo * that */ 4039*7ac9a364SKalle Valo if (!hw_to_local(il->hw)->short_preamble) 4040*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 4041*7ac9a364SKalle Valo else 4042*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 4043*7ac9a364SKalle Valo #endif 4044*7ac9a364SKalle Valo 4045*7ac9a364SKalle Valo ch_info = 4046*7ac9a364SKalle Valo il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel)); 4047*7ac9a364SKalle Valo 4048*7ac9a364SKalle Valo if (!ch_info) 4049*7ac9a364SKalle Valo ch_info = &il->channel_info[0]; 4050*7ac9a364SKalle Valo 4051*7ac9a364SKalle Valo il->staging.channel = cpu_to_le16(ch_info->channel); 4052*7ac9a364SKalle Valo il->band = ch_info->band; 4053*7ac9a364SKalle Valo 4054*7ac9a364SKalle Valo il_set_flags_for_band(il, il->band, il->vif); 4055*7ac9a364SKalle Valo 4056*7ac9a364SKalle Valo il->staging.ofdm_basic_rates = 4057*7ac9a364SKalle Valo (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; 4058*7ac9a364SKalle Valo il->staging.cck_basic_rates = 4059*7ac9a364SKalle Valo (IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; 4060*7ac9a364SKalle Valo 4061*7ac9a364SKalle Valo /* clear both MIX and PURE40 mode flag */ 4062*7ac9a364SKalle Valo il->staging.flags &= 4063*7ac9a364SKalle Valo ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); 4064*7ac9a364SKalle Valo if (il->vif) 4065*7ac9a364SKalle Valo memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN); 4066*7ac9a364SKalle Valo 4067*7ac9a364SKalle Valo il->staging.ofdm_ht_single_stream_basic_rates = 0xff; 4068*7ac9a364SKalle Valo il->staging.ofdm_ht_dual_stream_basic_rates = 0xff; 4069*7ac9a364SKalle Valo } 4070*7ac9a364SKalle Valo EXPORT_SYMBOL(il_connection_init_rx_config); 4071*7ac9a364SKalle Valo 4072*7ac9a364SKalle Valo void 4073*7ac9a364SKalle Valo il_set_rate(struct il_priv *il) 4074*7ac9a364SKalle Valo { 4075*7ac9a364SKalle Valo const struct ieee80211_supported_band *hw = NULL; 4076*7ac9a364SKalle Valo struct ieee80211_rate *rate; 4077*7ac9a364SKalle Valo int i; 4078*7ac9a364SKalle Valo 4079*7ac9a364SKalle Valo hw = il_get_hw_mode(il, il->band); 4080*7ac9a364SKalle Valo if (!hw) { 4081*7ac9a364SKalle Valo IL_ERR("Failed to set rate: unable to get hw mode\n"); 4082*7ac9a364SKalle Valo return; 4083*7ac9a364SKalle Valo } 4084*7ac9a364SKalle Valo 4085*7ac9a364SKalle Valo il->active_rate = 0; 4086*7ac9a364SKalle Valo 4087*7ac9a364SKalle Valo for (i = 0; i < hw->n_bitrates; i++) { 4088*7ac9a364SKalle Valo rate = &(hw->bitrates[i]); 4089*7ac9a364SKalle Valo if (rate->hw_value < RATE_COUNT_LEGACY) 4090*7ac9a364SKalle Valo il->active_rate |= (1 << rate->hw_value); 4091*7ac9a364SKalle Valo } 4092*7ac9a364SKalle Valo 4093*7ac9a364SKalle Valo D_RATE("Set active_rate = %0x\n", il->active_rate); 4094*7ac9a364SKalle Valo 4095*7ac9a364SKalle Valo il->staging.cck_basic_rates = 4096*7ac9a364SKalle Valo (IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; 4097*7ac9a364SKalle Valo 4098*7ac9a364SKalle Valo il->staging.ofdm_basic_rates = 4099*7ac9a364SKalle Valo (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; 4100*7ac9a364SKalle Valo } 4101*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_rate); 4102*7ac9a364SKalle Valo 4103*7ac9a364SKalle Valo void 4104*7ac9a364SKalle Valo il_chswitch_done(struct il_priv *il, bool is_success) 4105*7ac9a364SKalle Valo { 4106*7ac9a364SKalle Valo if (test_bit(S_EXIT_PENDING, &il->status)) 4107*7ac9a364SKalle Valo return; 4108*7ac9a364SKalle Valo 4109*7ac9a364SKalle Valo if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) 4110*7ac9a364SKalle Valo ieee80211_chswitch_done(il->vif, is_success); 4111*7ac9a364SKalle Valo } 4112*7ac9a364SKalle Valo EXPORT_SYMBOL(il_chswitch_done); 4113*7ac9a364SKalle Valo 4114*7ac9a364SKalle Valo void 4115*7ac9a364SKalle Valo il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb) 4116*7ac9a364SKalle Valo { 4117*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 4118*7ac9a364SKalle Valo struct il_csa_notification *csa = &(pkt->u.csa_notif); 4119*7ac9a364SKalle Valo struct il_rxon_cmd *rxon = (void *)&il->active; 4120*7ac9a364SKalle Valo 4121*7ac9a364SKalle Valo if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) 4122*7ac9a364SKalle Valo return; 4123*7ac9a364SKalle Valo 4124*7ac9a364SKalle Valo if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) { 4125*7ac9a364SKalle Valo rxon->channel = csa->channel; 4126*7ac9a364SKalle Valo il->staging.channel = csa->channel; 4127*7ac9a364SKalle Valo D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel)); 4128*7ac9a364SKalle Valo il_chswitch_done(il, true); 4129*7ac9a364SKalle Valo } else { 4130*7ac9a364SKalle Valo IL_ERR("CSA notif (fail) : channel %d\n", 4131*7ac9a364SKalle Valo le16_to_cpu(csa->channel)); 4132*7ac9a364SKalle Valo il_chswitch_done(il, false); 4133*7ac9a364SKalle Valo } 4134*7ac9a364SKalle Valo } 4135*7ac9a364SKalle Valo EXPORT_SYMBOL(il_hdl_csa); 4136*7ac9a364SKalle Valo 4137*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 4138*7ac9a364SKalle Valo void 4139*7ac9a364SKalle Valo il_print_rx_config_cmd(struct il_priv *il) 4140*7ac9a364SKalle Valo { 4141*7ac9a364SKalle Valo struct il_rxon_cmd *rxon = &il->staging; 4142*7ac9a364SKalle Valo 4143*7ac9a364SKalle Valo D_RADIO("RX CONFIG:\n"); 4144*7ac9a364SKalle Valo il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); 4145*7ac9a364SKalle Valo D_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); 4146*7ac9a364SKalle Valo D_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); 4147*7ac9a364SKalle Valo D_RADIO("u32 filter_flags: 0x%08x\n", le32_to_cpu(rxon->filter_flags)); 4148*7ac9a364SKalle Valo D_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type); 4149*7ac9a364SKalle Valo D_RADIO("u8 ofdm_basic_rates: 0x%02x\n", rxon->ofdm_basic_rates); 4150*7ac9a364SKalle Valo D_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates); 4151*7ac9a364SKalle Valo D_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr); 4152*7ac9a364SKalle Valo D_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr); 4153*7ac9a364SKalle Valo D_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); 4154*7ac9a364SKalle Valo } 4155*7ac9a364SKalle Valo EXPORT_SYMBOL(il_print_rx_config_cmd); 4156*7ac9a364SKalle Valo #endif 4157*7ac9a364SKalle Valo /** 4158*7ac9a364SKalle Valo * il_irq_handle_error - called for HW or SW error interrupt from card 4159*7ac9a364SKalle Valo */ 4160*7ac9a364SKalle Valo void 4161*7ac9a364SKalle Valo il_irq_handle_error(struct il_priv *il) 4162*7ac9a364SKalle Valo { 4163*7ac9a364SKalle Valo /* Set the FW error flag -- cleared on il_down */ 4164*7ac9a364SKalle Valo set_bit(S_FW_ERROR, &il->status); 4165*7ac9a364SKalle Valo 4166*7ac9a364SKalle Valo /* Cancel currently queued command. */ 4167*7ac9a364SKalle Valo clear_bit(S_HCMD_ACTIVE, &il->status); 4168*7ac9a364SKalle Valo 4169*7ac9a364SKalle Valo IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version); 4170*7ac9a364SKalle Valo 4171*7ac9a364SKalle Valo il->ops->dump_nic_error_log(il); 4172*7ac9a364SKalle Valo if (il->ops->dump_fh) 4173*7ac9a364SKalle Valo il->ops->dump_fh(il, NULL, false); 4174*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 4175*7ac9a364SKalle Valo if (il_get_debug_level(il) & IL_DL_FW_ERRORS) 4176*7ac9a364SKalle Valo il_print_rx_config_cmd(il); 4177*7ac9a364SKalle Valo #endif 4178*7ac9a364SKalle Valo 4179*7ac9a364SKalle Valo wake_up(&il->wait_command_queue); 4180*7ac9a364SKalle Valo 4181*7ac9a364SKalle Valo /* Keep the restart process from trying to send host 4182*7ac9a364SKalle Valo * commands by clearing the INIT status bit */ 4183*7ac9a364SKalle Valo clear_bit(S_READY, &il->status); 4184*7ac9a364SKalle Valo 4185*7ac9a364SKalle Valo if (!test_bit(S_EXIT_PENDING, &il->status)) { 4186*7ac9a364SKalle Valo IL_DBG(IL_DL_FW_ERRORS, 4187*7ac9a364SKalle Valo "Restarting adapter due to uCode error.\n"); 4188*7ac9a364SKalle Valo 4189*7ac9a364SKalle Valo if (il->cfg->mod_params->restart_fw) 4190*7ac9a364SKalle Valo queue_work(il->workqueue, &il->restart); 4191*7ac9a364SKalle Valo } 4192*7ac9a364SKalle Valo } 4193*7ac9a364SKalle Valo EXPORT_SYMBOL(il_irq_handle_error); 4194*7ac9a364SKalle Valo 4195*7ac9a364SKalle Valo static int 4196*7ac9a364SKalle Valo _il_apm_stop_master(struct il_priv *il) 4197*7ac9a364SKalle Valo { 4198*7ac9a364SKalle Valo int ret = 0; 4199*7ac9a364SKalle Valo 4200*7ac9a364SKalle Valo /* stop device's busmaster DMA activity */ 4201*7ac9a364SKalle Valo _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); 4202*7ac9a364SKalle Valo 4203*7ac9a364SKalle Valo ret = 4204*7ac9a364SKalle Valo _il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, 4205*7ac9a364SKalle Valo CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); 4206*7ac9a364SKalle Valo if (ret < 0) 4207*7ac9a364SKalle Valo IL_WARN("Master Disable Timed Out, 100 usec\n"); 4208*7ac9a364SKalle Valo 4209*7ac9a364SKalle Valo D_INFO("stop master\n"); 4210*7ac9a364SKalle Valo 4211*7ac9a364SKalle Valo return ret; 4212*7ac9a364SKalle Valo } 4213*7ac9a364SKalle Valo 4214*7ac9a364SKalle Valo void 4215*7ac9a364SKalle Valo _il_apm_stop(struct il_priv *il) 4216*7ac9a364SKalle Valo { 4217*7ac9a364SKalle Valo lockdep_assert_held(&il->reg_lock); 4218*7ac9a364SKalle Valo 4219*7ac9a364SKalle Valo D_INFO("Stop card, put in low power state\n"); 4220*7ac9a364SKalle Valo 4221*7ac9a364SKalle Valo /* Stop device's DMA activity */ 4222*7ac9a364SKalle Valo _il_apm_stop_master(il); 4223*7ac9a364SKalle Valo 4224*7ac9a364SKalle Valo /* Reset the entire device */ 4225*7ac9a364SKalle Valo _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 4226*7ac9a364SKalle Valo 4227*7ac9a364SKalle Valo udelay(10); 4228*7ac9a364SKalle Valo 4229*7ac9a364SKalle Valo /* 4230*7ac9a364SKalle Valo * Clear "initialization complete" bit to move adapter from 4231*7ac9a364SKalle Valo * D0A* (powered-up Active) --> D0U* (Uninitialized) state. 4232*7ac9a364SKalle Valo */ 4233*7ac9a364SKalle Valo _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 4234*7ac9a364SKalle Valo } 4235*7ac9a364SKalle Valo EXPORT_SYMBOL(_il_apm_stop); 4236*7ac9a364SKalle Valo 4237*7ac9a364SKalle Valo void 4238*7ac9a364SKalle Valo il_apm_stop(struct il_priv *il) 4239*7ac9a364SKalle Valo { 4240*7ac9a364SKalle Valo unsigned long flags; 4241*7ac9a364SKalle Valo 4242*7ac9a364SKalle Valo spin_lock_irqsave(&il->reg_lock, flags); 4243*7ac9a364SKalle Valo _il_apm_stop(il); 4244*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->reg_lock, flags); 4245*7ac9a364SKalle Valo } 4246*7ac9a364SKalle Valo EXPORT_SYMBOL(il_apm_stop); 4247*7ac9a364SKalle Valo 4248*7ac9a364SKalle Valo /* 4249*7ac9a364SKalle Valo * Start up NIC's basic functionality after it has been reset 4250*7ac9a364SKalle Valo * (e.g. after platform boot, or shutdown via il_apm_stop()) 4251*7ac9a364SKalle Valo * NOTE: This does not load uCode nor start the embedded processor 4252*7ac9a364SKalle Valo */ 4253*7ac9a364SKalle Valo int 4254*7ac9a364SKalle Valo il_apm_init(struct il_priv *il) 4255*7ac9a364SKalle Valo { 4256*7ac9a364SKalle Valo int ret = 0; 4257*7ac9a364SKalle Valo u16 lctl; 4258*7ac9a364SKalle Valo 4259*7ac9a364SKalle Valo D_INFO("Init card's basic functions\n"); 4260*7ac9a364SKalle Valo 4261*7ac9a364SKalle Valo /* 4262*7ac9a364SKalle Valo * Use "set_bit" below rather than "write", to preserve any hardware 4263*7ac9a364SKalle Valo * bits already set by default after reset. 4264*7ac9a364SKalle Valo */ 4265*7ac9a364SKalle Valo 4266*7ac9a364SKalle Valo /* Disable L0S exit timer (platform NMI Work/Around) */ 4267*7ac9a364SKalle Valo il_set_bit(il, CSR_GIO_CHICKEN_BITS, 4268*7ac9a364SKalle Valo CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); 4269*7ac9a364SKalle Valo 4270*7ac9a364SKalle Valo /* 4271*7ac9a364SKalle Valo * Disable L0s without affecting L1; 4272*7ac9a364SKalle Valo * don't wait for ICH L0s (ICH bug W/A) 4273*7ac9a364SKalle Valo */ 4274*7ac9a364SKalle Valo il_set_bit(il, CSR_GIO_CHICKEN_BITS, 4275*7ac9a364SKalle Valo CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); 4276*7ac9a364SKalle Valo 4277*7ac9a364SKalle Valo /* Set FH wait threshold to maximum (HW error during stress W/A) */ 4278*7ac9a364SKalle Valo il_set_bit(il, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); 4279*7ac9a364SKalle Valo 4280*7ac9a364SKalle Valo /* 4281*7ac9a364SKalle Valo * Enable HAP INTA (interrupt from management bus) to 4282*7ac9a364SKalle Valo * wake device's PCI Express link L1a -> L0s 4283*7ac9a364SKalle Valo * NOTE: This is no-op for 3945 (non-existent bit) 4284*7ac9a364SKalle Valo */ 4285*7ac9a364SKalle Valo il_set_bit(il, CSR_HW_IF_CONFIG_REG, 4286*7ac9a364SKalle Valo CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); 4287*7ac9a364SKalle Valo 4288*7ac9a364SKalle Valo /* 4289*7ac9a364SKalle Valo * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition. 4290*7ac9a364SKalle Valo * Check if BIOS (or OS) enabled L1-ASPM on this device. 4291*7ac9a364SKalle Valo * If so (likely), disable L0S, so device moves directly L0->L1; 4292*7ac9a364SKalle Valo * costs negligible amount of power savings. 4293*7ac9a364SKalle Valo * If not (unlikely), enable L0S, so there is at least some 4294*7ac9a364SKalle Valo * power savings, even without L1. 4295*7ac9a364SKalle Valo */ 4296*7ac9a364SKalle Valo if (il->cfg->set_l0s) { 4297*7ac9a364SKalle Valo pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); 4298*7ac9a364SKalle Valo if (lctl & PCI_EXP_LNKCTL_ASPM_L1) { 4299*7ac9a364SKalle Valo /* L1-ASPM enabled; disable(!) L0S */ 4300*7ac9a364SKalle Valo il_set_bit(il, CSR_GIO_REG, 4301*7ac9a364SKalle Valo CSR_GIO_REG_VAL_L0S_ENABLED); 4302*7ac9a364SKalle Valo D_POWER("L1 Enabled; Disabling L0S\n"); 4303*7ac9a364SKalle Valo } else { 4304*7ac9a364SKalle Valo /* L1-ASPM disabled; enable(!) L0S */ 4305*7ac9a364SKalle Valo il_clear_bit(il, CSR_GIO_REG, 4306*7ac9a364SKalle Valo CSR_GIO_REG_VAL_L0S_ENABLED); 4307*7ac9a364SKalle Valo D_POWER("L1 Disabled; Enabling L0S\n"); 4308*7ac9a364SKalle Valo } 4309*7ac9a364SKalle Valo } 4310*7ac9a364SKalle Valo 4311*7ac9a364SKalle Valo /* Configure analog phase-lock-loop before activating to D0A */ 4312*7ac9a364SKalle Valo if (il->cfg->pll_cfg_val) 4313*7ac9a364SKalle Valo il_set_bit(il, CSR_ANA_PLL_CFG, 4314*7ac9a364SKalle Valo il->cfg->pll_cfg_val); 4315*7ac9a364SKalle Valo 4316*7ac9a364SKalle Valo /* 4317*7ac9a364SKalle Valo * Set "initialization complete" bit to move adapter from 4318*7ac9a364SKalle Valo * D0U* --> D0A* (powered-up active) state. 4319*7ac9a364SKalle Valo */ 4320*7ac9a364SKalle Valo il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 4321*7ac9a364SKalle Valo 4322*7ac9a364SKalle Valo /* 4323*7ac9a364SKalle Valo * Wait for clock stabilization; once stabilized, access to 4324*7ac9a364SKalle Valo * device-internal resources is supported, e.g. il_wr_prph() 4325*7ac9a364SKalle Valo * and accesses to uCode SRAM. 4326*7ac9a364SKalle Valo */ 4327*7ac9a364SKalle Valo ret = 4328*7ac9a364SKalle Valo _il_poll_bit(il, CSR_GP_CNTRL, 4329*7ac9a364SKalle Valo CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 4330*7ac9a364SKalle Valo CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); 4331*7ac9a364SKalle Valo if (ret < 0) { 4332*7ac9a364SKalle Valo D_INFO("Failed to init the card\n"); 4333*7ac9a364SKalle Valo goto out; 4334*7ac9a364SKalle Valo } 4335*7ac9a364SKalle Valo 4336*7ac9a364SKalle Valo /* 4337*7ac9a364SKalle Valo * Enable DMA and BSM (if used) clocks, wait for them to stabilize. 4338*7ac9a364SKalle Valo * BSM (Boostrap State Machine) is only in 3945 and 4965. 4339*7ac9a364SKalle Valo * 4340*7ac9a364SKalle Valo * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits 4341*7ac9a364SKalle Valo * do not disable clocks. This preserves any hardware bits already 4342*7ac9a364SKalle Valo * set by default in "CLK_CTRL_REG" after reset. 4343*7ac9a364SKalle Valo */ 4344*7ac9a364SKalle Valo if (il->cfg->use_bsm) 4345*7ac9a364SKalle Valo il_wr_prph(il, APMG_CLK_EN_REG, 4346*7ac9a364SKalle Valo APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); 4347*7ac9a364SKalle Valo else 4348*7ac9a364SKalle Valo il_wr_prph(il, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); 4349*7ac9a364SKalle Valo udelay(20); 4350*7ac9a364SKalle Valo 4351*7ac9a364SKalle Valo /* Disable L1-Active */ 4352*7ac9a364SKalle Valo il_set_bits_prph(il, APMG_PCIDEV_STT_REG, 4353*7ac9a364SKalle Valo APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 4354*7ac9a364SKalle Valo 4355*7ac9a364SKalle Valo out: 4356*7ac9a364SKalle Valo return ret; 4357*7ac9a364SKalle Valo } 4358*7ac9a364SKalle Valo EXPORT_SYMBOL(il_apm_init); 4359*7ac9a364SKalle Valo 4360*7ac9a364SKalle Valo int 4361*7ac9a364SKalle Valo il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) 4362*7ac9a364SKalle Valo { 4363*7ac9a364SKalle Valo int ret; 4364*7ac9a364SKalle Valo s8 prev_tx_power; 4365*7ac9a364SKalle Valo bool defer; 4366*7ac9a364SKalle Valo 4367*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 4368*7ac9a364SKalle Valo 4369*7ac9a364SKalle Valo if (il->tx_power_user_lmt == tx_power && !force) 4370*7ac9a364SKalle Valo return 0; 4371*7ac9a364SKalle Valo 4372*7ac9a364SKalle Valo if (!il->ops->send_tx_power) 4373*7ac9a364SKalle Valo return -EOPNOTSUPP; 4374*7ac9a364SKalle Valo 4375*7ac9a364SKalle Valo /* 0 dBm mean 1 milliwatt */ 4376*7ac9a364SKalle Valo if (tx_power < 0) { 4377*7ac9a364SKalle Valo IL_WARN("Requested user TXPOWER %d below 1 mW.\n", tx_power); 4378*7ac9a364SKalle Valo return -EINVAL; 4379*7ac9a364SKalle Valo } 4380*7ac9a364SKalle Valo 4381*7ac9a364SKalle Valo if (tx_power > il->tx_power_device_lmt) { 4382*7ac9a364SKalle Valo IL_WARN("Requested user TXPOWER %d above upper limit %d.\n", 4383*7ac9a364SKalle Valo tx_power, il->tx_power_device_lmt); 4384*7ac9a364SKalle Valo return -EINVAL; 4385*7ac9a364SKalle Valo } 4386*7ac9a364SKalle Valo 4387*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) 4388*7ac9a364SKalle Valo return -EIO; 4389*7ac9a364SKalle Valo 4390*7ac9a364SKalle Valo /* scan complete and commit_rxon use tx_power_next value, 4391*7ac9a364SKalle Valo * it always need to be updated for newest request */ 4392*7ac9a364SKalle Valo il->tx_power_next = tx_power; 4393*7ac9a364SKalle Valo 4394*7ac9a364SKalle Valo /* do not set tx power when scanning or channel changing */ 4395*7ac9a364SKalle Valo defer = test_bit(S_SCANNING, &il->status) || 4396*7ac9a364SKalle Valo memcmp(&il->active, &il->staging, sizeof(il->staging)); 4397*7ac9a364SKalle Valo if (defer && !force) { 4398*7ac9a364SKalle Valo D_INFO("Deferring tx power set\n"); 4399*7ac9a364SKalle Valo return 0; 4400*7ac9a364SKalle Valo } 4401*7ac9a364SKalle Valo 4402*7ac9a364SKalle Valo prev_tx_power = il->tx_power_user_lmt; 4403*7ac9a364SKalle Valo il->tx_power_user_lmt = tx_power; 4404*7ac9a364SKalle Valo 4405*7ac9a364SKalle Valo ret = il->ops->send_tx_power(il); 4406*7ac9a364SKalle Valo 4407*7ac9a364SKalle Valo /* if fail to set tx_power, restore the orig. tx power */ 4408*7ac9a364SKalle Valo if (ret) { 4409*7ac9a364SKalle Valo il->tx_power_user_lmt = prev_tx_power; 4410*7ac9a364SKalle Valo il->tx_power_next = prev_tx_power; 4411*7ac9a364SKalle Valo } 4412*7ac9a364SKalle Valo return ret; 4413*7ac9a364SKalle Valo } 4414*7ac9a364SKalle Valo EXPORT_SYMBOL(il_set_tx_power); 4415*7ac9a364SKalle Valo 4416*7ac9a364SKalle Valo void 4417*7ac9a364SKalle Valo il_send_bt_config(struct il_priv *il) 4418*7ac9a364SKalle Valo { 4419*7ac9a364SKalle Valo struct il_bt_cmd bt_cmd = { 4420*7ac9a364SKalle Valo .lead_time = BT_LEAD_TIME_DEF, 4421*7ac9a364SKalle Valo .max_kill = BT_MAX_KILL_DEF, 4422*7ac9a364SKalle Valo .kill_ack_mask = 0, 4423*7ac9a364SKalle Valo .kill_cts_mask = 0, 4424*7ac9a364SKalle Valo }; 4425*7ac9a364SKalle Valo 4426*7ac9a364SKalle Valo if (!bt_coex_active) 4427*7ac9a364SKalle Valo bt_cmd.flags = BT_COEX_DISABLE; 4428*7ac9a364SKalle Valo else 4429*7ac9a364SKalle Valo bt_cmd.flags = BT_COEX_ENABLE; 4430*7ac9a364SKalle Valo 4431*7ac9a364SKalle Valo D_INFO("BT coex %s\n", 4432*7ac9a364SKalle Valo (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); 4433*7ac9a364SKalle Valo 4434*7ac9a364SKalle Valo if (il_send_cmd_pdu(il, C_BT_CONFIG, sizeof(struct il_bt_cmd), &bt_cmd)) 4435*7ac9a364SKalle Valo IL_ERR("failed to send BT Coex Config\n"); 4436*7ac9a364SKalle Valo } 4437*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_bt_config); 4438*7ac9a364SKalle Valo 4439*7ac9a364SKalle Valo int 4440*7ac9a364SKalle Valo il_send_stats_request(struct il_priv *il, u8 flags, bool clear) 4441*7ac9a364SKalle Valo { 4442*7ac9a364SKalle Valo struct il_stats_cmd stats_cmd = { 4443*7ac9a364SKalle Valo .configuration_flags = clear ? IL_STATS_CONF_CLEAR_STATS : 0, 4444*7ac9a364SKalle Valo }; 4445*7ac9a364SKalle Valo 4446*7ac9a364SKalle Valo if (flags & CMD_ASYNC) 4447*7ac9a364SKalle Valo return il_send_cmd_pdu_async(il, C_STATS, sizeof(struct il_stats_cmd), 4448*7ac9a364SKalle Valo &stats_cmd, NULL); 4449*7ac9a364SKalle Valo else 4450*7ac9a364SKalle Valo return il_send_cmd_pdu(il, C_STATS, sizeof(struct il_stats_cmd), 4451*7ac9a364SKalle Valo &stats_cmd); 4452*7ac9a364SKalle Valo } 4453*7ac9a364SKalle Valo EXPORT_SYMBOL(il_send_stats_request); 4454*7ac9a364SKalle Valo 4455*7ac9a364SKalle Valo void 4456*7ac9a364SKalle Valo il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb) 4457*7ac9a364SKalle Valo { 4458*7ac9a364SKalle Valo #ifdef CONFIG_IWLEGACY_DEBUG 4459*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 4460*7ac9a364SKalle Valo struct il_sleep_notification *sleep = &(pkt->u.sleep_notif); 4461*7ac9a364SKalle Valo D_RX("sleep mode: %d, src: %d\n", 4462*7ac9a364SKalle Valo sleep->pm_sleep_mode, sleep->pm_wakeup_src); 4463*7ac9a364SKalle Valo #endif 4464*7ac9a364SKalle Valo } 4465*7ac9a364SKalle Valo EXPORT_SYMBOL(il_hdl_pm_sleep); 4466*7ac9a364SKalle Valo 4467*7ac9a364SKalle Valo void 4468*7ac9a364SKalle Valo il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb) 4469*7ac9a364SKalle Valo { 4470*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 4471*7ac9a364SKalle Valo u32 len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK; 4472*7ac9a364SKalle Valo D_RADIO("Dumping %d bytes of unhandled notification for %s:\n", len, 4473*7ac9a364SKalle Valo il_get_cmd_string(pkt->hdr.cmd)); 4474*7ac9a364SKalle Valo il_print_hex_dump(il, IL_DL_RADIO, pkt->u.raw, len); 4475*7ac9a364SKalle Valo } 4476*7ac9a364SKalle Valo EXPORT_SYMBOL(il_hdl_pm_debug_stats); 4477*7ac9a364SKalle Valo 4478*7ac9a364SKalle Valo void 4479*7ac9a364SKalle Valo il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb) 4480*7ac9a364SKalle Valo { 4481*7ac9a364SKalle Valo struct il_rx_pkt *pkt = rxb_addr(rxb); 4482*7ac9a364SKalle Valo 4483*7ac9a364SKalle Valo IL_ERR("Error Reply type 0x%08X cmd %s (0x%02X) " 4484*7ac9a364SKalle Valo "seq 0x%04X ser 0x%08X\n", 4485*7ac9a364SKalle Valo le32_to_cpu(pkt->u.err_resp.error_type), 4486*7ac9a364SKalle Valo il_get_cmd_string(pkt->u.err_resp.cmd_id), 4487*7ac9a364SKalle Valo pkt->u.err_resp.cmd_id, 4488*7ac9a364SKalle Valo le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), 4489*7ac9a364SKalle Valo le32_to_cpu(pkt->u.err_resp.error_info)); 4490*7ac9a364SKalle Valo } 4491*7ac9a364SKalle Valo EXPORT_SYMBOL(il_hdl_error); 4492*7ac9a364SKalle Valo 4493*7ac9a364SKalle Valo void 4494*7ac9a364SKalle Valo il_clear_isr_stats(struct il_priv *il) 4495*7ac9a364SKalle Valo { 4496*7ac9a364SKalle Valo memset(&il->isr_stats, 0, sizeof(il->isr_stats)); 4497*7ac9a364SKalle Valo } 4498*7ac9a364SKalle Valo 4499*7ac9a364SKalle Valo int 4500*7ac9a364SKalle Valo il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, 4501*7ac9a364SKalle Valo const struct ieee80211_tx_queue_params *params) 4502*7ac9a364SKalle Valo { 4503*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4504*7ac9a364SKalle Valo unsigned long flags; 4505*7ac9a364SKalle Valo int q; 4506*7ac9a364SKalle Valo 4507*7ac9a364SKalle Valo D_MAC80211("enter\n"); 4508*7ac9a364SKalle Valo 4509*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) { 4510*7ac9a364SKalle Valo D_MAC80211("leave - RF not ready\n"); 4511*7ac9a364SKalle Valo return -EIO; 4512*7ac9a364SKalle Valo } 4513*7ac9a364SKalle Valo 4514*7ac9a364SKalle Valo if (queue >= AC_NUM) { 4515*7ac9a364SKalle Valo D_MAC80211("leave - queue >= AC_NUM %d\n", queue); 4516*7ac9a364SKalle Valo return 0; 4517*7ac9a364SKalle Valo } 4518*7ac9a364SKalle Valo 4519*7ac9a364SKalle Valo q = AC_NUM - 1 - queue; 4520*7ac9a364SKalle Valo 4521*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 4522*7ac9a364SKalle Valo 4523*7ac9a364SKalle Valo il->qos_data.def_qos_parm.ac[q].cw_min = 4524*7ac9a364SKalle Valo cpu_to_le16(params->cw_min); 4525*7ac9a364SKalle Valo il->qos_data.def_qos_parm.ac[q].cw_max = 4526*7ac9a364SKalle Valo cpu_to_le16(params->cw_max); 4527*7ac9a364SKalle Valo il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; 4528*7ac9a364SKalle Valo il->qos_data.def_qos_parm.ac[q].edca_txop = 4529*7ac9a364SKalle Valo cpu_to_le16((params->txop * 32)); 4530*7ac9a364SKalle Valo 4531*7ac9a364SKalle Valo il->qos_data.def_qos_parm.ac[q].reserved1 = 0; 4532*7ac9a364SKalle Valo 4533*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 4534*7ac9a364SKalle Valo 4535*7ac9a364SKalle Valo D_MAC80211("leave\n"); 4536*7ac9a364SKalle Valo return 0; 4537*7ac9a364SKalle Valo } 4538*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_conf_tx); 4539*7ac9a364SKalle Valo 4540*7ac9a364SKalle Valo int 4541*7ac9a364SKalle Valo il_mac_tx_last_beacon(struct ieee80211_hw *hw) 4542*7ac9a364SKalle Valo { 4543*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4544*7ac9a364SKalle Valo int ret; 4545*7ac9a364SKalle Valo 4546*7ac9a364SKalle Valo D_MAC80211("enter\n"); 4547*7ac9a364SKalle Valo 4548*7ac9a364SKalle Valo ret = (il->ibss_manager == IL_IBSS_MANAGER); 4549*7ac9a364SKalle Valo 4550*7ac9a364SKalle Valo D_MAC80211("leave ret %d\n", ret); 4551*7ac9a364SKalle Valo return ret; 4552*7ac9a364SKalle Valo } 4553*7ac9a364SKalle Valo EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon); 4554*7ac9a364SKalle Valo 4555*7ac9a364SKalle Valo static int 4556*7ac9a364SKalle Valo il_set_mode(struct il_priv *il) 4557*7ac9a364SKalle Valo { 4558*7ac9a364SKalle Valo il_connection_init_rx_config(il); 4559*7ac9a364SKalle Valo 4560*7ac9a364SKalle Valo if (il->ops->set_rxon_chain) 4561*7ac9a364SKalle Valo il->ops->set_rxon_chain(il); 4562*7ac9a364SKalle Valo 4563*7ac9a364SKalle Valo return il_commit_rxon(il); 4564*7ac9a364SKalle Valo } 4565*7ac9a364SKalle Valo 4566*7ac9a364SKalle Valo int 4567*7ac9a364SKalle Valo il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 4568*7ac9a364SKalle Valo { 4569*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4570*7ac9a364SKalle Valo int err; 4571*7ac9a364SKalle Valo bool reset; 4572*7ac9a364SKalle Valo 4573*7ac9a364SKalle Valo mutex_lock(&il->mutex); 4574*7ac9a364SKalle Valo D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); 4575*7ac9a364SKalle Valo 4576*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) { 4577*7ac9a364SKalle Valo IL_WARN("Try to add interface when device not ready\n"); 4578*7ac9a364SKalle Valo err = -EINVAL; 4579*7ac9a364SKalle Valo goto out; 4580*7ac9a364SKalle Valo } 4581*7ac9a364SKalle Valo 4582*7ac9a364SKalle Valo /* 4583*7ac9a364SKalle Valo * We do not support multiple virtual interfaces, but on hardware reset 4584*7ac9a364SKalle Valo * we have to add the same interface again. 4585*7ac9a364SKalle Valo */ 4586*7ac9a364SKalle Valo reset = (il->vif == vif); 4587*7ac9a364SKalle Valo if (il->vif && !reset) { 4588*7ac9a364SKalle Valo err = -EOPNOTSUPP; 4589*7ac9a364SKalle Valo goto out; 4590*7ac9a364SKalle Valo } 4591*7ac9a364SKalle Valo 4592*7ac9a364SKalle Valo il->vif = vif; 4593*7ac9a364SKalle Valo il->iw_mode = vif->type; 4594*7ac9a364SKalle Valo 4595*7ac9a364SKalle Valo err = il_set_mode(il); 4596*7ac9a364SKalle Valo if (err) { 4597*7ac9a364SKalle Valo IL_WARN("Fail to set mode %d\n", vif->type); 4598*7ac9a364SKalle Valo if (!reset) { 4599*7ac9a364SKalle Valo il->vif = NULL; 4600*7ac9a364SKalle Valo il->iw_mode = NL80211_IFTYPE_STATION; 4601*7ac9a364SKalle Valo } 4602*7ac9a364SKalle Valo } 4603*7ac9a364SKalle Valo 4604*7ac9a364SKalle Valo out: 4605*7ac9a364SKalle Valo D_MAC80211("leave err %d\n", err); 4606*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 4607*7ac9a364SKalle Valo 4608*7ac9a364SKalle Valo return err; 4609*7ac9a364SKalle Valo } 4610*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_add_interface); 4611*7ac9a364SKalle Valo 4612*7ac9a364SKalle Valo static void 4613*7ac9a364SKalle Valo il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif) 4614*7ac9a364SKalle Valo { 4615*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 4616*7ac9a364SKalle Valo 4617*7ac9a364SKalle Valo if (il->scan_vif == vif) { 4618*7ac9a364SKalle Valo il_scan_cancel_timeout(il, 200); 4619*7ac9a364SKalle Valo il_force_scan_end(il); 4620*7ac9a364SKalle Valo } 4621*7ac9a364SKalle Valo 4622*7ac9a364SKalle Valo il_set_mode(il); 4623*7ac9a364SKalle Valo } 4624*7ac9a364SKalle Valo 4625*7ac9a364SKalle Valo void 4626*7ac9a364SKalle Valo il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 4627*7ac9a364SKalle Valo { 4628*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4629*7ac9a364SKalle Valo 4630*7ac9a364SKalle Valo mutex_lock(&il->mutex); 4631*7ac9a364SKalle Valo D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); 4632*7ac9a364SKalle Valo 4633*7ac9a364SKalle Valo WARN_ON(il->vif != vif); 4634*7ac9a364SKalle Valo il->vif = NULL; 4635*7ac9a364SKalle Valo il->iw_mode = NL80211_IFTYPE_UNSPECIFIED; 4636*7ac9a364SKalle Valo il_teardown_interface(il, vif); 4637*7ac9a364SKalle Valo eth_zero_addr(il->bssid); 4638*7ac9a364SKalle Valo 4639*7ac9a364SKalle Valo D_MAC80211("leave\n"); 4640*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 4641*7ac9a364SKalle Valo } 4642*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_remove_interface); 4643*7ac9a364SKalle Valo 4644*7ac9a364SKalle Valo int 4645*7ac9a364SKalle Valo il_alloc_txq_mem(struct il_priv *il) 4646*7ac9a364SKalle Valo { 4647*7ac9a364SKalle Valo if (!il->txq) 4648*7ac9a364SKalle Valo il->txq = 4649*7ac9a364SKalle Valo kzalloc(sizeof(struct il_tx_queue) * 4650*7ac9a364SKalle Valo il->cfg->num_of_queues, GFP_KERNEL); 4651*7ac9a364SKalle Valo if (!il->txq) { 4652*7ac9a364SKalle Valo IL_ERR("Not enough memory for txq\n"); 4653*7ac9a364SKalle Valo return -ENOMEM; 4654*7ac9a364SKalle Valo } 4655*7ac9a364SKalle Valo return 0; 4656*7ac9a364SKalle Valo } 4657*7ac9a364SKalle Valo EXPORT_SYMBOL(il_alloc_txq_mem); 4658*7ac9a364SKalle Valo 4659*7ac9a364SKalle Valo void 4660*7ac9a364SKalle Valo il_free_txq_mem(struct il_priv *il) 4661*7ac9a364SKalle Valo { 4662*7ac9a364SKalle Valo kfree(il->txq); 4663*7ac9a364SKalle Valo il->txq = NULL; 4664*7ac9a364SKalle Valo } 4665*7ac9a364SKalle Valo EXPORT_SYMBOL(il_free_txq_mem); 4666*7ac9a364SKalle Valo 4667*7ac9a364SKalle Valo int 4668*7ac9a364SKalle Valo il_force_reset(struct il_priv *il, bool external) 4669*7ac9a364SKalle Valo { 4670*7ac9a364SKalle Valo struct il_force_reset *force_reset; 4671*7ac9a364SKalle Valo 4672*7ac9a364SKalle Valo if (test_bit(S_EXIT_PENDING, &il->status)) 4673*7ac9a364SKalle Valo return -EINVAL; 4674*7ac9a364SKalle Valo 4675*7ac9a364SKalle Valo force_reset = &il->force_reset; 4676*7ac9a364SKalle Valo force_reset->reset_request_count++; 4677*7ac9a364SKalle Valo if (!external) { 4678*7ac9a364SKalle Valo if (force_reset->last_force_reset_jiffies && 4679*7ac9a364SKalle Valo time_after(force_reset->last_force_reset_jiffies + 4680*7ac9a364SKalle Valo force_reset->reset_duration, jiffies)) { 4681*7ac9a364SKalle Valo D_INFO("force reset rejected\n"); 4682*7ac9a364SKalle Valo force_reset->reset_reject_count++; 4683*7ac9a364SKalle Valo return -EAGAIN; 4684*7ac9a364SKalle Valo } 4685*7ac9a364SKalle Valo } 4686*7ac9a364SKalle Valo force_reset->reset_success_count++; 4687*7ac9a364SKalle Valo force_reset->last_force_reset_jiffies = jiffies; 4688*7ac9a364SKalle Valo 4689*7ac9a364SKalle Valo /* 4690*7ac9a364SKalle Valo * if the request is from external(ex: debugfs), 4691*7ac9a364SKalle Valo * then always perform the request in regardless the module 4692*7ac9a364SKalle Valo * parameter setting 4693*7ac9a364SKalle Valo * if the request is from internal (uCode error or driver 4694*7ac9a364SKalle Valo * detect failure), then fw_restart module parameter 4695*7ac9a364SKalle Valo * need to be check before performing firmware reload 4696*7ac9a364SKalle Valo */ 4697*7ac9a364SKalle Valo 4698*7ac9a364SKalle Valo if (!external && !il->cfg->mod_params->restart_fw) { 4699*7ac9a364SKalle Valo D_INFO("Cancel firmware reload based on " 4700*7ac9a364SKalle Valo "module parameter setting\n"); 4701*7ac9a364SKalle Valo return 0; 4702*7ac9a364SKalle Valo } 4703*7ac9a364SKalle Valo 4704*7ac9a364SKalle Valo IL_ERR("On demand firmware reload\n"); 4705*7ac9a364SKalle Valo 4706*7ac9a364SKalle Valo /* Set the FW error flag -- cleared on il_down */ 4707*7ac9a364SKalle Valo set_bit(S_FW_ERROR, &il->status); 4708*7ac9a364SKalle Valo wake_up(&il->wait_command_queue); 4709*7ac9a364SKalle Valo /* 4710*7ac9a364SKalle Valo * Keep the restart process from trying to send host 4711*7ac9a364SKalle Valo * commands by clearing the INIT status bit 4712*7ac9a364SKalle Valo */ 4713*7ac9a364SKalle Valo clear_bit(S_READY, &il->status); 4714*7ac9a364SKalle Valo queue_work(il->workqueue, &il->restart); 4715*7ac9a364SKalle Valo 4716*7ac9a364SKalle Valo return 0; 4717*7ac9a364SKalle Valo } 4718*7ac9a364SKalle Valo EXPORT_SYMBOL(il_force_reset); 4719*7ac9a364SKalle Valo 4720*7ac9a364SKalle Valo int 4721*7ac9a364SKalle Valo il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4722*7ac9a364SKalle Valo enum nl80211_iftype newtype, bool newp2p) 4723*7ac9a364SKalle Valo { 4724*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4725*7ac9a364SKalle Valo int err; 4726*7ac9a364SKalle Valo 4727*7ac9a364SKalle Valo mutex_lock(&il->mutex); 4728*7ac9a364SKalle Valo D_MAC80211("enter: type %d, addr %pM newtype %d newp2p %d\n", 4729*7ac9a364SKalle Valo vif->type, vif->addr, newtype, newp2p); 4730*7ac9a364SKalle Valo 4731*7ac9a364SKalle Valo if (newp2p) { 4732*7ac9a364SKalle Valo err = -EOPNOTSUPP; 4733*7ac9a364SKalle Valo goto out; 4734*7ac9a364SKalle Valo } 4735*7ac9a364SKalle Valo 4736*7ac9a364SKalle Valo if (!il->vif || !il_is_ready_rf(il)) { 4737*7ac9a364SKalle Valo /* 4738*7ac9a364SKalle Valo * Huh? But wait ... this can maybe happen when 4739*7ac9a364SKalle Valo * we're in the middle of a firmware restart! 4740*7ac9a364SKalle Valo */ 4741*7ac9a364SKalle Valo err = -EBUSY; 4742*7ac9a364SKalle Valo goto out; 4743*7ac9a364SKalle Valo } 4744*7ac9a364SKalle Valo 4745*7ac9a364SKalle Valo /* success */ 4746*7ac9a364SKalle Valo vif->type = newtype; 4747*7ac9a364SKalle Valo vif->p2p = false; 4748*7ac9a364SKalle Valo il->iw_mode = newtype; 4749*7ac9a364SKalle Valo il_teardown_interface(il, vif); 4750*7ac9a364SKalle Valo err = 0; 4751*7ac9a364SKalle Valo 4752*7ac9a364SKalle Valo out: 4753*7ac9a364SKalle Valo D_MAC80211("leave err %d\n", err); 4754*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 4755*7ac9a364SKalle Valo 4756*7ac9a364SKalle Valo return err; 4757*7ac9a364SKalle Valo } 4758*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_change_interface); 4759*7ac9a364SKalle Valo 4760*7ac9a364SKalle Valo void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4761*7ac9a364SKalle Valo u32 queues, bool drop) 4762*7ac9a364SKalle Valo { 4763*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 4764*7ac9a364SKalle Valo unsigned long timeout = jiffies + msecs_to_jiffies(500); 4765*7ac9a364SKalle Valo int i; 4766*7ac9a364SKalle Valo 4767*7ac9a364SKalle Valo mutex_lock(&il->mutex); 4768*7ac9a364SKalle Valo D_MAC80211("enter\n"); 4769*7ac9a364SKalle Valo 4770*7ac9a364SKalle Valo if (il->txq == NULL) 4771*7ac9a364SKalle Valo goto out; 4772*7ac9a364SKalle Valo 4773*7ac9a364SKalle Valo for (i = 0; i < il->hw_params.max_txq_num; i++) { 4774*7ac9a364SKalle Valo struct il_queue *q; 4775*7ac9a364SKalle Valo 4776*7ac9a364SKalle Valo if (i == il->cmd_queue) 4777*7ac9a364SKalle Valo continue; 4778*7ac9a364SKalle Valo 4779*7ac9a364SKalle Valo q = &il->txq[i].q; 4780*7ac9a364SKalle Valo if (q->read_ptr == q->write_ptr) 4781*7ac9a364SKalle Valo continue; 4782*7ac9a364SKalle Valo 4783*7ac9a364SKalle Valo if (time_after(jiffies, timeout)) { 4784*7ac9a364SKalle Valo IL_ERR("Failed to flush queue %d\n", q->id); 4785*7ac9a364SKalle Valo break; 4786*7ac9a364SKalle Valo } 4787*7ac9a364SKalle Valo 4788*7ac9a364SKalle Valo msleep(20); 4789*7ac9a364SKalle Valo } 4790*7ac9a364SKalle Valo out: 4791*7ac9a364SKalle Valo D_MAC80211("leave\n"); 4792*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 4793*7ac9a364SKalle Valo } 4794*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_flush); 4795*7ac9a364SKalle Valo 4796*7ac9a364SKalle Valo /* 4797*7ac9a364SKalle Valo * On every watchdog tick we check (latest) time stamp. If it does not 4798*7ac9a364SKalle Valo * change during timeout period and queue is not empty we reset firmware. 4799*7ac9a364SKalle Valo */ 4800*7ac9a364SKalle Valo static int 4801*7ac9a364SKalle Valo il_check_stuck_queue(struct il_priv *il, int cnt) 4802*7ac9a364SKalle Valo { 4803*7ac9a364SKalle Valo struct il_tx_queue *txq = &il->txq[cnt]; 4804*7ac9a364SKalle Valo struct il_queue *q = &txq->q; 4805*7ac9a364SKalle Valo unsigned long timeout; 4806*7ac9a364SKalle Valo unsigned long now = jiffies; 4807*7ac9a364SKalle Valo int ret; 4808*7ac9a364SKalle Valo 4809*7ac9a364SKalle Valo if (q->read_ptr == q->write_ptr) { 4810*7ac9a364SKalle Valo txq->time_stamp = now; 4811*7ac9a364SKalle Valo return 0; 4812*7ac9a364SKalle Valo } 4813*7ac9a364SKalle Valo 4814*7ac9a364SKalle Valo timeout = 4815*7ac9a364SKalle Valo txq->time_stamp + 4816*7ac9a364SKalle Valo msecs_to_jiffies(il->cfg->wd_timeout); 4817*7ac9a364SKalle Valo 4818*7ac9a364SKalle Valo if (time_after(now, timeout)) { 4819*7ac9a364SKalle Valo IL_ERR("Queue %d stuck for %u ms.\n", q->id, 4820*7ac9a364SKalle Valo jiffies_to_msecs(now - txq->time_stamp)); 4821*7ac9a364SKalle Valo ret = il_force_reset(il, false); 4822*7ac9a364SKalle Valo return (ret == -EAGAIN) ? 0 : 1; 4823*7ac9a364SKalle Valo } 4824*7ac9a364SKalle Valo 4825*7ac9a364SKalle Valo return 0; 4826*7ac9a364SKalle Valo } 4827*7ac9a364SKalle Valo 4828*7ac9a364SKalle Valo /* 4829*7ac9a364SKalle Valo * Making watchdog tick be a quarter of timeout assure we will 4830*7ac9a364SKalle Valo * discover the queue hung between timeout and 1.25*timeout 4831*7ac9a364SKalle Valo */ 4832*7ac9a364SKalle Valo #define IL_WD_TICK(timeout) ((timeout) / 4) 4833*7ac9a364SKalle Valo 4834*7ac9a364SKalle Valo /* 4835*7ac9a364SKalle Valo * Watchdog timer callback, we check each tx queue for stuck, if if hung 4836*7ac9a364SKalle Valo * we reset the firmware. If everything is fine just rearm the timer. 4837*7ac9a364SKalle Valo */ 4838*7ac9a364SKalle Valo void 4839*7ac9a364SKalle Valo il_bg_watchdog(unsigned long data) 4840*7ac9a364SKalle Valo { 4841*7ac9a364SKalle Valo struct il_priv *il = (struct il_priv *)data; 4842*7ac9a364SKalle Valo int cnt; 4843*7ac9a364SKalle Valo unsigned long timeout; 4844*7ac9a364SKalle Valo 4845*7ac9a364SKalle Valo if (test_bit(S_EXIT_PENDING, &il->status)) 4846*7ac9a364SKalle Valo return; 4847*7ac9a364SKalle Valo 4848*7ac9a364SKalle Valo timeout = il->cfg->wd_timeout; 4849*7ac9a364SKalle Valo if (timeout == 0) 4850*7ac9a364SKalle Valo return; 4851*7ac9a364SKalle Valo 4852*7ac9a364SKalle Valo /* monitor and check for stuck cmd queue */ 4853*7ac9a364SKalle Valo if (il_check_stuck_queue(il, il->cmd_queue)) 4854*7ac9a364SKalle Valo return; 4855*7ac9a364SKalle Valo 4856*7ac9a364SKalle Valo /* monitor and check for other stuck queues */ 4857*7ac9a364SKalle Valo for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { 4858*7ac9a364SKalle Valo /* skip as we already checked the command queue */ 4859*7ac9a364SKalle Valo if (cnt == il->cmd_queue) 4860*7ac9a364SKalle Valo continue; 4861*7ac9a364SKalle Valo if (il_check_stuck_queue(il, cnt)) 4862*7ac9a364SKalle Valo return; 4863*7ac9a364SKalle Valo } 4864*7ac9a364SKalle Valo 4865*7ac9a364SKalle Valo mod_timer(&il->watchdog, 4866*7ac9a364SKalle Valo jiffies + msecs_to_jiffies(IL_WD_TICK(timeout))); 4867*7ac9a364SKalle Valo } 4868*7ac9a364SKalle Valo EXPORT_SYMBOL(il_bg_watchdog); 4869*7ac9a364SKalle Valo 4870*7ac9a364SKalle Valo void 4871*7ac9a364SKalle Valo il_setup_watchdog(struct il_priv *il) 4872*7ac9a364SKalle Valo { 4873*7ac9a364SKalle Valo unsigned int timeout = il->cfg->wd_timeout; 4874*7ac9a364SKalle Valo 4875*7ac9a364SKalle Valo if (timeout) 4876*7ac9a364SKalle Valo mod_timer(&il->watchdog, 4877*7ac9a364SKalle Valo jiffies + msecs_to_jiffies(IL_WD_TICK(timeout))); 4878*7ac9a364SKalle Valo else 4879*7ac9a364SKalle Valo del_timer(&il->watchdog); 4880*7ac9a364SKalle Valo } 4881*7ac9a364SKalle Valo EXPORT_SYMBOL(il_setup_watchdog); 4882*7ac9a364SKalle Valo 4883*7ac9a364SKalle Valo /* 4884*7ac9a364SKalle Valo * extended beacon time format 4885*7ac9a364SKalle Valo * time in usec will be changed into a 32-bit value in extended:internal format 4886*7ac9a364SKalle Valo * the extended part is the beacon counts 4887*7ac9a364SKalle Valo * the internal part is the time in usec within one beacon interval 4888*7ac9a364SKalle Valo */ 4889*7ac9a364SKalle Valo u32 4890*7ac9a364SKalle Valo il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval) 4891*7ac9a364SKalle Valo { 4892*7ac9a364SKalle Valo u32 quot; 4893*7ac9a364SKalle Valo u32 rem; 4894*7ac9a364SKalle Valo u32 interval = beacon_interval * TIME_UNIT; 4895*7ac9a364SKalle Valo 4896*7ac9a364SKalle Valo if (!interval || !usec) 4897*7ac9a364SKalle Valo return 0; 4898*7ac9a364SKalle Valo 4899*7ac9a364SKalle Valo quot = 4900*7ac9a364SKalle Valo (usec / 4901*7ac9a364SKalle Valo interval) & (il_beacon_time_mask_high(il, 4902*7ac9a364SKalle Valo il->hw_params. 4903*7ac9a364SKalle Valo beacon_time_tsf_bits) >> il-> 4904*7ac9a364SKalle Valo hw_params.beacon_time_tsf_bits); 4905*7ac9a364SKalle Valo rem = 4906*7ac9a364SKalle Valo (usec % interval) & il_beacon_time_mask_low(il, 4907*7ac9a364SKalle Valo il->hw_params. 4908*7ac9a364SKalle Valo beacon_time_tsf_bits); 4909*7ac9a364SKalle Valo 4910*7ac9a364SKalle Valo return (quot << il->hw_params.beacon_time_tsf_bits) + rem; 4911*7ac9a364SKalle Valo } 4912*7ac9a364SKalle Valo EXPORT_SYMBOL(il_usecs_to_beacons); 4913*7ac9a364SKalle Valo 4914*7ac9a364SKalle Valo /* base is usually what we get from ucode with each received frame, 4915*7ac9a364SKalle Valo * the same as HW timer counter counting down 4916*7ac9a364SKalle Valo */ 4917*7ac9a364SKalle Valo __le32 4918*7ac9a364SKalle Valo il_add_beacon_time(struct il_priv *il, u32 base, u32 addon, 4919*7ac9a364SKalle Valo u32 beacon_interval) 4920*7ac9a364SKalle Valo { 4921*7ac9a364SKalle Valo u32 base_low = base & il_beacon_time_mask_low(il, 4922*7ac9a364SKalle Valo il->hw_params. 4923*7ac9a364SKalle Valo beacon_time_tsf_bits); 4924*7ac9a364SKalle Valo u32 addon_low = addon & il_beacon_time_mask_low(il, 4925*7ac9a364SKalle Valo il->hw_params. 4926*7ac9a364SKalle Valo beacon_time_tsf_bits); 4927*7ac9a364SKalle Valo u32 interval = beacon_interval * TIME_UNIT; 4928*7ac9a364SKalle Valo u32 res = (base & il_beacon_time_mask_high(il, 4929*7ac9a364SKalle Valo il->hw_params. 4930*7ac9a364SKalle Valo beacon_time_tsf_bits)) + 4931*7ac9a364SKalle Valo (addon & il_beacon_time_mask_high(il, 4932*7ac9a364SKalle Valo il->hw_params. 4933*7ac9a364SKalle Valo beacon_time_tsf_bits)); 4934*7ac9a364SKalle Valo 4935*7ac9a364SKalle Valo if (base_low > addon_low) 4936*7ac9a364SKalle Valo res += base_low - addon_low; 4937*7ac9a364SKalle Valo else if (base_low < addon_low) { 4938*7ac9a364SKalle Valo res += interval + base_low - addon_low; 4939*7ac9a364SKalle Valo res += (1 << il->hw_params.beacon_time_tsf_bits); 4940*7ac9a364SKalle Valo } else 4941*7ac9a364SKalle Valo res += (1 << il->hw_params.beacon_time_tsf_bits); 4942*7ac9a364SKalle Valo 4943*7ac9a364SKalle Valo return cpu_to_le32(res); 4944*7ac9a364SKalle Valo } 4945*7ac9a364SKalle Valo EXPORT_SYMBOL(il_add_beacon_time); 4946*7ac9a364SKalle Valo 4947*7ac9a364SKalle Valo #ifdef CONFIG_PM_SLEEP 4948*7ac9a364SKalle Valo 4949*7ac9a364SKalle Valo static int 4950*7ac9a364SKalle Valo il_pci_suspend(struct device *device) 4951*7ac9a364SKalle Valo { 4952*7ac9a364SKalle Valo struct pci_dev *pdev = to_pci_dev(device); 4953*7ac9a364SKalle Valo struct il_priv *il = pci_get_drvdata(pdev); 4954*7ac9a364SKalle Valo 4955*7ac9a364SKalle Valo /* 4956*7ac9a364SKalle Valo * This function is called when system goes into suspend state 4957*7ac9a364SKalle Valo * mac80211 will call il_mac_stop() from the mac80211 suspend function 4958*7ac9a364SKalle Valo * first but since il_mac_stop() has no knowledge of who the caller is, 4959*7ac9a364SKalle Valo * it will not call apm_ops.stop() to stop the DMA operation. 4960*7ac9a364SKalle Valo * Calling apm_ops.stop here to make sure we stop the DMA. 4961*7ac9a364SKalle Valo */ 4962*7ac9a364SKalle Valo il_apm_stop(il); 4963*7ac9a364SKalle Valo 4964*7ac9a364SKalle Valo return 0; 4965*7ac9a364SKalle Valo } 4966*7ac9a364SKalle Valo 4967*7ac9a364SKalle Valo static int 4968*7ac9a364SKalle Valo il_pci_resume(struct device *device) 4969*7ac9a364SKalle Valo { 4970*7ac9a364SKalle Valo struct pci_dev *pdev = to_pci_dev(device); 4971*7ac9a364SKalle Valo struct il_priv *il = pci_get_drvdata(pdev); 4972*7ac9a364SKalle Valo bool hw_rfkill = false; 4973*7ac9a364SKalle Valo 4974*7ac9a364SKalle Valo /* 4975*7ac9a364SKalle Valo * We disable the RETRY_TIMEOUT register (0x41) to keep 4976*7ac9a364SKalle Valo * PCI Tx retries from interfering with C3 CPU state. 4977*7ac9a364SKalle Valo */ 4978*7ac9a364SKalle Valo pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); 4979*7ac9a364SKalle Valo 4980*7ac9a364SKalle Valo il_enable_interrupts(il); 4981*7ac9a364SKalle Valo 4982*7ac9a364SKalle Valo if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) 4983*7ac9a364SKalle Valo hw_rfkill = true; 4984*7ac9a364SKalle Valo 4985*7ac9a364SKalle Valo if (hw_rfkill) 4986*7ac9a364SKalle Valo set_bit(S_RFKILL, &il->status); 4987*7ac9a364SKalle Valo else 4988*7ac9a364SKalle Valo clear_bit(S_RFKILL, &il->status); 4989*7ac9a364SKalle Valo 4990*7ac9a364SKalle Valo wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rfkill); 4991*7ac9a364SKalle Valo 4992*7ac9a364SKalle Valo return 0; 4993*7ac9a364SKalle Valo } 4994*7ac9a364SKalle Valo 4995*7ac9a364SKalle Valo SIMPLE_DEV_PM_OPS(il_pm_ops, il_pci_suspend, il_pci_resume); 4996*7ac9a364SKalle Valo EXPORT_SYMBOL(il_pm_ops); 4997*7ac9a364SKalle Valo 4998*7ac9a364SKalle Valo #endif /* CONFIG_PM_SLEEP */ 4999*7ac9a364SKalle Valo 5000*7ac9a364SKalle Valo static void 5001*7ac9a364SKalle Valo il_update_qos(struct il_priv *il) 5002*7ac9a364SKalle Valo { 5003*7ac9a364SKalle Valo if (test_bit(S_EXIT_PENDING, &il->status)) 5004*7ac9a364SKalle Valo return; 5005*7ac9a364SKalle Valo 5006*7ac9a364SKalle Valo il->qos_data.def_qos_parm.qos_flags = 0; 5007*7ac9a364SKalle Valo 5008*7ac9a364SKalle Valo if (il->qos_data.qos_active) 5009*7ac9a364SKalle Valo il->qos_data.def_qos_parm.qos_flags |= 5010*7ac9a364SKalle Valo QOS_PARAM_FLG_UPDATE_EDCA_MSK; 5011*7ac9a364SKalle Valo 5012*7ac9a364SKalle Valo if (il->ht.enabled) 5013*7ac9a364SKalle Valo il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; 5014*7ac9a364SKalle Valo 5015*7ac9a364SKalle Valo D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", 5016*7ac9a364SKalle Valo il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags); 5017*7ac9a364SKalle Valo 5018*7ac9a364SKalle Valo il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd), 5019*7ac9a364SKalle Valo &il->qos_data.def_qos_parm, NULL); 5020*7ac9a364SKalle Valo } 5021*7ac9a364SKalle Valo 5022*7ac9a364SKalle Valo /** 5023*7ac9a364SKalle Valo * il_mac_config - mac80211 config callback 5024*7ac9a364SKalle Valo */ 5025*7ac9a364SKalle Valo int 5026*7ac9a364SKalle Valo il_mac_config(struct ieee80211_hw *hw, u32 changed) 5027*7ac9a364SKalle Valo { 5028*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 5029*7ac9a364SKalle Valo const struct il_channel_info *ch_info; 5030*7ac9a364SKalle Valo struct ieee80211_conf *conf = &hw->conf; 5031*7ac9a364SKalle Valo struct ieee80211_channel *channel = conf->chandef.chan; 5032*7ac9a364SKalle Valo struct il_ht_config *ht_conf = &il->current_ht_config; 5033*7ac9a364SKalle Valo unsigned long flags = 0; 5034*7ac9a364SKalle Valo int ret = 0; 5035*7ac9a364SKalle Valo u16 ch; 5036*7ac9a364SKalle Valo int scan_active = 0; 5037*7ac9a364SKalle Valo bool ht_changed = false; 5038*7ac9a364SKalle Valo 5039*7ac9a364SKalle Valo mutex_lock(&il->mutex); 5040*7ac9a364SKalle Valo D_MAC80211("enter: channel %d changed 0x%X\n", channel->hw_value, 5041*7ac9a364SKalle Valo changed); 5042*7ac9a364SKalle Valo 5043*7ac9a364SKalle Valo if (unlikely(test_bit(S_SCANNING, &il->status))) { 5044*7ac9a364SKalle Valo scan_active = 1; 5045*7ac9a364SKalle Valo D_MAC80211("scan active\n"); 5046*7ac9a364SKalle Valo } 5047*7ac9a364SKalle Valo 5048*7ac9a364SKalle Valo if (changed & 5049*7ac9a364SKalle Valo (IEEE80211_CONF_CHANGE_SMPS | IEEE80211_CONF_CHANGE_CHANNEL)) { 5050*7ac9a364SKalle Valo /* mac80211 uses static for non-HT which is what we want */ 5051*7ac9a364SKalle Valo il->current_ht_config.smps = conf->smps_mode; 5052*7ac9a364SKalle Valo 5053*7ac9a364SKalle Valo /* 5054*7ac9a364SKalle Valo * Recalculate chain counts. 5055*7ac9a364SKalle Valo * 5056*7ac9a364SKalle Valo * If monitor mode is enabled then mac80211 will 5057*7ac9a364SKalle Valo * set up the SM PS mode to OFF if an HT channel is 5058*7ac9a364SKalle Valo * configured. 5059*7ac9a364SKalle Valo */ 5060*7ac9a364SKalle Valo if (il->ops->set_rxon_chain) 5061*7ac9a364SKalle Valo il->ops->set_rxon_chain(il); 5062*7ac9a364SKalle Valo } 5063*7ac9a364SKalle Valo 5064*7ac9a364SKalle Valo /* during scanning mac80211 will delay channel setting until 5065*7ac9a364SKalle Valo * scan finish with changed = 0 5066*7ac9a364SKalle Valo */ 5067*7ac9a364SKalle Valo if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { 5068*7ac9a364SKalle Valo 5069*7ac9a364SKalle Valo if (scan_active) 5070*7ac9a364SKalle Valo goto set_ch_out; 5071*7ac9a364SKalle Valo 5072*7ac9a364SKalle Valo ch = channel->hw_value; 5073*7ac9a364SKalle Valo ch_info = il_get_channel_info(il, channel->band, ch); 5074*7ac9a364SKalle Valo if (!il_is_channel_valid(ch_info)) { 5075*7ac9a364SKalle Valo D_MAC80211("leave - invalid channel\n"); 5076*7ac9a364SKalle Valo ret = -EINVAL; 5077*7ac9a364SKalle Valo goto set_ch_out; 5078*7ac9a364SKalle Valo } 5079*7ac9a364SKalle Valo 5080*7ac9a364SKalle Valo if (il->iw_mode == NL80211_IFTYPE_ADHOC && 5081*7ac9a364SKalle Valo !il_is_channel_ibss(ch_info)) { 5082*7ac9a364SKalle Valo D_MAC80211("leave - not IBSS channel\n"); 5083*7ac9a364SKalle Valo ret = -EINVAL; 5084*7ac9a364SKalle Valo goto set_ch_out; 5085*7ac9a364SKalle Valo } 5086*7ac9a364SKalle Valo 5087*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 5088*7ac9a364SKalle Valo 5089*7ac9a364SKalle Valo /* Configure HT40 channels */ 5090*7ac9a364SKalle Valo if (il->ht.enabled != conf_is_ht(conf)) { 5091*7ac9a364SKalle Valo il->ht.enabled = conf_is_ht(conf); 5092*7ac9a364SKalle Valo ht_changed = true; 5093*7ac9a364SKalle Valo } 5094*7ac9a364SKalle Valo if (il->ht.enabled) { 5095*7ac9a364SKalle Valo if (conf_is_ht40_minus(conf)) { 5096*7ac9a364SKalle Valo il->ht.extension_chan_offset = 5097*7ac9a364SKalle Valo IEEE80211_HT_PARAM_CHA_SEC_BELOW; 5098*7ac9a364SKalle Valo il->ht.is_40mhz = true; 5099*7ac9a364SKalle Valo } else if (conf_is_ht40_plus(conf)) { 5100*7ac9a364SKalle Valo il->ht.extension_chan_offset = 5101*7ac9a364SKalle Valo IEEE80211_HT_PARAM_CHA_SEC_ABOVE; 5102*7ac9a364SKalle Valo il->ht.is_40mhz = true; 5103*7ac9a364SKalle Valo } else { 5104*7ac9a364SKalle Valo il->ht.extension_chan_offset = 5105*7ac9a364SKalle Valo IEEE80211_HT_PARAM_CHA_SEC_NONE; 5106*7ac9a364SKalle Valo il->ht.is_40mhz = false; 5107*7ac9a364SKalle Valo } 5108*7ac9a364SKalle Valo } else 5109*7ac9a364SKalle Valo il->ht.is_40mhz = false; 5110*7ac9a364SKalle Valo 5111*7ac9a364SKalle Valo /* 5112*7ac9a364SKalle Valo * Default to no protection. Protection mode will 5113*7ac9a364SKalle Valo * later be set from BSS config in il_ht_conf 5114*7ac9a364SKalle Valo */ 5115*7ac9a364SKalle Valo il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 5116*7ac9a364SKalle Valo 5117*7ac9a364SKalle Valo /* if we are switching from ht to 2.4 clear flags 5118*7ac9a364SKalle Valo * from any ht related info since 2.4 does not 5119*7ac9a364SKalle Valo * support ht */ 5120*7ac9a364SKalle Valo if ((le16_to_cpu(il->staging.channel) != ch)) 5121*7ac9a364SKalle Valo il->staging.flags = 0; 5122*7ac9a364SKalle Valo 5123*7ac9a364SKalle Valo il_set_rxon_channel(il, channel); 5124*7ac9a364SKalle Valo il_set_rxon_ht(il, ht_conf); 5125*7ac9a364SKalle Valo 5126*7ac9a364SKalle Valo il_set_flags_for_band(il, channel->band, il->vif); 5127*7ac9a364SKalle Valo 5128*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5129*7ac9a364SKalle Valo 5130*7ac9a364SKalle Valo if (il->ops->update_bcast_stations) 5131*7ac9a364SKalle Valo ret = il->ops->update_bcast_stations(il); 5132*7ac9a364SKalle Valo 5133*7ac9a364SKalle Valo set_ch_out: 5134*7ac9a364SKalle Valo /* The list of supported rates and rate mask can be different 5135*7ac9a364SKalle Valo * for each band; since the band may have changed, reset 5136*7ac9a364SKalle Valo * the rate mask to what mac80211 lists */ 5137*7ac9a364SKalle Valo il_set_rate(il); 5138*7ac9a364SKalle Valo } 5139*7ac9a364SKalle Valo 5140*7ac9a364SKalle Valo if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) { 5141*7ac9a364SKalle Valo il->power_data.ps_disabled = !(conf->flags & IEEE80211_CONF_PS); 5142*7ac9a364SKalle Valo ret = il_power_update_mode(il, false); 5143*7ac9a364SKalle Valo if (ret) 5144*7ac9a364SKalle Valo D_MAC80211("Error setting sleep level\n"); 5145*7ac9a364SKalle Valo } 5146*7ac9a364SKalle Valo 5147*7ac9a364SKalle Valo if (changed & IEEE80211_CONF_CHANGE_POWER) { 5148*7ac9a364SKalle Valo D_MAC80211("TX Power old=%d new=%d\n", il->tx_power_user_lmt, 5149*7ac9a364SKalle Valo conf->power_level); 5150*7ac9a364SKalle Valo 5151*7ac9a364SKalle Valo il_set_tx_power(il, conf->power_level, false); 5152*7ac9a364SKalle Valo } 5153*7ac9a364SKalle Valo 5154*7ac9a364SKalle Valo if (!il_is_ready(il)) { 5155*7ac9a364SKalle Valo D_MAC80211("leave - not ready\n"); 5156*7ac9a364SKalle Valo goto out; 5157*7ac9a364SKalle Valo } 5158*7ac9a364SKalle Valo 5159*7ac9a364SKalle Valo if (scan_active) 5160*7ac9a364SKalle Valo goto out; 5161*7ac9a364SKalle Valo 5162*7ac9a364SKalle Valo if (memcmp(&il->active, &il->staging, sizeof(il->staging))) 5163*7ac9a364SKalle Valo il_commit_rxon(il); 5164*7ac9a364SKalle Valo else 5165*7ac9a364SKalle Valo D_INFO("Not re-sending same RXON configuration.\n"); 5166*7ac9a364SKalle Valo if (ht_changed) 5167*7ac9a364SKalle Valo il_update_qos(il); 5168*7ac9a364SKalle Valo 5169*7ac9a364SKalle Valo out: 5170*7ac9a364SKalle Valo D_MAC80211("leave ret %d\n", ret); 5171*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5172*7ac9a364SKalle Valo 5173*7ac9a364SKalle Valo return ret; 5174*7ac9a364SKalle Valo } 5175*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_config); 5176*7ac9a364SKalle Valo 5177*7ac9a364SKalle Valo void 5178*7ac9a364SKalle Valo il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 5179*7ac9a364SKalle Valo { 5180*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 5181*7ac9a364SKalle Valo unsigned long flags; 5182*7ac9a364SKalle Valo 5183*7ac9a364SKalle Valo mutex_lock(&il->mutex); 5184*7ac9a364SKalle Valo D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); 5185*7ac9a364SKalle Valo 5186*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 5187*7ac9a364SKalle Valo 5188*7ac9a364SKalle Valo memset(&il->current_ht_config, 0, sizeof(struct il_ht_config)); 5189*7ac9a364SKalle Valo 5190*7ac9a364SKalle Valo /* new association get rid of ibss beacon skb */ 5191*7ac9a364SKalle Valo if (il->beacon_skb) 5192*7ac9a364SKalle Valo dev_kfree_skb(il->beacon_skb); 5193*7ac9a364SKalle Valo il->beacon_skb = NULL; 5194*7ac9a364SKalle Valo il->timestamp = 0; 5195*7ac9a364SKalle Valo 5196*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5197*7ac9a364SKalle Valo 5198*7ac9a364SKalle Valo il_scan_cancel_timeout(il, 100); 5199*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) { 5200*7ac9a364SKalle Valo D_MAC80211("leave - not ready\n"); 5201*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5202*7ac9a364SKalle Valo return; 5203*7ac9a364SKalle Valo } 5204*7ac9a364SKalle Valo 5205*7ac9a364SKalle Valo /* we are restarting association process */ 5206*7ac9a364SKalle Valo il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 5207*7ac9a364SKalle Valo il_commit_rxon(il); 5208*7ac9a364SKalle Valo 5209*7ac9a364SKalle Valo il_set_rate(il); 5210*7ac9a364SKalle Valo 5211*7ac9a364SKalle Valo D_MAC80211("leave\n"); 5212*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5213*7ac9a364SKalle Valo } 5214*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_reset_tsf); 5215*7ac9a364SKalle Valo 5216*7ac9a364SKalle Valo static void 5217*7ac9a364SKalle Valo il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) 5218*7ac9a364SKalle Valo { 5219*7ac9a364SKalle Valo struct il_ht_config *ht_conf = &il->current_ht_config; 5220*7ac9a364SKalle Valo struct ieee80211_sta *sta; 5221*7ac9a364SKalle Valo struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 5222*7ac9a364SKalle Valo 5223*7ac9a364SKalle Valo D_ASSOC("enter:\n"); 5224*7ac9a364SKalle Valo 5225*7ac9a364SKalle Valo if (!il->ht.enabled) 5226*7ac9a364SKalle Valo return; 5227*7ac9a364SKalle Valo 5228*7ac9a364SKalle Valo il->ht.protection = 5229*7ac9a364SKalle Valo bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; 5230*7ac9a364SKalle Valo il->ht.non_gf_sta_present = 5231*7ac9a364SKalle Valo !!(bss_conf-> 5232*7ac9a364SKalle Valo ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 5233*7ac9a364SKalle Valo 5234*7ac9a364SKalle Valo ht_conf->single_chain_sufficient = false; 5235*7ac9a364SKalle Valo 5236*7ac9a364SKalle Valo switch (vif->type) { 5237*7ac9a364SKalle Valo case NL80211_IFTYPE_STATION: 5238*7ac9a364SKalle Valo rcu_read_lock(); 5239*7ac9a364SKalle Valo sta = ieee80211_find_sta(vif, bss_conf->bssid); 5240*7ac9a364SKalle Valo if (sta) { 5241*7ac9a364SKalle Valo struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 5242*7ac9a364SKalle Valo int maxstreams; 5243*7ac9a364SKalle Valo 5244*7ac9a364SKalle Valo maxstreams = 5245*7ac9a364SKalle Valo (ht_cap->mcs. 5246*7ac9a364SKalle Valo tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) 5247*7ac9a364SKalle Valo >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; 5248*7ac9a364SKalle Valo maxstreams += 1; 5249*7ac9a364SKalle Valo 5250*7ac9a364SKalle Valo if (ht_cap->mcs.rx_mask[1] == 0 && 5251*7ac9a364SKalle Valo ht_cap->mcs.rx_mask[2] == 0) 5252*7ac9a364SKalle Valo ht_conf->single_chain_sufficient = true; 5253*7ac9a364SKalle Valo if (maxstreams <= 1) 5254*7ac9a364SKalle Valo ht_conf->single_chain_sufficient = true; 5255*7ac9a364SKalle Valo } else { 5256*7ac9a364SKalle Valo /* 5257*7ac9a364SKalle Valo * If at all, this can only happen through a race 5258*7ac9a364SKalle Valo * when the AP disconnects us while we're still 5259*7ac9a364SKalle Valo * setting up the connection, in that case mac80211 5260*7ac9a364SKalle Valo * will soon tell us about that. 5261*7ac9a364SKalle Valo */ 5262*7ac9a364SKalle Valo ht_conf->single_chain_sufficient = true; 5263*7ac9a364SKalle Valo } 5264*7ac9a364SKalle Valo rcu_read_unlock(); 5265*7ac9a364SKalle Valo break; 5266*7ac9a364SKalle Valo case NL80211_IFTYPE_ADHOC: 5267*7ac9a364SKalle Valo ht_conf->single_chain_sufficient = true; 5268*7ac9a364SKalle Valo break; 5269*7ac9a364SKalle Valo default: 5270*7ac9a364SKalle Valo break; 5271*7ac9a364SKalle Valo } 5272*7ac9a364SKalle Valo 5273*7ac9a364SKalle Valo D_ASSOC("leave\n"); 5274*7ac9a364SKalle Valo } 5275*7ac9a364SKalle Valo 5276*7ac9a364SKalle Valo static inline void 5277*7ac9a364SKalle Valo il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif) 5278*7ac9a364SKalle Valo { 5279*7ac9a364SKalle Valo /* 5280*7ac9a364SKalle Valo * inform the ucode that there is no longer an 5281*7ac9a364SKalle Valo * association and that no more packets should be 5282*7ac9a364SKalle Valo * sent 5283*7ac9a364SKalle Valo */ 5284*7ac9a364SKalle Valo il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 5285*7ac9a364SKalle Valo il->staging.assoc_id = 0; 5286*7ac9a364SKalle Valo il_commit_rxon(il); 5287*7ac9a364SKalle Valo } 5288*7ac9a364SKalle Valo 5289*7ac9a364SKalle Valo static void 5290*7ac9a364SKalle Valo il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 5291*7ac9a364SKalle Valo { 5292*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 5293*7ac9a364SKalle Valo unsigned long flags; 5294*7ac9a364SKalle Valo __le64 timestamp; 5295*7ac9a364SKalle Valo struct sk_buff *skb = ieee80211_beacon_get(hw, vif); 5296*7ac9a364SKalle Valo 5297*7ac9a364SKalle Valo if (!skb) 5298*7ac9a364SKalle Valo return; 5299*7ac9a364SKalle Valo 5300*7ac9a364SKalle Valo D_MAC80211("enter\n"); 5301*7ac9a364SKalle Valo 5302*7ac9a364SKalle Valo lockdep_assert_held(&il->mutex); 5303*7ac9a364SKalle Valo 5304*7ac9a364SKalle Valo if (!il->beacon_enabled) { 5305*7ac9a364SKalle Valo IL_ERR("update beacon with no beaconing enabled\n"); 5306*7ac9a364SKalle Valo dev_kfree_skb(skb); 5307*7ac9a364SKalle Valo return; 5308*7ac9a364SKalle Valo } 5309*7ac9a364SKalle Valo 5310*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 5311*7ac9a364SKalle Valo 5312*7ac9a364SKalle Valo if (il->beacon_skb) 5313*7ac9a364SKalle Valo dev_kfree_skb(il->beacon_skb); 5314*7ac9a364SKalle Valo 5315*7ac9a364SKalle Valo il->beacon_skb = skb; 5316*7ac9a364SKalle Valo 5317*7ac9a364SKalle Valo timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 5318*7ac9a364SKalle Valo il->timestamp = le64_to_cpu(timestamp); 5319*7ac9a364SKalle Valo 5320*7ac9a364SKalle Valo D_MAC80211("leave\n"); 5321*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5322*7ac9a364SKalle Valo 5323*7ac9a364SKalle Valo if (!il_is_ready_rf(il)) { 5324*7ac9a364SKalle Valo D_MAC80211("leave - RF not ready\n"); 5325*7ac9a364SKalle Valo return; 5326*7ac9a364SKalle Valo } 5327*7ac9a364SKalle Valo 5328*7ac9a364SKalle Valo il->ops->post_associate(il); 5329*7ac9a364SKalle Valo } 5330*7ac9a364SKalle Valo 5331*7ac9a364SKalle Valo void 5332*7ac9a364SKalle Valo il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5333*7ac9a364SKalle Valo struct ieee80211_bss_conf *bss_conf, u32 changes) 5334*7ac9a364SKalle Valo { 5335*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 5336*7ac9a364SKalle Valo int ret; 5337*7ac9a364SKalle Valo 5338*7ac9a364SKalle Valo mutex_lock(&il->mutex); 5339*7ac9a364SKalle Valo D_MAC80211("enter: changes 0x%x\n", changes); 5340*7ac9a364SKalle Valo 5341*7ac9a364SKalle Valo if (!il_is_alive(il)) { 5342*7ac9a364SKalle Valo D_MAC80211("leave - not alive\n"); 5343*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5344*7ac9a364SKalle Valo return; 5345*7ac9a364SKalle Valo } 5346*7ac9a364SKalle Valo 5347*7ac9a364SKalle Valo if (changes & BSS_CHANGED_QOS) { 5348*7ac9a364SKalle Valo unsigned long flags; 5349*7ac9a364SKalle Valo 5350*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 5351*7ac9a364SKalle Valo il->qos_data.qos_active = bss_conf->qos; 5352*7ac9a364SKalle Valo il_update_qos(il); 5353*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5354*7ac9a364SKalle Valo } 5355*7ac9a364SKalle Valo 5356*7ac9a364SKalle Valo if (changes & BSS_CHANGED_BEACON_ENABLED) { 5357*7ac9a364SKalle Valo /* FIXME: can we remove beacon_enabled ? */ 5358*7ac9a364SKalle Valo if (vif->bss_conf.enable_beacon) 5359*7ac9a364SKalle Valo il->beacon_enabled = true; 5360*7ac9a364SKalle Valo else 5361*7ac9a364SKalle Valo il->beacon_enabled = false; 5362*7ac9a364SKalle Valo } 5363*7ac9a364SKalle Valo 5364*7ac9a364SKalle Valo if (changes & BSS_CHANGED_BSSID) { 5365*7ac9a364SKalle Valo D_MAC80211("BSSID %pM\n", bss_conf->bssid); 5366*7ac9a364SKalle Valo 5367*7ac9a364SKalle Valo /* 5368*7ac9a364SKalle Valo * On passive channel we wait with blocked queues to see if 5369*7ac9a364SKalle Valo * there is traffic on that channel. If no frame will be 5370*7ac9a364SKalle Valo * received (what is very unlikely since scan detects AP on 5371*7ac9a364SKalle Valo * that channel, but theoretically possible), mac80211 associate 5372*7ac9a364SKalle Valo * procedure will time out and mac80211 will call us with NULL 5373*7ac9a364SKalle Valo * bssid. We have to unblock queues on such condition. 5374*7ac9a364SKalle Valo */ 5375*7ac9a364SKalle Valo if (is_zero_ether_addr(bss_conf->bssid)) 5376*7ac9a364SKalle Valo il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE); 5377*7ac9a364SKalle Valo 5378*7ac9a364SKalle Valo /* 5379*7ac9a364SKalle Valo * If there is currently a HW scan going on in the background, 5380*7ac9a364SKalle Valo * then we need to cancel it, otherwise sometimes we are not 5381*7ac9a364SKalle Valo * able to authenticate (FIXME: why ?) 5382*7ac9a364SKalle Valo */ 5383*7ac9a364SKalle Valo if (il_scan_cancel_timeout(il, 100)) { 5384*7ac9a364SKalle Valo D_MAC80211("leave - scan abort failed\n"); 5385*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5386*7ac9a364SKalle Valo return; 5387*7ac9a364SKalle Valo } 5388*7ac9a364SKalle Valo 5389*7ac9a364SKalle Valo /* mac80211 only sets assoc when in STATION mode */ 5390*7ac9a364SKalle Valo memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); 5391*7ac9a364SKalle Valo 5392*7ac9a364SKalle Valo /* FIXME: currently needed in a few places */ 5393*7ac9a364SKalle Valo memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); 5394*7ac9a364SKalle Valo } 5395*7ac9a364SKalle Valo 5396*7ac9a364SKalle Valo /* 5397*7ac9a364SKalle Valo * This needs to be after setting the BSSID in case 5398*7ac9a364SKalle Valo * mac80211 decides to do both changes at once because 5399*7ac9a364SKalle Valo * it will invoke post_associate. 5400*7ac9a364SKalle Valo */ 5401*7ac9a364SKalle Valo if (vif->type == NL80211_IFTYPE_ADHOC && (changes & BSS_CHANGED_BEACON)) 5402*7ac9a364SKalle Valo il_beacon_update(hw, vif); 5403*7ac9a364SKalle Valo 5404*7ac9a364SKalle Valo if (changes & BSS_CHANGED_ERP_PREAMBLE) { 5405*7ac9a364SKalle Valo D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble); 5406*7ac9a364SKalle Valo if (bss_conf->use_short_preamble) 5407*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 5408*7ac9a364SKalle Valo else 5409*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 5410*7ac9a364SKalle Valo } 5411*7ac9a364SKalle Valo 5412*7ac9a364SKalle Valo if (changes & BSS_CHANGED_ERP_CTS_PROT) { 5413*7ac9a364SKalle Valo D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); 5414*7ac9a364SKalle Valo if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ) 5415*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; 5416*7ac9a364SKalle Valo else 5417*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; 5418*7ac9a364SKalle Valo if (bss_conf->use_cts_prot) 5419*7ac9a364SKalle Valo il->staging.flags |= RXON_FLG_SELF_CTS_EN; 5420*7ac9a364SKalle Valo else 5421*7ac9a364SKalle Valo il->staging.flags &= ~RXON_FLG_SELF_CTS_EN; 5422*7ac9a364SKalle Valo } 5423*7ac9a364SKalle Valo 5424*7ac9a364SKalle Valo if (changes & BSS_CHANGED_BASIC_RATES) { 5425*7ac9a364SKalle Valo /* XXX use this information 5426*7ac9a364SKalle Valo * 5427*7ac9a364SKalle Valo * To do that, remove code from il_set_rate() and put something 5428*7ac9a364SKalle Valo * like this here: 5429*7ac9a364SKalle Valo * 5430*7ac9a364SKalle Valo if (A-band) 5431*7ac9a364SKalle Valo il->staging.ofdm_basic_rates = 5432*7ac9a364SKalle Valo bss_conf->basic_rates; 5433*7ac9a364SKalle Valo else 5434*7ac9a364SKalle Valo il->staging.ofdm_basic_rates = 5435*7ac9a364SKalle Valo bss_conf->basic_rates >> 4; 5436*7ac9a364SKalle Valo il->staging.cck_basic_rates = 5437*7ac9a364SKalle Valo bss_conf->basic_rates & 0xF; 5438*7ac9a364SKalle Valo */ 5439*7ac9a364SKalle Valo } 5440*7ac9a364SKalle Valo 5441*7ac9a364SKalle Valo if (changes & BSS_CHANGED_HT) { 5442*7ac9a364SKalle Valo il_ht_conf(il, vif); 5443*7ac9a364SKalle Valo 5444*7ac9a364SKalle Valo if (il->ops->set_rxon_chain) 5445*7ac9a364SKalle Valo il->ops->set_rxon_chain(il); 5446*7ac9a364SKalle Valo } 5447*7ac9a364SKalle Valo 5448*7ac9a364SKalle Valo if (changes & BSS_CHANGED_ASSOC) { 5449*7ac9a364SKalle Valo D_MAC80211("ASSOC %d\n", bss_conf->assoc); 5450*7ac9a364SKalle Valo if (bss_conf->assoc) { 5451*7ac9a364SKalle Valo il->timestamp = bss_conf->sync_tsf; 5452*7ac9a364SKalle Valo 5453*7ac9a364SKalle Valo if (!il_is_rfkill(il)) 5454*7ac9a364SKalle Valo il->ops->post_associate(il); 5455*7ac9a364SKalle Valo } else 5456*7ac9a364SKalle Valo il_set_no_assoc(il, vif); 5457*7ac9a364SKalle Valo } 5458*7ac9a364SKalle Valo 5459*7ac9a364SKalle Valo if (changes && il_is_associated(il) && bss_conf->aid) { 5460*7ac9a364SKalle Valo D_MAC80211("Changes (%#x) while associated\n", changes); 5461*7ac9a364SKalle Valo ret = il_send_rxon_assoc(il); 5462*7ac9a364SKalle Valo if (!ret) { 5463*7ac9a364SKalle Valo /* Sync active_rxon with latest change. */ 5464*7ac9a364SKalle Valo memcpy((void *)&il->active, &il->staging, 5465*7ac9a364SKalle Valo sizeof(struct il_rxon_cmd)); 5466*7ac9a364SKalle Valo } 5467*7ac9a364SKalle Valo } 5468*7ac9a364SKalle Valo 5469*7ac9a364SKalle Valo if (changes & BSS_CHANGED_BEACON_ENABLED) { 5470*7ac9a364SKalle Valo if (vif->bss_conf.enable_beacon) { 5471*7ac9a364SKalle Valo memcpy(il->staging.bssid_addr, bss_conf->bssid, 5472*7ac9a364SKalle Valo ETH_ALEN); 5473*7ac9a364SKalle Valo memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); 5474*7ac9a364SKalle Valo il->ops->config_ap(il); 5475*7ac9a364SKalle Valo } else 5476*7ac9a364SKalle Valo il_set_no_assoc(il, vif); 5477*7ac9a364SKalle Valo } 5478*7ac9a364SKalle Valo 5479*7ac9a364SKalle Valo if (changes & BSS_CHANGED_IBSS) { 5480*7ac9a364SKalle Valo ret = il->ops->manage_ibss_station(il, vif, 5481*7ac9a364SKalle Valo bss_conf->ibss_joined); 5482*7ac9a364SKalle Valo if (ret) 5483*7ac9a364SKalle Valo IL_ERR("failed to %s IBSS station %pM\n", 5484*7ac9a364SKalle Valo bss_conf->ibss_joined ? "add" : "remove", 5485*7ac9a364SKalle Valo bss_conf->bssid); 5486*7ac9a364SKalle Valo } 5487*7ac9a364SKalle Valo 5488*7ac9a364SKalle Valo D_MAC80211("leave\n"); 5489*7ac9a364SKalle Valo mutex_unlock(&il->mutex); 5490*7ac9a364SKalle Valo } 5491*7ac9a364SKalle Valo EXPORT_SYMBOL(il_mac_bss_info_changed); 5492*7ac9a364SKalle Valo 5493*7ac9a364SKalle Valo irqreturn_t 5494*7ac9a364SKalle Valo il_isr(int irq, void *data) 5495*7ac9a364SKalle Valo { 5496*7ac9a364SKalle Valo struct il_priv *il = data; 5497*7ac9a364SKalle Valo u32 inta, inta_mask; 5498*7ac9a364SKalle Valo u32 inta_fh; 5499*7ac9a364SKalle Valo unsigned long flags; 5500*7ac9a364SKalle Valo if (!il) 5501*7ac9a364SKalle Valo return IRQ_NONE; 5502*7ac9a364SKalle Valo 5503*7ac9a364SKalle Valo spin_lock_irqsave(&il->lock, flags); 5504*7ac9a364SKalle Valo 5505*7ac9a364SKalle Valo /* Disable (but don't clear!) interrupts here to avoid 5506*7ac9a364SKalle Valo * back-to-back ISRs and sporadic interrupts from our NIC. 5507*7ac9a364SKalle Valo * If we have something to service, the tasklet will re-enable ints. 5508*7ac9a364SKalle Valo * If we *don't* have something, we'll re-enable before leaving here. */ 5509*7ac9a364SKalle Valo inta_mask = _il_rd(il, CSR_INT_MASK); /* just for debug */ 5510*7ac9a364SKalle Valo _il_wr(il, CSR_INT_MASK, 0x00000000); 5511*7ac9a364SKalle Valo 5512*7ac9a364SKalle Valo /* Discover which interrupts are active/pending */ 5513*7ac9a364SKalle Valo inta = _il_rd(il, CSR_INT); 5514*7ac9a364SKalle Valo inta_fh = _il_rd(il, CSR_FH_INT_STATUS); 5515*7ac9a364SKalle Valo 5516*7ac9a364SKalle Valo /* Ignore interrupt if there's nothing in NIC to service. 5517*7ac9a364SKalle Valo * This may be due to IRQ shared with another device, 5518*7ac9a364SKalle Valo * or due to sporadic interrupts thrown from our NIC. */ 5519*7ac9a364SKalle Valo if (!inta && !inta_fh) { 5520*7ac9a364SKalle Valo D_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n"); 5521*7ac9a364SKalle Valo goto none; 5522*7ac9a364SKalle Valo } 5523*7ac9a364SKalle Valo 5524*7ac9a364SKalle Valo if (inta == 0xFFFFFFFF || (inta & 0xFFFFFFF0) == 0xa5a5a5a0) { 5525*7ac9a364SKalle Valo /* Hardware disappeared. It might have already raised 5526*7ac9a364SKalle Valo * an interrupt */ 5527*7ac9a364SKalle Valo IL_WARN("HARDWARE GONE?? INTA == 0x%08x\n", inta); 5528*7ac9a364SKalle Valo goto unplugged; 5529*7ac9a364SKalle Valo } 5530*7ac9a364SKalle Valo 5531*7ac9a364SKalle Valo D_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, 5532*7ac9a364SKalle Valo inta_fh); 5533*7ac9a364SKalle Valo 5534*7ac9a364SKalle Valo inta &= ~CSR_INT_BIT_SCD; 5535*7ac9a364SKalle Valo 5536*7ac9a364SKalle Valo /* il_irq_tasklet() will service interrupts and re-enable them */ 5537*7ac9a364SKalle Valo if (likely(inta || inta_fh)) 5538*7ac9a364SKalle Valo tasklet_schedule(&il->irq_tasklet); 5539*7ac9a364SKalle Valo 5540*7ac9a364SKalle Valo unplugged: 5541*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5542*7ac9a364SKalle Valo return IRQ_HANDLED; 5543*7ac9a364SKalle Valo 5544*7ac9a364SKalle Valo none: 5545*7ac9a364SKalle Valo /* re-enable interrupts here since we don't have anything to service. */ 5546*7ac9a364SKalle Valo /* only Re-enable if disabled by irq */ 5547*7ac9a364SKalle Valo if (test_bit(S_INT_ENABLED, &il->status)) 5548*7ac9a364SKalle Valo il_enable_interrupts(il); 5549*7ac9a364SKalle Valo spin_unlock_irqrestore(&il->lock, flags); 5550*7ac9a364SKalle Valo return IRQ_NONE; 5551*7ac9a364SKalle Valo } 5552*7ac9a364SKalle Valo EXPORT_SYMBOL(il_isr); 5553*7ac9a364SKalle Valo 5554*7ac9a364SKalle Valo /* 5555*7ac9a364SKalle Valo * il_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this 5556*7ac9a364SKalle Valo * function. 5557*7ac9a364SKalle Valo */ 5558*7ac9a364SKalle Valo void 5559*7ac9a364SKalle Valo il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info, 5560*7ac9a364SKalle Valo __le16 fc, __le32 *tx_flags) 5561*7ac9a364SKalle Valo { 5562*7ac9a364SKalle Valo if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { 5563*7ac9a364SKalle Valo *tx_flags |= TX_CMD_FLG_RTS_MSK; 5564*7ac9a364SKalle Valo *tx_flags &= ~TX_CMD_FLG_CTS_MSK; 5565*7ac9a364SKalle Valo *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; 5566*7ac9a364SKalle Valo 5567*7ac9a364SKalle Valo if (!ieee80211_is_mgmt(fc)) 5568*7ac9a364SKalle Valo return; 5569*7ac9a364SKalle Valo 5570*7ac9a364SKalle Valo switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { 5571*7ac9a364SKalle Valo case cpu_to_le16(IEEE80211_STYPE_AUTH): 5572*7ac9a364SKalle Valo case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 5573*7ac9a364SKalle Valo case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): 5574*7ac9a364SKalle Valo case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): 5575*7ac9a364SKalle Valo *tx_flags &= ~TX_CMD_FLG_RTS_MSK; 5576*7ac9a364SKalle Valo *tx_flags |= TX_CMD_FLG_CTS_MSK; 5577*7ac9a364SKalle Valo break; 5578*7ac9a364SKalle Valo } 5579*7ac9a364SKalle Valo } else if (info->control.rates[0]. 5580*7ac9a364SKalle Valo flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 5581*7ac9a364SKalle Valo *tx_flags &= ~TX_CMD_FLG_RTS_MSK; 5582*7ac9a364SKalle Valo *tx_flags |= TX_CMD_FLG_CTS_MSK; 5583*7ac9a364SKalle Valo *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; 5584*7ac9a364SKalle Valo } 5585*7ac9a364SKalle Valo } 5586*7ac9a364SKalle Valo EXPORT_SYMBOL(il_tx_cmd_protection); 5587