| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
|---|
| 3 | 4 | <http://rt2x00.serialmonkey.com> |
|---|
| 4 | 5 | |
|---|
| 5 | | - This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | | - (at your option) any later version. |
|---|
| 9 | | - |
|---|
| 10 | | - This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - GNU General Public License for more details. |
|---|
| 14 | | - |
|---|
| 15 | | - You should have received a copy of the GNU General Public License |
|---|
| 16 | | - along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 6 | */ |
|---|
| 18 | 7 | |
|---|
| 19 | 8 | /* |
|---|
| .. | .. |
|---|
| 321 | 310 | struct rt2x00lib_crypto *crypto, |
|---|
| 322 | 311 | struct ieee80211_key_conf *key) |
|---|
| 323 | 312 | { |
|---|
| 324 | | - struct hw_key_entry key_entry; |
|---|
| 325 | | - struct rt2x00_field32 field; |
|---|
| 326 | | - u32 mask; |
|---|
| 327 | | - u32 reg; |
|---|
| 328 | | - |
|---|
| 329 | | - if (crypto->cmd == SET_KEY) { |
|---|
| 330 | | - /* |
|---|
| 331 | | - * rt2x00lib can't determine the correct free |
|---|
| 332 | | - * key_idx for shared keys. We have 1 register |
|---|
| 333 | | - * with key valid bits. The goal is simple, read |
|---|
| 334 | | - * the register, if that is full we have no slots |
|---|
| 335 | | - * left. |
|---|
| 336 | | - * Note that each BSS is allowed to have up to 4 |
|---|
| 337 | | - * shared keys, so put a mask over the allowed |
|---|
| 338 | | - * entries. |
|---|
| 339 | | - */ |
|---|
| 340 | | - mask = (0xf << crypto->bssidx); |
|---|
| 341 | | - |
|---|
| 342 | | - reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0); |
|---|
| 343 | | - reg &= mask; |
|---|
| 344 | | - |
|---|
| 345 | | - if (reg && reg == mask) |
|---|
| 346 | | - return -ENOSPC; |
|---|
| 347 | | - |
|---|
| 348 | | - key->hw_key_idx += reg ? ffz(reg) : 0; |
|---|
| 349 | | - |
|---|
| 350 | | - /* |
|---|
| 351 | | - * Upload key to hardware |
|---|
| 352 | | - */ |
|---|
| 353 | | - memcpy(key_entry.key, crypto->key, |
|---|
| 354 | | - sizeof(key_entry.key)); |
|---|
| 355 | | - memcpy(key_entry.tx_mic, crypto->tx_mic, |
|---|
| 356 | | - sizeof(key_entry.tx_mic)); |
|---|
| 357 | | - memcpy(key_entry.rx_mic, crypto->rx_mic, |
|---|
| 358 | | - sizeof(key_entry.rx_mic)); |
|---|
| 359 | | - |
|---|
| 360 | | - reg = SHARED_KEY_ENTRY(key->hw_key_idx); |
|---|
| 361 | | - rt2x00mmio_register_multiwrite(rt2x00dev, reg, |
|---|
| 362 | | - &key_entry, sizeof(key_entry)); |
|---|
| 363 | | - |
|---|
| 364 | | - /* |
|---|
| 365 | | - * The cipher types are stored over 2 registers. |
|---|
| 366 | | - * bssidx 0 and 1 keys are stored in SEC_CSR1 and |
|---|
| 367 | | - * bssidx 1 and 2 keys are stored in SEC_CSR5. |
|---|
| 368 | | - * Using the correct defines correctly will cause overhead, |
|---|
| 369 | | - * so just calculate the correct offset. |
|---|
| 370 | | - */ |
|---|
| 371 | | - if (key->hw_key_idx < 8) { |
|---|
| 372 | | - field.bit_offset = (3 * key->hw_key_idx); |
|---|
| 373 | | - field.bit_mask = 0x7 << field.bit_offset; |
|---|
| 374 | | - |
|---|
| 375 | | - reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR1); |
|---|
| 376 | | - rt2x00_set_field32(®, field, crypto->cipher); |
|---|
| 377 | | - rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg); |
|---|
| 378 | | - } else { |
|---|
| 379 | | - field.bit_offset = (3 * (key->hw_key_idx - 8)); |
|---|
| 380 | | - field.bit_mask = 0x7 << field.bit_offset; |
|---|
| 381 | | - |
|---|
| 382 | | - reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR5); |
|---|
| 383 | | - rt2x00_set_field32(®, field, crypto->cipher); |
|---|
| 384 | | - rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg); |
|---|
| 385 | | - } |
|---|
| 386 | | - |
|---|
| 387 | | - /* |
|---|
| 388 | | - * The driver does not support the IV/EIV generation |
|---|
| 389 | | - * in hardware. However it doesn't support the IV/EIV |
|---|
| 390 | | - * inside the ieee80211 frame either, but requires it |
|---|
| 391 | | - * to be provided separately for the descriptor. |
|---|
| 392 | | - * rt2x00lib will cut the IV/EIV data out of all frames |
|---|
| 393 | | - * given to us by mac80211, but we must tell mac80211 |
|---|
| 394 | | - * to generate the IV/EIV data. |
|---|
| 395 | | - */ |
|---|
| 396 | | - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
|---|
| 397 | | - } |
|---|
| 398 | | - |
|---|
| 399 | 313 | /* |
|---|
| 400 | | - * SEC_CSR0 contains only single-bit fields to indicate |
|---|
| 401 | | - * a particular key is valid. Because using the FIELD32() |
|---|
| 402 | | - * defines directly will cause a lot of overhead, we use |
|---|
| 403 | | - * a calculation to determine the correct bit directly. |
|---|
| 314 | + * Let the software handle the shared keys, |
|---|
| 315 | + * since the hardware decryption does not work reliably, |
|---|
| 316 | + * because the firmware does not know the key's keyidx. |
|---|
| 404 | 317 | */ |
|---|
| 405 | | - mask = 1 << key->hw_key_idx; |
|---|
| 406 | | - |
|---|
| 407 | | - reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0); |
|---|
| 408 | | - if (crypto->cmd == SET_KEY) |
|---|
| 409 | | - reg |= mask; |
|---|
| 410 | | - else if (crypto->cmd == DISABLE_KEY) |
|---|
| 411 | | - reg &= ~mask; |
|---|
| 412 | | - rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg); |
|---|
| 413 | | - |
|---|
| 414 | | - return 0; |
|---|
| 318 | + return -EOPNOTSUPP; |
|---|
| 415 | 319 | } |
|---|
| 416 | 320 | |
|---|
| 417 | 321 | static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, |
|---|
| .. | .. |
|---|
| 2226 | 2130 | break; |
|---|
| 2227 | 2131 | case 6: /* Failure, excessive retries */ |
|---|
| 2228 | 2132 | __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); |
|---|
| 2229 | | - /* Don't break, this is a failed frame! */ |
|---|
| 2133 | + fallthrough; /* this is a failed frame! */ |
|---|
| 2230 | 2134 | default: /* Failure */ |
|---|
| 2231 | 2135 | __set_bit(TXDONE_FAILURE, &txdesc.flags); |
|---|
| 2232 | 2136 | } |
|---|
| .. | .. |
|---|
| 2286 | 2190 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
|---|
| 2287 | 2191 | } |
|---|
| 2288 | 2192 | |
|---|
| 2289 | | -static void rt61pci_txstatus_tasklet(unsigned long data) |
|---|
| 2193 | +static void rt61pci_txstatus_tasklet(struct tasklet_struct *t) |
|---|
| 2290 | 2194 | { |
|---|
| 2291 | | - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
|---|
| 2195 | + struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, |
|---|
| 2196 | + txstatus_tasklet); |
|---|
| 2197 | + |
|---|
| 2292 | 2198 | rt61pci_txdone(rt2x00dev); |
|---|
| 2293 | 2199 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
|---|
| 2294 | 2200 | rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE); |
|---|
| 2295 | 2201 | } |
|---|
| 2296 | 2202 | |
|---|
| 2297 | | -static void rt61pci_tbtt_tasklet(unsigned long data) |
|---|
| 2203 | +static void rt61pci_tbtt_tasklet(struct tasklet_struct *t) |
|---|
| 2298 | 2204 | { |
|---|
| 2299 | | - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
|---|
| 2205 | + struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, tbtt_tasklet); |
|---|
| 2300 | 2206 | rt2x00lib_beacondone(rt2x00dev); |
|---|
| 2301 | 2207 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
|---|
| 2302 | 2208 | rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE); |
|---|
| 2303 | 2209 | } |
|---|
| 2304 | 2210 | |
|---|
| 2305 | | -static void rt61pci_rxdone_tasklet(unsigned long data) |
|---|
| 2211 | +static void rt61pci_rxdone_tasklet(struct tasklet_struct *t) |
|---|
| 2306 | 2212 | { |
|---|
| 2307 | | - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
|---|
| 2213 | + struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, |
|---|
| 2214 | + rxdone_tasklet); |
|---|
| 2308 | 2215 | if (rt2x00mmio_rxdone(rt2x00dev)) |
|---|
| 2309 | 2216 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); |
|---|
| 2310 | 2217 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
|---|
| 2311 | 2218 | rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); |
|---|
| 2312 | 2219 | } |
|---|
| 2313 | 2220 | |
|---|
| 2314 | | -static void rt61pci_autowake_tasklet(unsigned long data) |
|---|
| 2221 | +static void rt61pci_autowake_tasklet(struct tasklet_struct *t) |
|---|
| 2315 | 2222 | { |
|---|
| 2316 | | - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
|---|
| 2223 | + struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, |
|---|
| 2224 | + autowake_tasklet); |
|---|
| 2317 | 2225 | rt61pci_wakeup(rt2x00dev); |
|---|
| 2318 | 2226 | rt2x00mmio_register_write(rt2x00dev, |
|---|
| 2319 | 2227 | M2H_CMD_DONE_CSR, 0xffffffff); |
|---|
| .. | .. |
|---|
| 3049 | 2957 | break; |
|---|
| 3050 | 2958 | |
|---|
| 3051 | 2959 | case QID_ATIM: |
|---|
| 3052 | | - /* fallthrough */ |
|---|
| 3053 | 2960 | default: |
|---|
| 3054 | 2961 | BUG(); |
|---|
| 3055 | 2962 | break; |
|---|
| .. | .. |
|---|
| 3105 | 3012 | .id_table = rt61pci_device_table, |
|---|
| 3106 | 3013 | .probe = rt61pci_probe, |
|---|
| 3107 | 3014 | .remove = rt2x00pci_remove, |
|---|
| 3108 | | - .suspend = rt2x00pci_suspend, |
|---|
| 3109 | | - .resume = rt2x00pci_resume, |
|---|
| 3015 | + .driver.pm = &rt2x00pci_pm_ops, |
|---|
| 3110 | 3016 | }; |
|---|
| 3111 | 3017 | |
|---|
| 3112 | 3018 | module_pci_driver(rt61pci_driver); |
|---|