.. | .. |
---|
| 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); |
---|